diff options
609 files changed, 22496 insertions, 8459 deletions
diff --git a/Documentation/dontdiff b/Documentation/dontdiff index 88519daab6e..e1efc400bed 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -152,7 +152,6 @@ piggy.gz piggyback pnmtologo ppc_defs.h* -promcon_tbl.c pss_boot.h qconf raid6altivec*.c diff --git a/Documentation/hwmon/pcf8591 b/Documentation/hwmon/pcf8591 index 5628fcf4207..e76a7892f68 100644 --- a/Documentation/hwmon/pcf8591 +++ b/Documentation/hwmon/pcf8591 @@ -2,11 +2,11 @@ Kernel driver pcf8591 ===================== Supported chips: - * Philips PCF8591 + * Philips/NXP PCF8591 Prefix: 'pcf8591' Addresses scanned: I2C 0x48 - 0x4f - Datasheet: Publicly available at the Philips Semiconductor website - http://www.semiconductors.philips.com/pip/PCF8591P.html + Datasheet: Publicly available at the NXP website + http://www.nxp.com/pip/PCF8591_6.html Authors: Aurelien Jarno <aurelien@aurel32.net> @@ -16,9 +16,10 @@ Authors: Description ----------- + The PCF8591 is an 8-bit A/D and D/A converter (4 analog inputs and one -analog output) for the I2C bus produced by Philips Semiconductors. It -is designed to provide a byte I2C interface to up to 4 separate devices. +analog output) for the I2C bus produced by Philips Semiconductors (now NXP). +It is designed to provide a byte I2C interface to up to 4 separate devices. The PCF8591 has 4 analog inputs programmable as single-ended or differential inputs : @@ -58,8 +59,8 @@ Accessing PCF8591 via /sys interface ------------------------------------- ! Be careful ! -The PCF8591 is plainly impossible to detect ! Stupid chip. -So every chip with address in the interval [48..4f] is +The PCF8591 is plainly impossible to detect! Stupid chip. +So every chip with address in the interval [0x48..0x4f] is detected as PCF8591. If you have other chips in this address range, the workaround is to load this module after the one for your others chips. @@ -67,19 +68,20 @@ for your others chips. On detection (i.e. insmod, modprobe et al.), directories are being created for each detected PCF8591: -/sys/bus/devices/<0>-<1>/ +/sys/bus/i2c/devices/<0>-<1>/ where <0> is the bus the chip was detected on (e. g. i2c-0) and <1> the chip address ([48..4f]) Inside these directories, there are such files: -in0, in1, in2, in3, out0_enable, out0_output, name +in0_input, in1_input, in2_input, in3_input, out0_enable, out0_output, name Name contains chip name. -The in0, in1, in2 and in3 files are RO. Reading gives the value of the -corresponding channel. Depending on the current analog inputs configuration, -files in2 and/or in3 do not exist. Values range are from 0 to 255 for single -ended inputs and -128 to +127 for differential inputs (8-bit ADC). +The in0_input, in1_input, in2_input and in3_input files are RO. Reading gives +the value of the corresponding channel. Depending on the current analog inputs +configuration, files in2_input and in3_input may not exist. Values range +from 0 to 255 for single ended inputs and -128 to +127 for differential inputs +(8-bit ADC). The out0_enable file is RW. Reading gives "1" for analog output enabled and "0" for analog output disabled. Writing accepts "0" and "1" accordingly. diff --git a/Documentation/hwmon/tmp421 b/Documentation/hwmon/tmp421 new file mode 100644 index 00000000000..0cf07f82474 --- /dev/null +++ b/Documentation/hwmon/tmp421 @@ -0,0 +1,36 @@ +Kernel driver tmp421 +==================== + +Supported chips: + * Texas Instruments TMP421 + Prefix: 'tmp421' + Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f + Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html + * Texas Instruments TMP422 + Prefix: 'tmp422' + Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f + Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html + * Texas Instruments TMP423 + Prefix: 'tmp423' + Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f + Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html + +Authors: + Andre Prendel <andre.prendel@gmx.de> + +Description +----------- + +This driver implements support for Texas Instruments TMP421, TMP422 +and TMP423 temperature sensor chips. These chips implement one local +and up to one (TMP421), up to two (TMP422) or up to three (TMP423) +remote sensors. Temperature is measured in degrees Celsius. The chips +are wired over I2C/SMBus and specified over a temperature range of -40 +to +125 degrees Celsius. Resolution for both the local and remote +channels is 0.0625 degree C. + +The chips support only temperature measurement. The driver exports +the temperature values via the following sysfs files: + +temp[1-4]_input +temp[2-4]_fault diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 4c12a290bee..f45d0d8e71d 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1286,6 +1286,10 @@ and is between 256 and 4096 characters. It is defined in the file (machvec) in a generic kernel. Example: machvec=hpzx1_swiotlb + machtype= [Loongson] Share the same kernel image file between different + yeeloong laptop. + Example: machtype=lemote-yeeloong-2f-7inch + max_addr=nn[KMG] [KNL,BOOT,ia64] All physical memory greater than or equal to this physical address is ignored. diff --git a/MAINTAINERS b/MAINTAINERS index 9addc2838e4..e613c6dd709 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -931,6 +931,12 @@ W: http://wireless.kernel.org/en/users/Drivers/ar9170 S: Maintained F: drivers/net/wireless/ath/ar9170/ +ATK0110 HWMON DRIVER +M: Luca Tettamanti <kronos.it@gmail.com> +L: lm-sensors@lm-sensors.org +S: Maintained +F: drivers/hwmon/asus_atk0110.c + ATI_REMOTE2 DRIVER M: Ville Syrjala <syrjala@sci.fi> S: Maintained @@ -5704,7 +5710,7 @@ F: include/xen/ XFS FILESYSTEM P: Silicon Graphics Inc -M: Felix Blyakher <felixb@sgi.com> +M: Alex Elder <aelder@sgi.com> M: xfs-masters@oss.sgi.com L: xfs@oss.sgi.com W: http://oss.sgi.com/projects/xfs diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 7faa2f554ab..9a01d445eca 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -342,8 +342,9 @@ config MEM_MT48LC64M4A2FB_7E config MEM_MT48LC16M16A2TG_75 bool depends on (BFIN533_EZKIT || BFIN561_EZKIT \ - || BFIN533_BLUETECHNIX_CM || BFIN537_BLUETECHNIX_CM \ - || H8606_HVSISTEMAS || BFIN527_BLUETECHNIX_CM) + || BFIN533_BLUETECHNIX_CM || BFIN537_BLUETECHNIX_CM_E \ + || BFIN537_BLUETECHNIX_CM_U || H8606_HVSISTEMAS \ + || BFIN527_BLUETECHNIX_CM) default y config MEM_MT48LC32M8A2_75 @@ -459,7 +460,7 @@ config VCO_MULT default "45" if BFIN533_STAMP default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT) default "22" if BFIN533_BLUETECHNIX_CM - default "20" if (BFIN537_BLUETECHNIX_CM || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM) + default "20" if (BFIN537_BLUETECHNIX_CM_E || BFIN537_BLUETECHNIX_CM_U || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM) default "20" if BFIN561_EZKIT default "16" if (H8606_HVSISTEMAS || BLACKSTAMP || BFIN526_EZBRD || BFIN518F_EZBRD) help @@ -574,8 +575,8 @@ config MAX_VCO_HZ default 400000000 if BF514 default 400000000 if BF516 default 400000000 if BF518 - default 600000000 if BF522 - default 400000000 if BF523 + default 400000000 if BF522 + default 600000000 if BF523 default 400000000 if BF524 default 600000000 if BF525 default 400000000 if BF526 @@ -647,7 +648,7 @@ config CYCLES_CLOCKSOURCE writing the registers will most likely crash the kernel. config GPTMR0_CLOCKSOURCE - bool "Use GPTimer0 as a clocksource (higher rating)" + bool "Use GPTimer0 as a clocksource" select BFIN_GPTIMERS depends on GENERIC_CLOCKEVENTS depends on !TICKSOURCE_GPTMR0 @@ -917,10 +918,6 @@ comment "Cache Support" config BFIN_ICACHE bool "Enable ICACHE" default y -config BFIN_ICACHE_LOCK - bool "Enable Instruction Cache Locking" - depends on BFIN_ICACHE - default n config BFIN_EXTMEM_ICACHEABLE bool "Enable ICACHE for external memory" depends on BFIN_ICACHE @@ -987,7 +984,7 @@ endchoice config BFIN_L2_DCACHEABLE bool "Enable DCACHE for L2 SRAM" depends on BFIN_DCACHE - depends on BF54x || BF561 + depends on (BF54x || BF561) && !SMP default n choice prompt "L2 SRAM DCACHE policy" @@ -995,11 +992,9 @@ choice default BFIN_L2_WRITEBACK config BFIN_L2_WRITEBACK bool "Write back" - depends on !SMP config BFIN_L2_WRITETHROUGH bool "Write through" - depends on !SMP endchoice @@ -1154,11 +1149,12 @@ source "fs/Kconfig.binfmt" endmenu menu "Power management options" + depends on !SMP + source "kernel/power/Kconfig" config ARCH_SUSPEND_POSSIBLE def_bool y - depends on !SMP choice prompt "Standby Power Saving Mode" @@ -1246,6 +1242,7 @@ config PM_BFIN_WAKE_GP endmenu menu "CPU Frequency scaling" + depends on !SMP source "drivers/cpufreq/Kconfig" diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug index 1fc4981d486..87f195ee2e0 100644 --- a/arch/blackfin/Kconfig.debug +++ b/arch/blackfin/Kconfig.debug @@ -252,4 +252,10 @@ config ACCESS_CHECK Say N here to disable that check to improve the performance. +config BFIN_ISRAM_SELF_TEST + bool "isram boot self tests" + default n + help + Run some self tests of the isram driver code at boot. + endmenu diff --git a/arch/blackfin/configs/BF518F-EZBRD_defconfig b/arch/blackfin/configs/BF518F-EZBRD_defconfig index dcfb4889559..9905b26009e 100644 --- a/arch/blackfin/configs/BF518F-EZBRD_defconfig +++ b/arch/blackfin/configs/BF518F-EZBRD_defconfig @@ -358,9 +358,9 @@ CONFIG_C_AMBEN_ALL=y # EBIU_AMBCTL Control # CONFIG_BANK_0=0x7BB0 -CONFIG_BANK_1=0x5554 +CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xFFC0 +CONFIG_BANK_3=0x99B2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) diff --git a/arch/blackfin/configs/BF526-EZBRD_defconfig b/arch/blackfin/configs/BF526-EZBRD_defconfig index 48a3a7a9099..9dc68208802 100644 --- a/arch/blackfin/configs/BF526-EZBRD_defconfig +++ b/arch/blackfin/configs/BF526-EZBRD_defconfig @@ -359,9 +359,9 @@ CONFIG_C_AMBEN_ALL=y # EBIU_AMBCTL Control # CONFIG_BANK_0=0x7BB0 -CONFIG_BANK_1=0x5554 +CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xFFC0 +CONFIG_BANK_3=0x99B2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig index dd8352791da..77e35d4baf5 100644 --- a/arch/blackfin/configs/BF527-EZKIT_defconfig +++ b/arch/blackfin/configs/BF527-EZKIT_defconfig @@ -363,9 +363,9 @@ CONFIG_C_AMBEN_ALL=y # EBIU_AMBCTL Control # CONFIG_BANK_0=0x7BB0 -CONFIG_BANK_1=0x5554 +CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xFFC0 +CONFIG_BANK_3=0x99B2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig index b3d3cab81cf..f773ad1155d 100644 --- a/arch/blackfin/configs/BF548-EZKIT_defconfig +++ b/arch/blackfin/configs/BF548-EZKIT_defconfig @@ -400,7 +400,7 @@ CONFIG_C_AMBEN_ALL=y # EBIU_AMBCTL Control # CONFIG_BANK_0=0x7BB0 -CONFIG_BANK_1=0x5554 +CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 CONFIG_BANK_3=0x99B2 CONFIG_EBIU_MBSCTLVAL=0x0 diff --git a/arch/blackfin/include/asm/bfin-global.h b/arch/blackfin/include/asm/bfin-global.h index e39277ea43e..aef0594e786 100644 --- a/arch/blackfin/include/asm/bfin-global.h +++ b/arch/blackfin/include/asm/bfin-global.h @@ -66,7 +66,6 @@ extern void program_IAR(void); extern asmlinkage void lower_to_irq14(void); extern asmlinkage void bfin_return_from_exception(void); -extern asmlinkage void evt14_softirq(void); extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs); extern int bfin_internal_set_wake(unsigned int irq, unsigned int state); @@ -100,11 +99,6 @@ extern unsigned long bfin_sic_iwr[]; extern unsigned vr_wakeup; extern u16 _bfin_swrst; /* shadow for Software Reset Register (SWRST) */ -#ifdef CONFIG_BFIN_ICACHE_LOCK -extern void cache_grab_lock(int way); -extern void bfin_cache_lock(int way); -#endif - #endif #endif /* _BLACKFIN_H_ */ diff --git a/arch/blackfin/include/asm/bfin5xx_spi.h b/arch/blackfin/include/asm/bfin5xx_spi.h index aaeb4df10d5..c281c632827 100644 --- a/arch/blackfin/include/asm/bfin5xx_spi.h +++ b/arch/blackfin/include/asm/bfin5xx_spi.h @@ -127,6 +127,7 @@ struct bfin5xx_spi_chip { u32 cs_gpio; /* Value to send if no TX value is supplied, usually 0x0 or 0xFFFF */ u16 idle_tx_val; + u8 pio_interrupt; /* Enable spi data irq */ }; #endif /* _SPI_CHANNEL_H_ */ diff --git a/arch/blackfin/include/asm/cplb.h b/arch/blackfin/include/asm/cplb.h index c5dacf8f8cf..d18d16837a6 100644 --- a/arch/blackfin/include/asm/cplb.h +++ b/arch/blackfin/include/asm/cplb.h @@ -125,4 +125,48 @@ #define FAULT_USERSUPV (1 << 17) #define FAULT_CPLBBITS 0x0000ffff -#endif /* _CPLB_H */ +#ifndef __ASSEMBLY__ + +static inline void _disable_cplb(u32 mmr, u32 mask) +{ + u32 ctrl = bfin_read32(mmr) & ~mask; + /* CSYNC to ensure load store ordering */ + __builtin_bfin_csync(); + bfin_write32(mmr, ctrl); + __builtin_bfin_ssync(); +} +static inline void disable_cplb(u32 mmr, u32 mask) +{ + u32 ctrl = bfin_read32(mmr) & ~mask; + CSYNC(); + bfin_write32(mmr, ctrl); + SSYNC(); +} +#define _disable_dcplb() _disable_cplb(DMEM_CONTROL, ENDCPLB) +#define disable_dcplb() disable_cplb(DMEM_CONTROL, ENDCPLB) +#define _disable_icplb() _disable_cplb(IMEM_CONTROL, ENICPLB) +#define disable_icplb() disable_cplb(IMEM_CONTROL, ENICPLB) + +static inline void _enable_cplb(u32 mmr, u32 mask) +{ + u32 ctrl = bfin_read32(mmr) | mask; + /* CSYNC to ensure load store ordering */ + __builtin_bfin_csync(); + bfin_write32(mmr, ctrl); + __builtin_bfin_ssync(); +} +static inline void enable_cplb(u32 mmr, u32 mask) +{ + u32 ctrl = bfin_read32(mmr) | mask; + CSYNC(); + bfin_write32(mmr, ctrl); + SSYNC(); +} +#define _enable_dcplb() _enable_cplb(DMEM_CONTROL, ENDCPLB) +#define enable_dcplb() enable_cplb(DMEM_CONTROL, ENDCPLB) +#define _enable_icplb() _enable_cplb(IMEM_CONTROL, ENICPLB) +#define enable_icplb() enable_cplb(IMEM_CONTROL, ENICPLB) + +#endif /* __ASSEMBLY__ */ + +#endif /* _CPLB_H */ diff --git a/arch/blackfin/include/asm/early_printk.h b/arch/blackfin/include/asm/early_printk.h index 110f1c1f845..53a762b6fcd 100644 --- a/arch/blackfin/include/asm/early_printk.h +++ b/arch/blackfin/include/asm/early_printk.h @@ -21,8 +21,32 @@ * GNU General Public License for more details. */ + +#ifndef __ASM_EARLY_PRINTK_H__ +#define __ASM_EARLY_PRINTK_H__ + #ifdef CONFIG_EARLY_PRINTK +/* For those that don't include it already */ +#include <linux/console.h> + extern int setup_early_printk(char *); +extern void enable_shadow_console(void); +extern int shadow_console_enabled(void); +extern void mark_shadow_error(void); +extern void early_shadow_reg(unsigned long reg, unsigned int n); +extern void early_shadow_write(struct console *con, const char *s, + unsigned int n) __attribute__((nonnull(2))); +#define early_shadow_puts(str) early_shadow_write(NULL, str, strlen(str)) +#define early_shadow_stamp() \ + do { \ + early_shadow_puts(__FILE__ " : " __stringify(__LINE__) " ["); \ + early_shadow_puts(__func__); \ + early_shadow_puts("]\n"); \ + } while (0) #else #define setup_early_printk(fmt) do { } while (0) +#define enable_shadow_console(fmt) do { } while (0) +#define early_shadow_stamp() do { } while (0) #endif /* CONFIG_EARLY_PRINTK */ + +#endif /* __ASM_EARLY_PRINTK_H__ */ diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h index 5a87baf0659..c823e8ebbfa 100644 --- a/arch/blackfin/include/asm/elf.h +++ b/arch/blackfin/include/asm/elf.h @@ -23,7 +23,7 @@ typedef unsigned long elf_greg_t; #define ELF_NGREG 40 /* (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) */ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; -typedef struct user_bfinfp_struct elf_fpregset_t; +typedef struct { } elf_fpregset_t; /* * This is used to ensure we don't load something for the wrong architecture. */ diff --git a/arch/blackfin/include/asm/entry.h b/arch/blackfin/include/asm/entry.h index ec58efc130e..55b808fced7 100644 --- a/arch/blackfin/include/asm/entry.h +++ b/arch/blackfin/include/asm/entry.h @@ -36,6 +36,21 @@ # define LOAD_IPIPE_IPEND #endif +/* + * Workaround for anomalies 05000283 and 05000315 + */ +#if ANOMALY_05000283 || ANOMALY_05000315 +# define ANOMALY_283_315_WORKAROUND(preg, dreg) \ + cc = dreg == dreg; \ + preg.h = HI(CHIPID); \ + preg.l = LO(CHIPID); \ + if cc jump 1f; \ + dreg.l = W[preg]; \ +1: +#else +# define ANOMALY_283_315_WORKAROUND(preg, dreg) +#endif /* ANOMALY_05000283 || ANOMALY_05000315 */ + #ifndef CONFIG_EXACT_HWERR /* As a debugging aid - we save IPEND when DEBUG_KERNEL is on, * otherwise it is a waste of cycles. @@ -88,17 +103,22 @@ * As you can see by the code - we actually need to do two SSYNCS - one to * make sure the read/writes complete, and another to make sure the hardware * error is recognized by the core. + * + * The extra nop before the SSYNC is to make sure we work around 05000244, + * since the 283/315 workaround includes a branch to the end */ #define INTERRUPT_ENTRY(N) \ - SSYNC; \ - SSYNC; \ [--sp] = SYSCFG; \ [--sp] = P0; /*orig_p0*/ \ [--sp] = R0; /*orig_r0*/ \ [--sp] = (R7:0,P5:0); \ R1 = ASTAT; \ + ANOMALY_283_315_WORKAROUND(p0, r0) \ P0.L = LO(ILAT); \ P0.H = HI(ILAT); \ + NOP; \ + SSYNC; \ + SSYNC; \ R0 = [P0]; \ CC = BITTST(R0, EVT_IVHW_P); \ IF CC JUMP 1f; \ @@ -118,15 +138,17 @@ RTI; #define TIMER_INTERRUPT_ENTRY(N) \ - SSYNC; \ - SSYNC; \ [--sp] = SYSCFG; \ [--sp] = P0; /*orig_p0*/ \ [--sp] = R0; /*orig_r0*/ \ [--sp] = (R7:0,P5:0); \ R1 = ASTAT; \ + ANOMALY_283_315_WORKAROUND(p0, r0) \ P0.L = LO(ILAT); \ P0.H = HI(ILAT); \ + NOP; \ + SSYNC; \ + SSYNC; \ R0 = [P0]; \ CC = BITTST(R0, EVT_IVHW_P); \ IF CC JUMP 1f; \ diff --git a/arch/blackfin/include/asm/ftrace.h b/arch/blackfin/include/asm/ftrace.h index 8643680f0f7..90c9b400ba6 100644 --- a/arch/blackfin/include/asm/ftrace.h +++ b/arch/blackfin/include/asm/ftrace.h @@ -8,6 +8,6 @@ #ifndef __ASM_BFIN_FTRACE_H__ #define __ASM_BFIN_FTRACE_H__ -#define MCOUNT_INSN_SIZE 8 /* sizeof mcount call: LINK + CALL */ +#define MCOUNT_INSN_SIZE 6 /* sizeof "[++sp] = rets; call __mcount;" */ #endif diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h index 87ba9ad399c..4617ba66278 100644 --- a/arch/blackfin/include/asm/ipipe.h +++ b/arch/blackfin/include/asm/ipipe.h @@ -145,10 +145,6 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs); int __ipipe_get_irq_priority(unsigned irq); -void __ipipe_stall_root_raw(void); - -void __ipipe_unstall_root_raw(void); - void __ipipe_serial_debug(const char *fmt, ...); asmlinkage void __ipipe_call_irqtail(unsigned long addr); @@ -234,9 +230,6 @@ int ipipe_start_irq_thread(unsigned irq, struct irq_desc *desc); #define task_hijacked(p) 0 #define ipipe_trap_notify(t, r) 0 -#define __ipipe_stall_root_raw() do { } while (0) -#define __ipipe_unstall_root_raw() do { } while (0) - #define ipipe_init_irq_threads() do { } while (0) #define ipipe_start_irq_thread(irq, desc) 0 diff --git a/arch/blackfin/include/asm/irq_handler.h b/arch/blackfin/include/asm/irq_handler.h index 139b5208f9d..7d9e2d3bbed 100644 --- a/arch/blackfin/include/asm/irq_handler.h +++ b/arch/blackfin/include/asm/irq_handler.h @@ -17,6 +17,7 @@ asmlinkage void evt_evt10(void); asmlinkage void evt_evt11(void); asmlinkage void evt_evt12(void); asmlinkage void evt_evt13(void); +asmlinkage void evt_evt14(void); asmlinkage void evt_soft_int1(void); asmlinkage void evt_system_call(void); asmlinkage void init_exception_buff(void); diff --git a/arch/blackfin/include/asm/mmu_context.h b/arch/blackfin/include/asm/mmu_context.h index 944e29faae4..040410bb07e 100644 --- a/arch/blackfin/include/asm/mmu_context.h +++ b/arch/blackfin/include/asm/mmu_context.h @@ -127,17 +127,17 @@ static inline void protect_page(struct mm_struct *mm, unsigned long addr, unsigned long idx = page >> 5; unsigned long bit = 1 << (page & 31); - if (flags & VM_MAYREAD) + if (flags & VM_READ) mask[idx] |= bit; else mask[idx] &= ~bit; mask += page_mask_nelts; - if (flags & VM_MAYWRITE) + if (flags & VM_WRITE) mask[idx] |= bit; else mask[idx] &= ~bit; mask += page_mask_nelts; - if (flags & VM_MAYEXEC) + if (flags & VM_EXEC) mask[idx] |= bit; else mask[idx] &= ~bit; diff --git a/arch/blackfin/include/asm/pda.h b/arch/blackfin/include/asm/pda.h index b42555c1431..a6f95695731 100644 --- a/arch/blackfin/include/asm/pda.h +++ b/arch/blackfin/include/asm/pda.h @@ -50,6 +50,7 @@ struct blackfin_pda { /* Per-processor Data Area */ unsigned long ex_optr; unsigned long ex_buf[4]; unsigned long ex_imask; /* Saved imask from exception */ + unsigned long ex_ipend; /* Saved IPEND from exception */ unsigned long *ex_stack; /* Exception stack space */ #ifdef ANOMALY_05000261 @@ -60,6 +61,12 @@ struct blackfin_pda { /* Per-processor Data Area */ unsigned long retx; unsigned long seqstat; unsigned int __nmi_count; /* number of times NMI asserted on this CPU */ +#ifdef CONFIG_DEBUG_DOUBLEFAULT + unsigned long dcplb_doublefault_addr; + unsigned long icplb_doublefault_addr; + unsigned long retx_doublefault; + unsigned long seqstat_doublefault; +#endif }; extern struct blackfin_pda cpu_pda[]; diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 141d9281e4b..a8ddbc8ed5a 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KGDB_TESTS) += kgdb_test.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +obj-$(CONFIG_EARLY_PRINTK) += shadow_console.o obj-$(CONFIG_STACKTRACE) += stacktrace.o # the kgdb test puts code into L2 and without linker diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c index b5df9459d6d..f05d1b99b0e 100644 --- a/arch/blackfin/kernel/asm-offsets.c +++ b/arch/blackfin/kernel/asm-offsets.c @@ -145,6 +145,7 @@ int main(void) DEFINE(PDA_EXBUF, offsetof(struct blackfin_pda, ex_buf)); DEFINE(PDA_EXIMASK, offsetof(struct blackfin_pda, ex_imask)); DEFINE(PDA_EXSTACK, offsetof(struct blackfin_pda, ex_stack)); + DEFINE(PDA_EXIPEND, offsetof(struct blackfin_pda, ex_ipend)); #ifdef ANOMALY_05000261 DEFINE(PDA_LFRETX, offsetof(struct blackfin_pda, last_cplb_fault_retx)); #endif @@ -152,6 +153,12 @@ int main(void) DEFINE(PDA_ICPLB, offsetof(struct blackfin_pda, icplb_fault_addr)); DEFINE(PDA_RETX, offsetof(struct blackfin_pda, retx)); DEFINE(PDA_SEQSTAT, offsetof(struct blackfin_pda, seqstat)); +#ifdef CONFIG_DEBUG_DOUBLEFAULT + DEFINE(PDA_DF_DCPLB, offsetof(struct blackfin_pda, dcplb_doublefault_addr)); + DEFINE(PDA_DF_ICPLB, offsetof(struct blackfin_pda, icplb_doublefault_addr)); + DEFINE(PDA_DF_SEQSTAT, offsetof(struct blackfin_pda, seqstat_doublefault)); + DEFINE(PDA_DF_RETX, offsetof(struct blackfin_pda, retx_doublefault)); +#endif #ifdef CONFIG_SMP /* Inter-core lock (in L2 SRAM) */ DEFINE(SIZEOF_CORELOCK, sizeof(struct corelock_slot)); diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 9f9b8281665..384868dedac 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -19,6 +19,7 @@ #include <asm/cacheflush.h> #include <asm/dma.h> #include <asm/uaccess.h> +#include <asm/early_printk.h> /* * To make sure we work around 05000119 - we always check DMA_DONE bit, @@ -146,8 +147,8 @@ EXPORT_SYMBOL(request_dma); int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data) { - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_DMA_CHANNELS)); + BUG_ON(channel >= MAX_DMA_CHANNELS || + dma_ch[channel].chan_status == DMA_CHANNEL_FREE); if (callback != NULL) { int ret; @@ -181,8 +182,8 @@ static void clear_dma_buffer(unsigned int channel) void free_dma(unsigned int channel) { pr_debug("freedma() : BEGIN \n"); - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_DMA_CHANNELS)); + BUG_ON(channel >= MAX_DMA_CHANNELS || + dma_ch[channel].chan_status == DMA_CHANNEL_FREE); /* Halt the DMA */ disable_dma(channel); @@ -236,6 +237,7 @@ void blackfin_dma_resume(void) */ void __init blackfin_dma_early_init(void) { + early_shadow_stamp(); bfin_write_MDMA_S0_CONFIG(0); bfin_write_MDMA_S1_CONFIG(0); } @@ -246,6 +248,8 @@ void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size) unsigned long src = (unsigned long)psrc; struct dma_register *dst_ch, *src_ch; + early_shadow_stamp(); + /* We assume that everything is 4 byte aligned, so include * a basic sanity check */ @@ -300,6 +304,8 @@ void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size) void __init early_dma_memcpy_done(void) { + early_shadow_stamp(); + while ((bfin_read_MDMA_S0_CONFIG() && !(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) || (bfin_read_MDMA_S1_CONFIG() && !(bfin_read_MDMA_D1_IRQ_STATUS() & DMA_DONE))) continue; diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 6b944627137..fc4681c0170 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -722,7 +722,6 @@ void bfin_gpio_pm_hibernate_suspend(void) gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; gpio_bank_saved[bank].data = gpio_array[bank]->data; - gpio_bank_saved[bank].data = gpio_array[bank]->data; gpio_bank_saved[bank].inen = gpio_array[bank]->inen; gpio_bank_saved[bank].dir = gpio_array[bank]->dir_set; } diff --git a/arch/blackfin/kernel/cplb-mpu/Makefile b/arch/blackfin/kernel/cplb-mpu/Makefile index 7d70d3bf321..394d0b1b28f 100644 --- a/arch/blackfin/kernel/cplb-mpu/Makefile +++ b/arch/blackfin/kernel/cplb-mpu/Makefile @@ -2,7 +2,7 @@ # arch/blackfin/kernel/cplb-nompu/Makefile # -obj-y := cplbinit.o cacheinit.o cplbmgr.o +obj-y := cplbinit.o cplbmgr.o CFLAGS_cplbmgr.o := -ffixed-I0 -ffixed-I1 -ffixed-I2 -ffixed-I3 \ -ffixed-L0 -ffixed-L1 -ffixed-L2 -ffixed-L3 \ diff --git a/arch/blackfin/kernel/cplb-mpu/cacheinit.c b/arch/blackfin/kernel/cplb-mpu/cacheinit.c deleted file mode 100644 index d5a86c3017f..00000000000 --- a/arch/blackfin/kernel/cplb-mpu/cacheinit.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2004-2007 Analog Devices Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <linux/cpu.h> - -#include <asm/cacheflush.h> -#include <asm/blackfin.h> -#include <asm/cplb.h> -#include <asm/cplbinit.h> - -#if defined(CONFIG_BFIN_ICACHE) -void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl) -{ - unsigned long ctrl; - int i; - - SSYNC(); - for (i = 0; i < MAX_CPLBS; i++) { - bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr); - bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data); - } - ctrl = bfin_read_IMEM_CONTROL(); - ctrl |= IMC | ENICPLB; - bfin_write_IMEM_CONTROL(ctrl); - SSYNC(); -} -#endif - -#if defined(CONFIG_BFIN_DCACHE) -void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl) -{ - unsigned long ctrl; - int i; - - SSYNC(); - for (i = 0; i < MAX_CPLBS; i++) { - bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr); - bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data); - } - - ctrl = bfin_read_DMEM_CONTROL(); - - /* - * Anomaly notes: - * 05000287 - We implement workaround #2 - Change the DMEM_CONTROL - * register, so that the port preferences for DAG0 and DAG1 are set - * to port B - */ - ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0); - bfin_write_DMEM_CONTROL(ctrl); - SSYNC(); -} -#endif diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c index bcdfe9b0b71..8e1e9e9e963 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c @@ -22,6 +22,7 @@ #include <asm/blackfin.h> #include <asm/cacheflush.h> +#include <asm/cplb.h> #include <asm/cplbinit.h> #include <asm/mmu_context.h> @@ -41,46 +42,6 @@ int nr_dcplb_miss[NR_CPUS], nr_icplb_miss[NR_CPUS]; int nr_icplb_supv_miss[NR_CPUS], nr_dcplb_prot[NR_CPUS]; int nr_cplb_flush[NR_CPUS]; -static inline void disable_dcplb(void) -{ - unsigned long ctrl; - SSYNC(); - ctrl = bfin_read_DMEM_CONTROL(); - ctrl &= ~ENDCPLB; - bfin_write_DMEM_CONTROL(ctrl); - SSYNC(); -} - -static inline void enable_dcplb(void) -{ - unsigned long ctrl; - SSYNC(); - ctrl = bfin_read_DMEM_CONTROL(); - ctrl |= ENDCPLB; - bfin_write_DMEM_CONTROL(ctrl); - SSYNC(); -} - -static inline void disable_icplb(void) -{ - unsigned long ctrl; - SSYNC(); - ctrl = bfin_read_IMEM_CONTROL(); - ctrl &= ~ENICPLB; - bfin_write_IMEM_CONTROL(ctrl); - SSYNC(); -} - -static inline void enable_icplb(void) -{ - unsigned long ctrl; - SSYNC(); - ctrl = bfin_read_IMEM_CONTROL(); - ctrl |= ENICPLB; - bfin_write_IMEM_CONTROL(ctrl); - SSYNC(); -} - /* * Given the contents of the status register, return the index of the * CPLB that caused the fault. @@ -198,10 +159,10 @@ static noinline int dcplb_miss(unsigned int cpu) dcplb_tbl[cpu][idx].addr = addr; dcplb_tbl[cpu][idx].data = d_data; - disable_dcplb(); + _disable_dcplb(); bfin_write32(DCPLB_DATA0 + idx * 4, d_data); bfin_write32(DCPLB_ADDR0 + idx * 4, addr); - enable_dcplb(); + _enable_dcplb(); return 0; } @@ -288,10 +249,10 @@ static noinline int icplb_miss(unsigned int cpu) icplb_tbl[cpu][idx].addr = addr; icplb_tbl[cpu][idx].data = i_data; - disable_icplb(); + _disable_icplb(); bfin_write32(ICPLB_DATA0 + idx * 4, i_data); bfin_write32(ICPLB_ADDR0 + idx * 4, addr); - enable_icplb(); + _enable_icplb(); return 0; } @@ -319,7 +280,7 @@ static noinline int dcplb_protection_fault(unsigned int cpu) int cplb_hdr(int seqstat, struct pt_regs *regs) { int cause = seqstat & 0x3f; - unsigned int cpu = smp_processor_id(); + unsigned int cpu = raw_smp_processor_id(); switch (cause) { case 0x23: return dcplb_protection_fault(cpu); @@ -340,19 +301,19 @@ void flush_switched_cplbs(unsigned int cpu) nr_cplb_flush[cpu]++; local_irq_save_hw(flags); - disable_icplb(); + _disable_icplb(); for (i = first_switched_icplb; i < MAX_CPLBS; i++) { icplb_tbl[cpu][i].data = 0; bfin_write32(ICPLB_DATA0 + i * 4, 0); } - enable_icplb(); + _enable_icplb(); - disable_dcplb(); + _disable_dcplb(); for (i = first_switched_dcplb; i < MAX_CPLBS; i++) { dcplb_tbl[cpu][i].data = 0; bfin_write32(DCPLB_DATA0 + i * 4, 0); } - enable_dcplb(); + _enable_dcplb(); local_irq_restore_hw(flags); } @@ -385,7 +346,7 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu) #endif } - disable_dcplb(); + _disable_dcplb(); for (i = first_mask_dcplb; i < first_switched_dcplb; i++) { dcplb_tbl[cpu][i].addr = addr; dcplb_tbl[cpu][i].data = d_data; @@ -393,6 +354,6 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu) bfin_write32(DCPLB_ADDR0 + i * 4, addr); addr += PAGE_SIZE; } - enable_dcplb(); + _enable_dcplb(); local_irq_restore_hw(flags); } diff --git a/arch/blackfin/kernel/cplb-nompu/Makefile b/arch/blackfin/kernel/cplb-nompu/Makefile index 7d70d3bf321..394d0b1b28f 100644 --- a/arch/blackfin/kernel/cplb-nompu/Makefile +++ b/arch/blackfin/kernel/cplb-nompu/Makefile @@ -2,7 +2,7 @@ # arch/blackfin/kernel/cplb-nompu/Makefile # -obj-y := cplbinit.o cacheinit.o cplbmgr.o +obj-y := cplbinit.o cplbmgr.o CFLAGS_cplbmgr.o := -ffixed-I0 -ffixed-I1 -ffixed-I2 -ffixed-I3 \ -ffixed-L0 -ffixed-L1 -ffixed-L2 -ffixed-L3 \ diff --git a/arch/blackfin/kernel/cplb-nompu/cacheinit.c b/arch/blackfin/kernel/cplb-nompu/cacheinit.c deleted file mode 100644 index d5a86c3017f..00000000000 --- a/arch/blackfin/kernel/cplb-nompu/cacheinit.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2004-2007 Analog Devices Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <linux/cpu.h> - -#include <asm/cacheflush.h> -#include <asm/blackfin.h> -#include <asm/cplb.h> -#include <asm/cplbinit.h> - -#if defined(CONFIG_BFIN_ICACHE) -void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl) -{ - unsigned long ctrl; - int i; - - SSYNC(); - for (i = 0; i < MAX_CPLBS; i++) { - bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr); - bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data); - } - ctrl = bfin_read_IMEM_CONTROL(); - ctrl |= IMC | ENICPLB; - bfin_write_IMEM_CONTROL(ctrl); - SSYNC(); -} -#endif - -#if defined(CONFIG_BFIN_DCACHE) -void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl) -{ - unsigned long ctrl; - int i; - - SSYNC(); - for (i = 0; i < MAX_CPLBS; i++) { - bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr); - bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data); - } - - ctrl = bfin_read_DMEM_CONTROL(); - - /* - * Anomaly notes: - * 05000287 - We implement workaround #2 - Change the DMEM_CONTROL - * register, so that the port preferences for DAG0 and DAG1 are set - * to port B - */ - ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0); - bfin_write_DMEM_CONTROL(ctrl); - SSYNC(); -} -#endif diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 685f160a5a3..5d8ad503f82 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -36,7 +36,7 @@ int first_switched_icplb PDT_ATTR; int first_switched_dcplb PDT_ATTR; struct cplb_boundary dcplb_bounds[9] PDT_ATTR; -struct cplb_boundary icplb_bounds[7] PDT_ATTR; +struct cplb_boundary icplb_bounds[9] PDT_ATTR; int icplb_nr_bounds PDT_ATTR; int dcplb_nr_bounds PDT_ATTR; @@ -167,14 +167,21 @@ void __init generate_cplb_tables_all(void) icplb_bounds[i_i++].data = (reserved_mem_icache_on ? SDRAM_IGENERIC : SDRAM_INON_CHBL); } + /* Addressing hole up to the async bank. */ + icplb_bounds[i_i].eaddr = ASYNC_BANK0_BASE; + icplb_bounds[i_i++].data = 0; + /* ASYNC banks. */ + icplb_bounds[i_i].eaddr = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE; + icplb_bounds[i_i++].data = SDRAM_EBIU; /* Addressing hole up to BootROM. */ icplb_bounds[i_i].eaddr = BOOT_ROM_START; icplb_bounds[i_i++].data = 0; /* BootROM -- largest one should be less than 1 meg. */ icplb_bounds[i_i].eaddr = BOOT_ROM_START + (1 * 1024 * 1024); icplb_bounds[i_i++].data = SDRAM_IGENERIC; + if (L2_LENGTH) { - /* Addressing hole up to L2 SRAM, including the async bank. */ + /* Addressing hole up to L2 SRAM. */ icplb_bounds[i_i].eaddr = L2_START; icplb_bounds[i_i++].data = 0; /* L2 SRAM. */ diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c index 12b030842fd..d9ea46c6e41 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c @@ -48,36 +48,13 @@ int nr_cplb_flush[NR_CPUS], nr_dcplb_prot[NR_CPUS]; #define MGR_ATTR #endif -/* - * We're in an exception handler. The normal cli nop nop workaround - * isn't going to do very much, as the only thing that can interrupt - * us is an NMI, and the cli isn't going to stop that. - */ -#define NOWA_SSYNC __asm__ __volatile__ ("ssync;") - -/* Anomaly handlers provide SSYNCs, so avoid extra if anomaly is present */ -#if ANOMALY_05000125 - -#define bfin_write_DMEM_CONTROL_SSYNC(v) bfin_write_DMEM_CONTROL(v) -#define bfin_write_IMEM_CONTROL_SSYNC(v) bfin_write_IMEM_CONTROL(v) - -#else - -#define bfin_write_DMEM_CONTROL_SSYNC(v) \ - do { NOWA_SSYNC; bfin_write_DMEM_CONTROL(v); NOWA_SSYNC; } while (0) -#define bfin_write_IMEM_CONTROL_SSYNC(v) \ - do { NOWA_SSYNC; bfin_write_IMEM_CONTROL(v); NOWA_SSYNC; } while (0) - -#endif - static inline void write_dcplb_data(int cpu, int idx, unsigned long data, unsigned long addr) { - unsigned long ctrl = bfin_read_DMEM_CONTROL(); - bfin_write_DMEM_CONTROL_SSYNC(ctrl & ~ENDCPLB); + _disable_dcplb(); bfin_write32(DCPLB_DATA0 + idx * 4, data); bfin_write32(DCPLB_ADDR0 + idx * 4, addr); - bfin_write_DMEM_CONTROL_SSYNC(ctrl); + _enable_dcplb(); #ifdef CONFIG_CPLB_INFO dcplb_tbl[cpu][idx].addr = addr; @@ -88,12 +65,10 @@ static inline void write_dcplb_data(int cpu, int idx, unsigned long data, static inline void write_icplb_data(int cpu, int idx, unsigned long data, unsigned long addr) { - unsigned long ctrl = bfin_read_IMEM_CONTROL(); - - bfin_write_IMEM_CONTROL_SSYNC(ctrl & ~ENICPLB); + _disable_icplb(); bfin_write32(ICPLB_DATA0 + idx * 4, data); bfin_write32(ICPLB_ADDR0 + idx * 4, addr); - bfin_write_IMEM_CONTROL_SSYNC(ctrl); + _enable_icplb(); #ifdef CONFIG_CPLB_INFO icplb_tbl[cpu][idx].addr = addr; @@ -227,7 +202,7 @@ MGR_ATTR static int dcplb_miss(int cpu) MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs) { int cause = seqstat & 0x3f; - unsigned int cpu = smp_processor_id(); + unsigned int cpu = raw_smp_processor_id(); switch (cause) { case VEC_CPLB_I_M: return icplb_miss(cpu); diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c index 2ab56811841..931c78b5ea1 100644 --- a/arch/blackfin/kernel/early_printk.c +++ b/arch/blackfin/kernel/early_printk.c @@ -27,6 +27,7 @@ #include <linux/serial_core.h> #include <linux/console.h> #include <linux/string.h> +#include <linux/reboot.h> #include <asm/blackfin.h> #include <asm/irq_handler.h> #include <asm/early_printk.h> @@ -181,6 +182,22 @@ asmlinkage void __init init_early_exception_vectors(void) u32 evt; SSYNC(); + /* + * This starts up the shadow buffer, incase anything crashes before + * setup arch + */ + mark_shadow_error(); + early_shadow_puts(linux_banner); + early_shadow_stamp(); + + if (CPUID != bfin_cpuid()) { + early_shadow_puts("Running on wrong machine type, expected"); + early_shadow_reg(CPUID, 16); + early_shadow_puts(", but running on"); + early_shadow_reg(bfin_cpuid(), 16); + early_shadow_puts("\n"); + } + /* cannot program in software: * evt0 - emulation (jtag) * evt1 - reset @@ -199,6 +216,7 @@ asmlinkage void __init init_early_exception_vectors(void) } +__attribute__((__noreturn__)) asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr) { /* This can happen before the uart is initialized, so initialize @@ -210,10 +228,58 @@ asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr) if (likely(early_console == NULL) && CPUID == bfin_cpuid()) setup_early_printk(DEFAULT_EARLY_PORT); - printk(KERN_EMERG "Early panic\n"); - dump_bfin_mem(fp); - show_regs(fp); - dump_bfin_trace_buffer(); + if (!shadow_console_enabled()) { + /* crap - we crashed before setup_arch() */ + early_shadow_puts("panic before setup_arch\n"); + early_shadow_puts("IPEND:"); + early_shadow_reg(fp->ipend, 16); + if (fp->seqstat & SEQSTAT_EXCAUSE) { + early_shadow_puts("\nEXCAUSE:"); + early_shadow_reg(fp->seqstat & SEQSTAT_EXCAUSE, 8); + } + if (fp->seqstat & SEQSTAT_HWERRCAUSE) { + early_shadow_puts("\nHWERRCAUSE:"); + early_shadow_reg( + (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14, 8); + } + early_shadow_puts("\nErr @"); + if (fp->ipend & EVT_EVX) + early_shadow_reg(fp->retx, 32); + else + early_shadow_reg(fp->pc, 32); +#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON + early_shadow_puts("\nTrace:"); + if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { + while (bfin_read_TBUFSTAT() & TBUFCNT) { + early_shadow_puts("\nT :"); + early_shadow_reg(bfin_read_TBUF(), 32); + early_shadow_puts("\n S :"); + early_shadow_reg(bfin_read_TBUF(), 32); + } + } +#endif + early_shadow_puts("\nUse bfin-elf-addr2line to determine " + "function names\n"); + /* + * We should panic(), but we can't - since panic calls printk, + * and printk uses memcpy. + * we want to reboot, but if the machine type is different, + * can't due to machine specific reboot sequences + */ + if (CPUID == bfin_cpuid()) { + early_shadow_puts("Trying to restart\n"); + machine_restart(""); + } + + early_shadow_puts("Halting, since it is not safe to restart\n"); + while (1) + asm volatile ("EMUEXCPT; IDLE;\n"); + + } else { + printk(KERN_EMERG "Early panic\n"); + show_regs(fp); + dump_bfin_trace_buffer(); + } panic("Died early"); } diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S index a9cfba9946b..3f8769b7db5 100644 --- a/arch/blackfin/kernel/entry.S +++ b/arch/blackfin/kernel/entry.S @@ -43,8 +43,28 @@ ENTRY(_ret_from_fork) #ifdef CONFIG_IPIPE - [--sp] = reti; /* IRQs on. */ - SP += 4; + /* + * Hw IRQs are off on entry, and we don't want the scheduling tail + * code to starve high priority domains from interrupts while it + * runs. Therefore we first stall the root stage to have the + * virtual interrupt state reflect IMASK. + */ + p0.l = ___ipipe_root_status; + p0.h = ___ipipe_root_status; + r4 = [p0]; + bitset(r4, 0); + [p0] = r4; + /* + * Then we may enable hw IRQs, allowing preemption from high + * priority domains. schedule_tail() will do local_irq_enable() + * since Blackfin does not define __ARCH_WANT_UNLOCKED_CTXSW, so + * there is no need to unstall the root domain by ourselves + * afterwards. + */ + p0.l = _bfin_irq_flags; + p0.h = _bfin_irq_flags; + r4 = [p0]; + sti r4; #endif /* CONFIG_IPIPE */ SP += -12; call _schedule_tail; diff --git a/arch/blackfin/kernel/ftrace-entry.S b/arch/blackfin/kernel/ftrace-entry.S index 6980b7a0615..76dd4fbcd17 100644 --- a/arch/blackfin/kernel/ftrace-entry.S +++ b/arch/blackfin/kernel/ftrace-entry.S @@ -17,8 +17,8 @@ * only one we can blow away. With pointer registers, we have P0-P2. * * Upon entry, the RETS will point to the top of the current profiled - * function. And since GCC setup the frame for us, the previous function - * will be waiting there. mmmm pie. + * function. And since GCC pushed the previous RETS for us, the previous + * function will be waiting there. mmmm pie. */ ENTRY(__mcount) /* save third function arg early so we can do testing below */ @@ -70,14 +70,14 @@ ENTRY(__mcount) /* setup the tracer function */ p0 = r3; - /* tracer(ulong frompc, ulong selfpc): - * frompc: the pc that did the call to ... - * selfpc: ... this location - * the selfpc itself will need adjusting for the mcount call + /* function_trace_call(unsigned long ip, unsigned long parent_ip): + * ip: this point was called by ... + * parent_ip: ... this function + * the ip itself will need adjusting for the mcount call */ - r1 = rets; - r0 = [fp + 4]; - r1 += -MCOUNT_INSN_SIZE; + r0 = rets; + r1 = [sp + 16]; /* skip the 4 local regs on stack */ + r0 += -MCOUNT_INSN_SIZE; /* call the tracer */ call (p0); @@ -106,9 +106,10 @@ ENTRY(_ftrace_graph_caller) [--sp] = r1; [--sp] = rets; - r0 = fp; + /* prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) */ + r0 = sp; r1 = rets; - r0 += 4; + r0 += 16; /* skip the 4 local regs on stack */ r1 += -MCOUNT_INSN_SIZE; call _prepare_ftrace_return; diff --git a/arch/blackfin/kernel/ftrace.c b/arch/blackfin/kernel/ftrace.c index 905bfc40a00..f2c85ac6f2d 100644 --- a/arch/blackfin/kernel/ftrace.c +++ b/arch/blackfin/kernel/ftrace.c @@ -24,7 +24,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) if (unlikely(atomic_read(¤t->tracing_graph_pause))) return; - if (ftrace_push_return_trace(*parent, self_addr, &trace.depth) == -EBUSY) + if (ftrace_push_return_trace(*parent, self_addr, &trace.depth, 0) == -EBUSY) return; trace.func = self_addr; diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c index b8d22034b9a..5d7382396dc 100644 --- a/arch/blackfin/kernel/ipipe.c +++ b/arch/blackfin/kernel/ipipe.c @@ -30,10 +30,10 @@ #include <linux/slab.h> #include <linux/errno.h> #include <linux/kthread.h> -#include <asm/unistd.h> +#include <linux/unistd.h> +#include <linux/io.h> #include <asm/system.h> #include <asm/atomic.h> -#include <asm/io.h> DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs); @@ -90,6 +90,7 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs) struct ipipe_percpu_domain_data *p = ipipe_root_cpudom_ptr(); struct ipipe_domain *this_domain, *next_domain; struct list_head *head, *pos; + struct ipipe_irqdesc *idesc; int m_ack, s = -1; /* @@ -100,17 +101,20 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs) */ m_ack = (regs == NULL || irq == IRQ_SYSTMR || irq == IRQ_CORETMR); this_domain = __ipipe_current_domain; + idesc = &this_domain->irqs[irq]; - if (unlikely(test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control))) + if (unlikely(test_bit(IPIPE_STICKY_FLAG, &idesc->control))) head = &this_domain->p_link; else { head = __ipipe_pipeline.next; next_domain = list_entry(head, struct ipipe_domain, p_link); - if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) { - if (!m_ack && next_domain->irqs[irq].acknowledge != NULL) - next_domain->irqs[irq].acknowledge(irq, irq_to_desc(irq)); + idesc = &next_domain->irqs[irq]; + if (likely(test_bit(IPIPE_WIRED_FLAG, &idesc->control))) { + if (!m_ack && idesc->acknowledge != NULL) + idesc->acknowledge(irq, irq_to_desc(irq)); if (test_bit(IPIPE_SYNCDEFER_FLAG, &p->status)) - s = __test_and_set_bit(IPIPE_STALL_FLAG, &p->status); + s = __test_and_set_bit(IPIPE_STALL_FLAG, + &p->status); __ipipe_dispatch_wired(next_domain, irq); goto out; } @@ -121,14 +125,15 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs) pos = head; while (pos != &__ipipe_pipeline) { next_domain = list_entry(pos, struct ipipe_domain, p_link); - if (test_bit(IPIPE_HANDLE_FLAG, &next_domain->irqs[irq].control)) { + idesc = &next_domain->irqs[irq]; + if (test_bit(IPIPE_HANDLE_FLAG, &idesc->control)) { __ipipe_set_irq_pending(next_domain, irq); - if (!m_ack && next_domain->irqs[irq].acknowledge != NULL) { - next_domain->irqs[irq].acknowledge(irq, irq_to_desc(irq)); + if (!m_ack && idesc->acknowledge != NULL) { + idesc->acknowledge(irq, irq_to_desc(irq)); m_ack = 1; } } - if (!test_bit(IPIPE_PASS_FLAG, &next_domain->irqs[irq].control)) + if (!test_bit(IPIPE_PASS_FLAG, &idesc->control)) break; pos = next_domain->p_link.next; } @@ -159,11 +164,6 @@ out: __clear_bit(IPIPE_STALL_FLAG, &p->status); } -int __ipipe_check_root(void) -{ - return ipipe_root_domain_p; -} - void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) { struct irq_desc *desc = irq_to_desc(irq); @@ -186,30 +186,6 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) } EXPORT_SYMBOL(__ipipe_disable_irqdesc); -void __ipipe_stall_root_raw(void) -{ - /* - * This code is called by the ins{bwl} routines (see - * arch/blackfin/lib/ins.S), which are heavily used by the - * network stack. It masks all interrupts but those handled by - * non-root domains, so that we keep decent network transfer - * rates for Linux without inducing pathological jitter for - * the real-time domain. - */ - __asm__ __volatile__ ("sti %0;" : : "d"(__ipipe_irq_lvmask)); - - __set_bit(IPIPE_STALL_FLAG, - &ipipe_root_cpudom_var(status)); -} - -void __ipipe_unstall_root_raw(void) -{ - __clear_bit(IPIPE_STALL_FLAG, - &ipipe_root_cpudom_var(status)); - - __asm__ __volatile__ ("sti %0;" : : "d"(bfin_irq_flags)); -} - int __ipipe_syscall_root(struct pt_regs *regs) { struct ipipe_percpu_domain_data *p; @@ -333,12 +309,29 @@ asmlinkage void __ipipe_sync_root(void) void ___ipipe_sync_pipeline(unsigned long syncmask) { - if (__ipipe_root_domain_p) { - if (test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status))) - return; - } + if (__ipipe_root_domain_p && + test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status))) + return; __ipipe_sync_stage(syncmask); } -EXPORT_SYMBOL(show_stack); +void __ipipe_disable_root_irqs_hw(void) +{ + /* + * This code is called by the ins{bwl} routines (see + * arch/blackfin/lib/ins.S), which are heavily used by the + * network stack. It masks all interrupts but those handled by + * non-root domains, so that we keep decent network transfer + * rates for Linux without inducing pathological jitter for + * the real-time domain. + */ + bfin_sti(__ipipe_irq_lvmask); + __set_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)); +} + +void __ipipe_enable_root_irqs_hw(void) +{ + __clear_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)); + bfin_sti(bfin_irq_flags); +} diff --git a/arch/blackfin/kernel/kgdb_test.c b/arch/blackfin/kernel/kgdb_test.c index dbcf3e45cb0..59fc42dc5d6 100644 --- a/arch/blackfin/kernel/kgdb_test.c +++ b/arch/blackfin/kernel/kgdb_test.c @@ -54,7 +54,7 @@ void kgdb_l2_test(void) int kgdb_test(char *name, int len, int count, int z) { - printk(KERN_DEBUG "kgdb name(%d): %s, %d, %d\n", len, name, count, z); + printk(KERN_ALERT "kgdb name(%d): %s, %d, %d\n", len, name, count, z); count = z; return count; } diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c index d5aee362668..67fc7a56c86 100644 --- a/arch/blackfin/kernel/module.c +++ b/arch/blackfin/kernel/module.c @@ -27,6 +27,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#define pr_fmt(fmt) "module %s: " fmt #include <linux/moduleloader.h> #include <linux/elf.h> @@ -36,6 +37,7 @@ #include <linux/kernel.h> #include <asm/dma.h> #include <asm/cacheflush.h> +#include <asm/uaccess.h> void *module_alloc(unsigned long size) { @@ -52,7 +54,7 @@ void module_free(struct module *mod, void *module_region) /* Transfer the section to the L1 memory */ int -module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, +module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, char *secstrings, struct module *mod) { /* @@ -63,126 +65,119 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, * NOTE: this breaks the semantic of mod->arch structure. */ Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; - void *dest = NULL; + void *dest; for (s = sechdrs; s < sechdrs_end; ++s) { - if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) || - ((strcmp(".text", secstrings + s->sh_name) == 0) && - (hdr->e_flags & EF_BFIN_CODE_IN_L1) && (s->sh_size > 0))) { + const char *shname = secstrings + s->sh_name; + + if (s->sh_size == 0) + continue; + + if (!strcmp(".l1.text", shname) || + (!strcmp(".text", shname) && + (hdr->e_flags & EF_BFIN_CODE_IN_L1))) { + dest = l1_inst_sram_alloc(s->sh_size); mod->arch.text_l1 = dest; if (dest == NULL) { - printk(KERN_ERR - "module %s: L1 instruction memory allocation failed\n", - mod->name); + pr_err("L1 inst memory allocation failed\n", + mod->name); return -1; } dma_memcpy(dest, (void *)s->sh_addr, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) || - ((strcmp(".data", secstrings + s->sh_name) == 0) && - (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) { + + } else if (!strcmp(".l1.data", shname) || + (!strcmp(".data", shname) && + (hdr->e_flags & EF_BFIN_DATA_IN_L1))) { + dest = l1_data_sram_alloc(s->sh_size); mod->arch.data_a_l1 = dest; if (dest == NULL) { - printk(KERN_ERR - "module %s: L1 data memory allocation failed\n", + pr_err("L1 data memory allocation failed\n", mod->name); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 || - ((strcmp(".bss", secstrings + s->sh_name) == 0) && - (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) { - dest = l1_data_sram_alloc(s->sh_size); + + } else if (!strcmp(".l1.bss", shname) || + (!strcmp(".bss", shname) && + (hdr->e_flags & EF_BFIN_DATA_IN_L1))) { + + dest = l1_data_sram_zalloc(s->sh_size); mod->arch.bss_a_l1 = dest; if (dest == NULL) { - printk(KERN_ERR - "module %s: L1 data memory allocation failed\n", + pr_err("L1 data memory allocation failed\n", mod->name); return -1; } - memset(dest, 0, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) { + + } else if (!strcmp(".l1.data.B", shname)) { + dest = l1_data_B_sram_alloc(s->sh_size); mod->arch.data_b_l1 = dest; if (dest == NULL) { - printk(KERN_ERR - "module %s: L1 data memory allocation failed\n", + pr_err("L1 data memory allocation failed\n", mod->name); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) { + + } else if (!strcmp(".l1.bss.B", shname)) { + dest = l1_data_B_sram_alloc(s->sh_size); mod->arch.bss_b_l1 = dest; if (dest == NULL) { - printk(KERN_ERR - "module %s: L1 data memory allocation failed\n", + pr_err("L1 data memory allocation failed\n", mod->name); return -1; } memset(dest, 0, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - if ((strcmp(".l2.text", secstrings + s->sh_name) == 0) || - ((strcmp(".text", secstrings + s->sh_name) == 0) && - (hdr->e_flags & EF_BFIN_CODE_IN_L2) && (s->sh_size > 0))) { + + } else if (!strcmp(".l2.text", shname) || + (!strcmp(".text", shname) && + (hdr->e_flags & EF_BFIN_CODE_IN_L2))) { + dest = l2_sram_alloc(s->sh_size); mod->arch.text_l2 = dest; if (dest == NULL) { - printk(KERN_ERR - "module %s: L2 SRAM allocation failed\n", - mod->name); + pr_err("L2 SRAM allocation failed\n", + mod->name); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - if ((strcmp(".l2.data", secstrings + s->sh_name) == 0) || - ((strcmp(".data", secstrings + s->sh_name) == 0) && - (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) { + + } else if (!strcmp(".l2.data", shname) || + (!strcmp(".data", shname) && + (hdr->e_flags & EF_BFIN_DATA_IN_L2))) { + dest = l2_sram_alloc(s->sh_size); mod->arch.data_l2 = dest; if (dest == NULL) { - printk(KERN_ERR - "module %s: L2 SRAM allocation failed\n", + pr_err("L2 SRAM allocation failed\n", mod->name); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - if (strcmp(".l2.bss", secstrings + s->sh_name) == 0 || - ((strcmp(".bss", secstrings + s->sh_name) == 0) && - (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) { - dest = l2_sram_alloc(s->sh_size); + + } else if (!strcmp(".l2.bss", shname) || + (!strcmp(".bss", shname) && + (hdr->e_flags & EF_BFIN_DATA_IN_L2))) { + + dest = l2_sram_zalloc(s->sh_size); mod->arch.bss_l2 = dest; if (dest == NULL) { - printk(KERN_ERR - "module %s: L2 SRAM allocation failed\n", + pr_err("L2 SRAM allocation failed\n", mod->name); return -1; } - memset(dest, 0, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } + + } else + continue; + + s->sh_flags &= ~SHF_ALLOC; + s->sh_addr = (unsigned long)dest; } + return 0; } @@ -190,7 +185,7 @@ int apply_relocate(Elf_Shdr * sechdrs, const char *strtab, unsigned int symindex, unsigned int relsec, struct module *me) { - printk(KERN_ERR "module %s: .rel unsupported\n", me->name); + pr_err(".rel unsupported\n", me->name); return -ENOEXEC; } @@ -205,109 +200,86 @@ apply_relocate(Elf_Shdr * sechdrs, const char *strtab, /* gas does not generate it. */ /*************************************************************************/ int -apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab, +apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, unsigned int symindex, unsigned int relsec, struct module *mod) { unsigned int i; - unsigned short tmp; Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; Elf32_Sym *sym; - uint32_t *location32; - uint16_t *location16; - uint32_t value; + unsigned long location, value, size; + + pr_debug("applying relocate section %u to %u\n", mod->name, + relsec, sechdrs[relsec].sh_info); - pr_debug("Applying relocate section %u to %u\n", relsec, - sechdrs[relsec].sh_info); for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { /* This is where to make the change */ - location16 = - (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].sh_addr + - rel[i].r_offset); - location32 = (uint32_t *) location16; + location = sechdrs[sechdrs[relsec].sh_info].sh_addr + + rel[i].r_offset; + /* This is the symbol it is referring to. Note that all undefined symbols have been resolved. */ sym = (Elf32_Sym *) sechdrs[symindex].sh_addr + ELF32_R_SYM(rel[i].r_info); value = sym->st_value; value += rel[i].r_addend; - pr_debug("location is %x, value is %x type is %d \n", - (unsigned int) location32, value, - ELF32_R_TYPE(rel[i].r_info)); + #ifdef CONFIG_SMP - if ((unsigned long)location16 >= COREB_L1_DATA_A_START) { - printk(KERN_ERR "module %s: cannot relocate in L1: %u (SMP kernel)", - mod->name, ELF32_R_TYPE(rel[i].r_info)); + if (location >= COREB_L1_DATA_A_START) { + pr_err("cannot relocate in L1: %u (SMP kernel)", + mod->name, ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; } #endif + + pr_debug("location is %lx, value is %lx type is %d\n", + mod->name, location, value, ELF32_R_TYPE(rel[i].r_info)); + switch (ELF32_R_TYPE(rel[i].r_info)) { + case R_BFIN_HUIMM16: + value >>= 16; + case R_BFIN_LUIMM16: + case R_BFIN_RIMM16: + size = 2; + break; + case R_BFIN_BYTE4_DATA: + size = 4; + break; + case R_BFIN_PCREL24: case R_BFIN_PCREL24_JUMP_L: - /* Add the value, subtract its postition */ - location16 = - (uint16_t *) (sechdrs[sechdrs[relsec].sh_info]. - sh_addr + rel[i].r_offset - 2); - location32 = (uint32_t *) location16; - value -= (uint32_t) location32; - value >>= 1; - if ((value & 0xFF000000) != 0 && - (value & 0xFF000000) != 0xFF000000) { - printk(KERN_ERR "module %s: relocation overflow\n", - mod->name); - return -ENOEXEC; - } - pr_debug("value is %x, before %x-%x after %x-%x\n", value, - *location16, *(location16 + 1), - (*location16 & 0xff00) | (value >> 16 & 0x00ff), - value & 0xffff); - *location16 = - (*location16 & 0xff00) | (value >> 16 & 0x00ff); - *(location16 + 1) = value & 0xffff; - break; case R_BFIN_PCREL12_JUMP: case R_BFIN_PCREL12_JUMP_S: - value -= (uint32_t) location32; - value >>= 1; - *location16 = (value & 0xfff); - break; case R_BFIN_PCREL10: - value -= (uint32_t) location32; - value >>= 1; - *location16 = (value & 0x3ff); - break; - case R_BFIN_LUIMM16: - pr_debug("before %x after %x\n", *location16, - (value & 0xffff)); - tmp = (value & 0xffff); - if ((unsigned long)location16 >= L1_CODE_START) { - dma_memcpy(location16, &tmp, 2); - } else - *location16 = tmp; - break; - case R_BFIN_HUIMM16: - pr_debug("before %x after %x\n", *location16, - ((value >> 16) & 0xffff)); - tmp = ((value >> 16) & 0xffff); - if ((unsigned long)location16 >= L1_CODE_START) { - dma_memcpy(location16, &tmp, 2); - } else - *location16 = tmp; + pr_err("unsupported relocation: %u (no -mlong-calls?)\n", + mod->name, ELF32_R_TYPE(rel[i].r_info)); + return -ENOEXEC; + + default: + pr_err("unknown relocation: %u\n", mod->name, + ELF32_R_TYPE(rel[i].r_info)); + return -ENOEXEC; + } + + switch (bfin_mem_access_type(location, size)) { + case BFIN_MEM_ACCESS_CORE: + case BFIN_MEM_ACCESS_CORE_ONLY: + memcpy((void *)location, &value, size); break; - case R_BFIN_RIMM16: - *location16 = (value & 0xffff); + case BFIN_MEM_ACCESS_DMA: + dma_memcpy((void *)location, &value, size); break; - case R_BFIN_BYTE4_DATA: - pr_debug("before %x after %x\n", *location32, value); - *location32 = value; + case BFIN_MEM_ACCESS_ITEST: + isram_memcpy((void *)location, &value, size); break; default: - printk(KERN_ERR "module %s: Unknown relocation: %u\n", - mod->name, ELF32_R_TYPE(rel[i].r_info)); + pr_err("invalid relocation for %#lx\n", + mod->name, location); return -ENOEXEC; } } + return 0; } @@ -332,22 +304,28 @@ module_finalize(const Elf_Ehdr * hdr, for (i = 1; i < hdr->e_shnum; i++) { const char *strtab = (char *)sechdrs[strindex].sh_addr; unsigned int info = sechdrs[i].sh_info; + const char *shname = secstrings + sechdrs[i].sh_name; /* Not a valid relocation section? */ if (info >= hdr->e_shnum) continue; - if ((sechdrs[i].sh_type == SHT_RELA) && - ((strcmp(".rela.l2.text", secstrings + sechdrs[i].sh_name) == 0) || - (strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) || - ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) && - (hdr->e_flags & (EF_BFIN_CODE_IN_L1|EF_BFIN_CODE_IN_L2))))) { + /* Only support RELA relocation types */ + if (sechdrs[i].sh_type != SHT_RELA) + continue; + + if (!strcmp(".rela.l2.text", shname) || + !strcmp(".rela.l1.text", shname) || + (!strcmp(".rela.text", shname) && + (hdr->e_flags & (EF_BFIN_CODE_IN_L1 | EF_BFIN_CODE_IN_L2)))) { + err = apply_relocate_add((Elf_Shdr *) sechdrs, strtab, symindex, i, mod); if (err < 0) return -ENOEXEC; } } + return 0; } diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 9da36bab7cc..f5b28618964 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -282,25 +282,19 @@ void finish_atomic_sections (struct pt_regs *regs) { int __user *up0 = (int __user *)regs->p0; - if (regs->pc < ATOMIC_SEQS_START || regs->pc >= ATOMIC_SEQS_END) - return; - switch (regs->pc) { case ATOMIC_XCHG32 + 2: put_user(regs->r1, up0); - regs->pc += 2; + regs->pc = ATOMIC_XCHG32 + 4; break; case ATOMIC_CAS32 + 2: case ATOMIC_CAS32 + 4: if (regs->r0 == regs->r1) + case ATOMIC_CAS32 + 6: put_user(regs->r2, up0); regs->pc = ATOMIC_CAS32 + 8; break; - case ATOMIC_CAS32 + 6: - put_user(regs->r2, up0); - regs->pc += 2; - break; case ATOMIC_ADD32 + 2: regs->r0 = regs->r1 + regs->r0; diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index 6a387eec6b6..30f4828277a 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c @@ -206,6 +206,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) { int ret; unsigned long __user *datap = (unsigned long __user *)data; + void *paddr = (void *)addr; switch (request) { /* when I and D space are separate, these will need to be fixed. */ @@ -215,42 +216,49 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_PEEKTEXT: /* read word at location addr. */ { unsigned long tmp = 0; - int copied; + int copied = 0, to_copy = sizeof(tmp); ret = -EIO; - pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + %ld\n", addr, sizeof(data)); - if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0) + pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + %i\n", addr, to_copy); + if (is_user_addr_valid(child, addr, to_copy) < 0) break; pr_debug("ptrace: user address is valid\n"); - if (L1_CODE_LENGTH != 0 && addr >= get_l1_code_start() - && addr + sizeof(tmp) <= get_l1_code_start() + L1_CODE_LENGTH) { - safe_dma_memcpy (&tmp, (const void *)(addr), sizeof(tmp)); - copied = sizeof(tmp); - - } else if (L1_DATA_A_LENGTH != 0 && addr >= L1_DATA_A_START - && addr + sizeof(tmp) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { - memcpy(&tmp, (const void *)(addr), sizeof(tmp)); - copied = sizeof(tmp); - - } else if (L1_DATA_B_LENGTH != 0 && addr >= L1_DATA_B_START - && addr + sizeof(tmp) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { - memcpy(&tmp, (const void *)(addr), sizeof(tmp)); - copied = sizeof(tmp); - - } else if (addr >= FIXED_CODE_START - && addr + sizeof(tmp) <= FIXED_CODE_END) { - copy_from_user_page(0, 0, 0, &tmp, (const void *)(addr), sizeof(tmp)); - copied = sizeof(tmp); - - } else + switch (bfin_mem_access_type(addr, to_copy)) { + case BFIN_MEM_ACCESS_CORE: + case BFIN_MEM_ACCESS_CORE_ONLY: copied = access_process_vm(child, addr, &tmp, - sizeof(tmp), 0); + to_copy, 0); + if (copied) + break; + + /* hrm, why didn't that work ... maybe no mapping */ + if (addr >= FIXED_CODE_START && + addr + to_copy <= FIXED_CODE_END) { + copy_from_user_page(0, 0, 0, &tmp, paddr, to_copy); + copied = to_copy; + } else if (addr >= BOOT_ROM_START) { + memcpy(&tmp, paddr, to_copy); + copied = to_copy; + } - pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp); - if (copied != sizeof(tmp)) break; - ret = put_user(tmp, datap); + case BFIN_MEM_ACCESS_DMA: + if (safe_dma_memcpy(&tmp, paddr, to_copy)) + copied = to_copy; + break; + case BFIN_MEM_ACCESS_ITEST: + if (isram_memcpy(&tmp, paddr, to_copy)) + copied = to_copy; + break; + default: + copied = 0; + break; + } + + pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp); + if (copied == to_copy) + ret = put_user(tmp, datap); break; } @@ -277,9 +285,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) tmp = child->mm->start_data; #ifdef CONFIG_BINFMT_ELF_FDPIC } else if (addr == (sizeof(struct pt_regs) + 12)) { - tmp = child->mm->context.exec_fdpic_loadmap; + goto case_PTRACE_GETFDPIC_EXEC; } else if (addr == (sizeof(struct pt_regs) + 16)) { - tmp = child->mm->context.interp_fdpic_loadmap; + goto case_PTRACE_GETFDPIC_INTERP; #endif } else { tmp = get_reg(child, addr); @@ -288,49 +296,78 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; } +#ifdef CONFIG_BINFMT_ELF_FDPIC + case PTRACE_GETFDPIC: { + unsigned long tmp = 0; + + switch (addr) { + case_PTRACE_GETFDPIC_EXEC: + case PTRACE_GETFDPIC_EXEC: + tmp = child->mm->context.exec_fdpic_loadmap; + break; + case_PTRACE_GETFDPIC_INTERP: + case PTRACE_GETFDPIC_INTERP: + tmp = child->mm->context.interp_fdpic_loadmap; + break; + default: + break; + } + + ret = put_user(tmp, datap); + break; + } +#endif + /* when I and D space are separate, this will have to be fixed. */ case PTRACE_POKEDATA: pr_debug("ptrace: PTRACE_PEEKDATA\n"); /* fall through */ case PTRACE_POKETEXT: /* write the word at location addr. */ { - int copied; + int copied = 0, to_copy = sizeof(data); ret = -EIO; - pr_debug("ptrace: POKETEXT at addr 0x%08lx + %ld bytes %lx\n", - addr, sizeof(data), data); - if (is_user_addr_valid(child, addr, sizeof(data)) < 0) + pr_debug("ptrace: POKETEXT at addr 0x%08lx + %i bytes %lx\n", + addr, to_copy, data); + if (is_user_addr_valid(child, addr, to_copy) < 0) break; pr_debug("ptrace: user address is valid\n"); - if (L1_CODE_LENGTH != 0 && addr >= get_l1_code_start() - && addr + sizeof(data) <= get_l1_code_start() + L1_CODE_LENGTH) { - safe_dma_memcpy ((void *)(addr), &data, sizeof(data)); - copied = sizeof(data); - - } else if (L1_DATA_A_LENGTH != 0 && addr >= L1_DATA_A_START - && addr + sizeof(data) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { - memcpy((void *)(addr), &data, sizeof(data)); - copied = sizeof(data); - - } else if (L1_DATA_B_LENGTH != 0 && addr >= L1_DATA_B_START - && addr + sizeof(data) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { - memcpy((void *)(addr), &data, sizeof(data)); - copied = sizeof(data); - - } else if (addr >= FIXED_CODE_START - && addr + sizeof(data) <= FIXED_CODE_END) { - copy_to_user_page(0, 0, 0, (void *)(addr), &data, sizeof(data)); - copied = sizeof(data); - - } else + switch (bfin_mem_access_type(addr, to_copy)) { + case BFIN_MEM_ACCESS_CORE: + case BFIN_MEM_ACCESS_CORE_ONLY: copied = access_process_vm(child, addr, &data, - sizeof(data), 1); + to_copy, 0); + if (copied) + break; + + /* hrm, why didn't that work ... maybe no mapping */ + if (addr >= FIXED_CODE_START && + addr + to_copy <= FIXED_CODE_END) { + copy_to_user_page(0, 0, 0, paddr, &data, to_copy); + copied = to_copy; + } else if (addr >= BOOT_ROM_START) { + memcpy(paddr, &data, to_copy); + copied = to_copy; + } - pr_debug("ptrace: copied size %d\n", copied); - if (copied != sizeof(data)) break; - ret = 0; + case BFIN_MEM_ACCESS_DMA: + if (safe_dma_memcpy(paddr, &data, to_copy)) + copied = to_copy; + break; + case BFIN_MEM_ACCESS_ITEST: + if (isram_memcpy(paddr, &data, to_copy)) + copied = to_copy; + break; + default: + copied = 0; + break; + } + + pr_debug("ptrace: copied size %d\n", copied); + if (copied == to_copy) + ret = 0; break; } diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 6225edae488..369535b61ed 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -112,7 +112,7 @@ void __cpuinit bfin_setup_caches(unsigned int cpu) /* * In cache coherence emulation mode, we need to have the * D-cache enabled before running any atomic operation which - * might invove cache invalidation (i.e. spinlock, rwlock). + * might involve cache invalidation (i.e. spinlock, rwlock). * So printk's are deferred until then. */ #ifdef CONFIG_BFIN_ICACHE @@ -187,6 +187,8 @@ void __init bfin_relocate_l1_mem(void) unsigned long l1_data_b_length; unsigned long l2_length; + early_shadow_stamp(); + /* * due to the ALIGN(4) in the arch/blackfin/kernel/vmlinux.lds.S * we know that everything about l1 text/data is nice and aligned, @@ -511,6 +513,7 @@ static __init void memory_setup(void) #ifdef CONFIG_MTD_UCLINUX unsigned long mtd_phys = 0; #endif + unsigned long max_mem; _rambase = (unsigned long)_stext; _ramstart = (unsigned long)_end; @@ -520,7 +523,22 @@ static __init void memory_setup(void) panic("DMA region exceeds memory limit: %lu.", _ramend - _ramstart); } - memory_end = _ramend - DMA_UNCACHED_REGION; + max_mem = memory_end = _ramend - DMA_UNCACHED_REGION; + +#if (defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) && ANOMALY_05000263) + /* Due to a Hardware Anomaly we need to limit the size of usable + * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on + * 05000263 - Hardware loop corrupted when taking an ICPLB exception + */ +# if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO)) + if (max_mem >= 56 * 1024 * 1024) + max_mem = 56 * 1024 * 1024; +# else + if (max_mem >= 60 * 1024 * 1024) + max_mem = 60 * 1024 * 1024; +# endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */ +#endif /* ANOMALY_05000263 */ + #ifdef CONFIG_MPU /* Round up to multiple of 4MB */ @@ -549,22 +567,16 @@ static __init void memory_setup(void) # if defined(CONFIG_ROMFS_FS) if (((unsigned long *)mtd_phys)[0] == ROMSB_WORD0 - && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1) + && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1) { mtd_size = PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2])); -# if (defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) && ANOMALY_05000263) - /* Due to a Hardware Anomaly we need to limit the size of usable - * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on - * 05000263 - Hardware loop corrupted when taking an ICPLB exception - */ -# if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO)) - if (memory_end >= 56 * 1024 * 1024) - memory_end = 56 * 1024 * 1024; -# else - if (memory_end >= 60 * 1024 * 1024) - memory_end = 60 * 1024 * 1024; -# endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */ -# endif /* ANOMALY_05000263 */ + + /* ROM_FS is XIP, so if we found it, we need to limit memory */ + if (memory_end > max_mem) { + pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20); + memory_end = max_mem; + } + } # endif /* CONFIG_ROMFS_FS */ /* Since the default MTD_UCLINUX has no magic number, we just blindly @@ -586,20 +598,14 @@ static __init void memory_setup(void) } #endif /* CONFIG_MTD_UCLINUX */ -#if (defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) && ANOMALY_05000263) - /* Due to a Hardware Anomaly we need to limit the size of usable - * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on - * 05000263 - Hardware loop corrupted when taking an ICPLB exception + /* We need lo limit memory, since everything could have a text section + * of userspace in it, and expose anomaly 05000263. If the anomaly + * doesn't exist, or we don't need to - then dont. */ -#if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO)) - if (memory_end >= 56 * 1024 * 1024) - memory_end = 56 * 1024 * 1024; -#else - if (memory_end >= 60 * 1024 * 1024) - memory_end = 60 * 1024 * 1024; -#endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */ - printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20); -#endif /* ANOMALY_05000263 */ + if (memory_end > max_mem) { + pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20); + memory_end = max_mem; + } #ifdef CONFIG_MPU page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32; @@ -693,7 +699,7 @@ static __init void setup_bootmem_allocator(void) sanitize_memmap(bfin_memmap.map, &bfin_memmap.nr_map); print_memory_map("boot memmap"); - /* intialize globals in linux/bootmem.h */ + /* initialize globals in linux/bootmem.h */ find_min_max_pfn(); /* pfn of the last usable page frame */ if (max_pfn > memory_end >> PAGE_SHIFT) @@ -806,6 +812,8 @@ void __init setup_arch(char **cmdline_p) { unsigned long sclk, cclk; + enable_shadow_console(); + /* Check to make sure we are running on the right processor */ if (unlikely(CPUID != bfin_cpuid())) printk(KERN_ERR "ERROR: Not running on ADSP-%s: unknown CPUID 0x%04x Rev 0.%d\n", @@ -1230,57 +1238,6 @@ static int show_cpuinfo(struct seq_file *m, void *v) #ifdef __ARCH_SYNC_CORE_ICACHE seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", cpudata->icache_invld_count); #endif -#ifdef CONFIG_BFIN_ICACHE_LOCK - switch ((cpudata->imemctl >> 3) & WAYALL_L) { - case WAY0_L: - seq_printf(m, "Way0 Locked-Down\n"); - break; - case WAY1_L: - seq_printf(m, "Way1 Locked-Down\n"); - break; - case WAY01_L: - seq_printf(m, "Way0,Way1 Locked-Down\n"); - break; - case WAY2_L: - seq_printf(m, "Way2 Locked-Down\n"); - break; - case WAY02_L: - seq_printf(m, "Way0,Way2 Locked-Down\n"); - break; - case WAY12_L: - seq_printf(m, "Way1,Way2 Locked-Down\n"); - break; - case WAY012_L: - seq_printf(m, "Way0,Way1 & Way2 Locked-Down\n"); - break; - case WAY3_L: - seq_printf(m, "Way3 Locked-Down\n"); - break; - case WAY03_L: - seq_printf(m, "Way0,Way3 Locked-Down\n"); - break; - case WAY13_L: - seq_printf(m, "Way1,Way3 Locked-Down\n"); - break; - case WAY013_L: - seq_printf(m, "Way 0,Way1,Way3 Locked-Down\n"); - break; - case WAY32_L: - seq_printf(m, "Way3,Way2 Locked-Down\n"); - break; - case WAY320_L: - seq_printf(m, "Way3,Way2,Way0 Locked-Down\n"); - break; - case WAY321_L: - seq_printf(m, "Way3,Way2,Way1 Locked-Down\n"); - break; - case WAYALL_L: - seq_printf(m, "All Ways are locked\n"); - break; - default: - seq_printf(m, "No Ways are locked\n"); - } -#endif if (cpu_num != num_possible_cpus() - 1) return 0; @@ -1346,6 +1303,7 @@ const struct seq_operations cpuinfo_op = { void __init cmdline_init(const char *r0) { + early_shadow_stamp(); if (r0) strncpy(command_line, r0, COMMAND_LINE_SIZE); } diff --git a/arch/blackfin/kernel/shadow_console.c b/arch/blackfin/kernel/shadow_console.c new file mode 100644 index 00000000000..8b8c7107a16 --- /dev/null +++ b/arch/blackfin/kernel/shadow_console.c @@ -0,0 +1,113 @@ +/* + * manage a small early shadow of the log buffer which we can pass between the + * bootloader so early crash messages are communicated properly and easily + * + * Copyright 2009 Analog Devices Inc. + * + * Enter bugs at http://blackfin.uclinux.org/ + * + * Licensed under the GPL-2 or later. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/string.h> +#include <asm/blackfin.h> +#include <asm/irq_handler.h> +#include <asm/early_printk.h> + +#define SHADOW_CONSOLE_START (0x500) +#define SHADOW_CONSOLE_END (0x1000) +#define SHADOW_CONSOLE_MAGIC_LOC (0x4F0) +#define SHADOW_CONSOLE_MAGIC (0xDEADBEEF) + +static __initdata char *shadow_console_buffer = (char *)SHADOW_CONSOLE_START; + +__init void early_shadow_write(struct console *con, const char *s, + unsigned int n) +{ + unsigned int i; + /* + * save 2 bytes for the double null at the end + * once we fail on a long line, make sure we don't write a short line afterwards + */ + if ((shadow_console_buffer + n) <= (char *)(SHADOW_CONSOLE_END - 2)) { + /* can't use memcpy - it may not be relocated yet */ + for (i = 0; i <= n; i++) + shadow_console_buffer[i] = s[i]; + shadow_console_buffer += n; + shadow_console_buffer[0] = 0; + shadow_console_buffer[1] = 0; + } else + shadow_console_buffer = (char *)SHADOW_CONSOLE_END; +} + +static __initdata struct console early_shadow_console = { + .name = "early_shadow", + .write = early_shadow_write, + .flags = CON_BOOT | CON_PRINTBUFFER, + .index = -1, + .device = 0, +}; + +__init int shadow_console_enabled(void) +{ + return early_shadow_console.flags & CON_ENABLED; +} + +__init void mark_shadow_error(void) +{ + int *loc = (int *)SHADOW_CONSOLE_MAGIC_LOC; + loc[0] = SHADOW_CONSOLE_MAGIC; + loc[1] = SHADOW_CONSOLE_START; +} + +__init void enable_shadow_console(void) +{ + if (!shadow_console_enabled()) { + register_console(&early_shadow_console); + /* for now, assume things are going to fail */ + mark_shadow_error(); + } +} + +static __init int disable_shadow_console(void) +{ + /* + * by the time pure_initcall runs, the standard console is enabled, + * and the early_console is off, so unset the magic numbers + * unregistering the console is taken care of in common code (See + * ./kernel/printk:disable_boot_consoles() ) + */ + int *loc = (int *)SHADOW_CONSOLE_MAGIC_LOC; + + loc[0] = 0; + + return 0; +} +pure_initcall(disable_shadow_console); + +/* + * since we can't use printk, dump numbers (as hex), n = # bits + */ +__init void early_shadow_reg(unsigned long reg, unsigned int n) +{ + /* + * can't use any "normal" kernel features, since thay + * may not be relocated to their execute address yet + */ + int i; + char ascii[11] = " 0x"; + + n = n / 4; + reg = reg << ((8 - n) * 4); + n += 3; + + for (i = 3; i <= n ; i++) { + ascii[i] = hex_asc_lo(reg >> 28); + reg <<= 4; + } + early_shadow_write(NULL, ascii, n); + +} diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index 0791eba40d9..f9715764383 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -66,7 +66,7 @@ static cycle_t bfin_read_cycles(struct clocksource *cs) static struct clocksource bfin_cs_cycles = { .name = "bfin_cs_cycles", - .rating = 350, + .rating = 400, .read = bfin_read_cycles, .mask = CLOCKSOURCE_MASK(64), .shift = 22, @@ -115,7 +115,7 @@ static cycle_t bfin_read_gptimer0(void) static struct clocksource bfin_cs_gptimer0 = { .name = "bfin_cs_gptimer0", - .rating = 400, + .rating = 350, .read = bfin_read_gptimer0, .mask = CLOCKSOURCE_MASK(32), .shift = 22, diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index bf2b2d1f8ae..56464cb8edf 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -100,7 +100,11 @@ static void decode_address(char *buf, unsigned long address) char *modname; char *delim = ":"; char namebuf[128]; +#endif + + buf += sprintf(buf, "<0x%08lx> ", address); +#ifdef CONFIG_KALLSYMS /* look up the address and see if we are in kernel space */ symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); @@ -108,23 +112,33 @@ static void decode_address(char *buf, unsigned long address) /* yeah! kernel space! */ if (!modname) modname = delim = ""; - sprintf(buf, "<0x%p> { %s%s%s%s + 0x%lx }", - (void *)address, delim, modname, delim, symname, - (unsigned long)offset); + sprintf(buf, "{ %s%s%s%s + 0x%lx }", + delim, modname, delim, symname, + (unsigned long)offset); return; - } #endif - /* Problem in fixed code section? */ if (address >= FIXED_CODE_START && address < FIXED_CODE_END) { - sprintf(buf, "<0x%p> /* Maybe fixed code section */", (void *)address); + /* Problem in fixed code section? */ + strcat(buf, "/* Maybe fixed code section */"); + return; + + } else if (address < CONFIG_BOOT_LOAD) { + /* Problem somewhere before the kernel start address */ + strcat(buf, "/* Maybe null pointer? */"); + return; + + } else if (address >= COREMMR_BASE) { + strcat(buf, "/* core mmrs */"); return; - } - /* Problem somewhere before the kernel start address */ - if (address < CONFIG_BOOT_LOAD) { - sprintf(buf, "<0x%p> /* Maybe null pointer? */", (void *)address); + } else if (address >= SYSMMR_BASE) { + strcat(buf, "/* system mmrs */"); + return; + + } else if (address >= L1_ROM_START && address < L1_ROM_START + L1_ROM_LENGTH) { + strcat(buf, "/* on-chip L1 ROM */"); return; } @@ -172,18 +186,16 @@ static void decode_address(char *buf, unsigned long address) offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); - sprintf(buf, "<0x%p> [ %s + 0x%lx ]", - (void *)address, name, offset); + sprintf(buf, "[ %s + 0x%lx ]", name, offset); } else - sprintf(buf, "<0x%p> [ %s vma:0x%lx-0x%lx]", - (void *)address, name, - vma->vm_start, vma->vm_end); + sprintf(buf, "[ %s vma:0x%lx-0x%lx]", + name, vma->vm_start, vma->vm_end); if (!in_atomic) mmput(mm); - if (!strlen(buf)) - sprintf(buf, "<0x%p> [ %s ] dynamic memory", (void *)address, name); + if (buf[0] == '\0') + sprintf(buf, "[ %s ] dynamic memory", name); goto done; } @@ -193,7 +205,7 @@ static void decode_address(char *buf, unsigned long address) } /* we were unable to find this address anywhere */ - sprintf(buf, "<0x%p> /* kernel dynamic memory */", (void *)address); + sprintf(buf, "/* kernel dynamic memory */"); done: write_unlock_irqrestore(&tasklist_lock, flags); @@ -215,14 +227,14 @@ asmlinkage void double_fault_c(struct pt_regs *fp) printk(KERN_EMERG "Double Fault\n"); #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) { - unsigned int cpu = smp_processor_id(); + unsigned int cpu = raw_smp_processor_id(); char buf[150]; - decode_address(buf, cpu_pda[cpu].retx); + decode_address(buf, cpu_pda[cpu].retx_doublefault); printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n", - (unsigned int)cpu_pda[cpu].seqstat & SEQSTAT_EXCAUSE, buf); - decode_address(buf, cpu_pda[cpu].dcplb_fault_addr); + (unsigned int)cpu_pda[cpu].seqstat_doublefault & SEQSTAT_EXCAUSE, buf); + decode_address(buf, cpu_pda[cpu].dcplb_doublefault_addr); printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %s\n", buf); - decode_address(buf, cpu_pda[cpu].icplb_fault_addr); + decode_address(buf, cpu_pda[cpu].icplb_doublefault_addr); printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %s\n", buf); decode_address(buf, fp->retx); @@ -245,13 +257,13 @@ static int kernel_mode_regs(struct pt_regs *regs) return regs->ipend & 0xffc0; } -asmlinkage void trap_c(struct pt_regs *fp) +asmlinkage notrace void trap_c(struct pt_regs *fp) { #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON int j; #endif #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO - unsigned int cpu = smp_processor_id(); + unsigned int cpu = raw_smp_processor_id(); #endif const char *strerror = NULL; int sig = 0; @@ -267,11 +279,6 @@ asmlinkage void trap_c(struct pt_regs *fp) * double faults if the stack has become corrupt */ -#ifndef CONFIG_KGDB - /* IPEND is skipped if KGDB isn't enabled (see entry code) */ - fp->ipend = bfin_read_IPEND(); -#endif - /* trap_c() will be called for exceptions. During exceptions * processing, the pc value should be set with retx value. * With this change we can cleanup some code in signal.c- TODO @@ -404,7 +411,7 @@ asmlinkage void trap_c(struct pt_regs *fp) /* 0x23 - Data CPLB protection violation, handled here */ case VEC_CPLB_VL: info.si_code = ILL_CPLB_VI; - sig = SIGBUS; + sig = SIGSEGV; strerror = KERN_NOTICE EXC_0x23(KERN_NOTICE); CHK_DEBUGGER_TRAP_MAYBE(); break; @@ -904,7 +911,7 @@ void show_stack(struct task_struct *task, unsigned long *stack) frame_no = 0; for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; - addr <= endstack; addr++, i++) { + addr < endstack; addr++, i++) { ret_addr = 0; if (!j && i % 8 == 0) @@ -949,6 +956,7 @@ void show_stack(struct task_struct *task, unsigned long *stack) } #endif } +EXPORT_SYMBOL(show_stack); void dump_stack(void) { @@ -1090,7 +1098,7 @@ void show_regs(struct pt_regs *fp) struct irqaction *action; unsigned int i; unsigned long flags = 0; - unsigned int cpu = smp_processor_id(); + unsigned int cpu = raw_smp_processor_id(); unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); verbose_printk(KERN_NOTICE "\n"); @@ -1116,10 +1124,16 @@ void show_regs(struct pt_regs *fp) verbose_printk(KERN_NOTICE "%s", linux_banner); - verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", - print_tainted()); - verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", - (long)fp->seqstat, fp->ipend, fp->syscfg); + verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", print_tainted()); + verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx IMASK: %04lx SYSCFG: %04lx\n", + (long)fp->seqstat, fp->ipend, cpu_pda[raw_smp_processor_id()].ex_imask, fp->syscfg); + if (fp->ipend & EVT_IRPTEN) + verbose_printk(KERN_NOTICE " Global Interrupts Disabled (IPEND[4])\n"); + if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 | + EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR))) + verbose_printk(KERN_NOTICE " Peripheral interrupts masked off\n"); + if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14))) + verbose_printk(KERN_NOTICE " Kernel interrupts masked off\n"); if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) { verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index d7ffe299b97..21ac7c26079 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -221,7 +221,7 @@ SECTIONS . = ALIGN(4); __ebss_l1 = .; } - ASSERT (SIZEOF(.data_a_l1) <= L1_DATA_A_LENGTH, "L1 data A overflow!") + ASSERT (SIZEOF(.data_l1) <= L1_DATA_A_LENGTH, "L1 data A overflow!") .data_b_l1 L1_DATA_B_START : AT(LOADADDR(.data_l1) + SIZEOF(.data_l1)) { @@ -262,7 +262,7 @@ SECTIONS . = ALIGN(4); __ebss_l2 = .; } - ASSERT (SIZEOF(.text_data_l1) <= L2_LENGTH, "L2 overflow!") + ASSERT (SIZEOF(.text_data_l2) <= L2_LENGTH, "L2 overflow!") /* Force trailing alignment of our init section so that when we * free our init memory, we don't leave behind a partial page. diff --git a/arch/blackfin/lib/ins.S b/arch/blackfin/lib/ins.S index 1863a6ba507..3edbd8db659 100644 --- a/arch/blackfin/lib/ins.S +++ b/arch/blackfin/lib/ins.S @@ -16,7 +16,7 @@ [--sp] = rets; \ [--sp] = (P5:0); \ sp += -12; \ - call ___ipipe_stall_root_raw; \ + call ___ipipe_disable_root_irqs_hw; \ sp += 12; \ (P5:0) = [sp++]; # define CLI_INNER_NOP @@ -28,7 +28,7 @@ #ifdef CONFIG_IPIPE # define DO_STI \ sp += -12; \ - call ___ipipe_unstall_root_raw; \ + call ___ipipe_enable_root_irqs_hw; \ sp += 12; \ 2: rets = [sp++]; #else diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c index 809be268e42..03e4a9941f0 100644 --- a/arch/blackfin/mach-bf518/boards/ezbrd.c +++ b/arch/blackfin/mach-bf518/boards/ezbrd.c @@ -199,15 +199,6 @@ static struct bfin5xx_spi_chip mmc_spi_chip_info = { }; #endif -#if defined(CONFIG_PBX) -static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { - .ctl_reg = 0x4, /* send zero */ - .enable_dma = 0, - .bits_per_word = 8, - .cs_change_per_word = 1, -}; -#endif - #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, @@ -296,24 +287,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_PBX) - { - .modalias = "fxs-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J11_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "fxo-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J19_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", @@ -539,7 +512,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { I2C_BOARD_INFO("pcf8574_lcd", 0x22), }, #endif -#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE) +#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE) { I2C_BOARD_INFO("pcf8574_keypad", 0x27), .irq = IRQ_PF8, diff --git a/arch/blackfin/mach-bf518/include/mach/anomaly.h b/arch/blackfin/mach-bf518/include/mach/anomaly.h index 753ed810e1c..e9c65390edd 100644 --- a/arch/blackfin/mach-bf518/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf518/include/mach/anomaly.h @@ -124,6 +124,7 @@ #define ANOMALY_05000386 (0) #define ANOMALY_05000389 (0) #define ANOMALY_05000400 (0) +#define ANOMALY_05000402 (0) #define ANOMALY_05000412 (0) #define ANOMALY_05000432 (0) #define ANOMALY_05000447 (0) diff --git a/arch/blackfin/mach-bf518/include/mach/blackfin.h b/arch/blackfin/mach-bf518/include/mach/blackfin.h index e8e14c2769e..83421d39314 100644 --- a/arch/blackfin/mach-bf518/include/mach/blackfin.h +++ b/arch/blackfin/mach-bf518/include/mach/blackfin.h @@ -68,11 +68,6 @@ #endif #endif -/* UART_IIR Register */ -#define STATUS(x) ((x << 1) & 0x06) -#define STATUS_P1 0x02 -#define STATUS_P0 0x01 - #define BFIN_UART_NR_PORTS 2 #define OFFSET_THR 0x00 /* Transmit Holding register */ @@ -88,11 +83,6 @@ #define OFFSET_SCR 0x1C /* SCR Scratch Register */ #define OFFSET_GCTL 0x24 /* Global Control Register */ -/* DPMC*/ -#define bfin_read_STOPCK_OFF() bfin_read_STOPCK() -#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val) -#define STOPCK_OFF STOPCK - /* PLL_DIV Masks */ #define CCLK_DIV1 CSEL_DIV1 /* CCLK = VCO / 1 */ #define CCLK_DIV2 CSEL_DIV2 /* CCLK = VCO / 2 */ diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index b09484f538f..08a3f01c988 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -151,46 +151,6 @@ static struct platform_device musb_device = { }; #endif -#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) -static struct mtd_partition ezkit_partitions[] = { - { - .name = "bootloader(nor)", - .size = 0x40000, - .offset = 0, - }, { - .name = "linux kernel(nor)", - .size = 0x1C0000, - .offset = MTDPART_OFS_APPEND, - }, { - .name = "file system(nor)", - .size = MTDPART_SIZ_FULL, - .offset = MTDPART_OFS_APPEND, - } -}; - -static struct physmap_flash_data ezkit_flash_data = { - .width = 2, - .parts = ezkit_partitions, - .nr_parts = ARRAY_SIZE(ezkit_partitions), -}; - -static struct resource ezkit_flash_resource = { - .start = 0x20000000, - .end = 0x201fffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device ezkit_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &ezkit_flash_data, - }, - .num_resources = 1, - .resource = &ezkit_flash_resource, -}; -#endif - #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) static struct mtd_partition partition_info[] = { { @@ -275,6 +235,14 @@ static struct platform_device rtc_device = { #endif #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { { .name = "smc91x-regs", @@ -293,6 +261,9 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, }; #endif @@ -300,10 +271,15 @@ static struct platform_device smc91x_device = { static struct resource dm9000_resources[] = { [0] = { .start = 0x203FB800, - .end = 0x203FB800 + 8, + .end = 0x203FB800 + 1, .flags = IORESOURCE_MEM, }, [1] = { + .start = 0x203FB804, + .end = 0x203FB804 + 1, + .flags = IORESOURCE_MEM, + }, + [2] = { .start = IRQ_PF9, .end = IRQ_PF9, .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE), @@ -479,13 +455,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = { }; #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) -static struct bfin5xx_spi_chip ad9960_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) static struct bfin5xx_spi_chip mmc_spi_chip_info = { .enable_dma = 0, @@ -493,15 +462,6 @@ static struct bfin5xx_spi_chip mmc_spi_chip_info = { }; #endif -#if defined(CONFIG_PBX) -static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { - .ctl_reg = 0x4, /* send zero */ - .enable_dma = 0, - .bits_per_word = 8, - .cs_change_per_word = 1, -}; -#endif - #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, @@ -568,22 +528,13 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) \ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) { - .modalias = "ad1836-spi", + .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, .controller_data = &ad1836_spi_chip_info, }, #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) - { - .modalias = "ad9960-spi", - .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 1, - .controller_data = &ad9960_spi_chip_info, - }, -#endif #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) { .modalias = "mmc_spi", @@ -594,24 +545,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_PBX) - { - .modalias = "fxs-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J11_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "fxo-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J19_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", @@ -689,6 +622,55 @@ static struct platform_device bfin_fb_adv7393_device = { }; #endif +#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE) +static struct mtd_partition cm_partitions[] = { + { + .name = "bootloader(nor)", + .size = 0x40000, + .offset = 0, + }, { + .name = "linux kernel(nor)", + .size = 0x100000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "file system(nor)", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct physmap_flash_data cm_flash_data = { + .width = 2, + .parts = cm_partitions, + .nr_parts = ARRAY_SIZE(cm_partitions), +}; + +static unsigned cm_flash_gpios[] = { GPIO_PH9, GPIO_PG11 }; + +static struct resource cm_flash_resource[] = { + { + .name = "cfi_probe", + .start = 0x20000000, + .end = 0x201fffff, + .flags = IORESOURCE_MEM, + }, { + .start = (unsigned long)cm_flash_gpios, + .end = ARRAY_SIZE(cm_flash_gpios), + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device cm_flash_device = { + .name = "gpio-addr-flash", + .id = 0, + .dev = { + .platform_data = &cm_flash_data, + }, + .num_resources = ARRAY_SIZE(cm_flash_resource), + .resource = cm_flash_resource, +}; +#endif + #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) static struct resource bfin_uart_resources[] = { #ifdef CONFIG_SERIAL_BFIN_UART0 @@ -796,13 +778,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) { I2C_BOARD_INFO("pcf8574_lcd", 0x22), - .type = "pcf8574_lcd", }, #endif -#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE) +#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE) { I2C_BOARD_INFO("pcf8574_keypad", 0x27), - .type = "pcf8574_keypad", .irq = IRQ_PF8, }, #endif @@ -876,7 +856,7 @@ static struct platform_device bfin_dpmc = { }, }; -static struct platform_device *stamp_devices[] __initdata = { +static struct platform_device *cmbf527_devices[] __initdata = { &bfin_dpmc, @@ -959,8 +939,8 @@ static struct platform_device *stamp_devices[] __initdata = { &bfin_device_gpiokeys, #endif -#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) - &ezkit_flash_device, +#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE) + &cm_flash_device, #endif &bfin_gpios_device, @@ -971,7 +951,7 @@ static int __init cm_init(void) printk(KERN_INFO "%s(): registering device resources\n", __func__); i2c_register_board_info(0, bfin_i2c_board_info, ARRAY_SIZE(bfin_i2c_board_info)); - platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); + platform_add_devices(cmbf527_devices, ARRAY_SIZE(cmbf527_devices)); spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); return 0; } diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c index 2ad68cd10ae..68b4c804364 100644 --- a/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/arch/blackfin/mach-bf527/boards/ezbrd.c @@ -263,15 +263,6 @@ static struct bfin5xx_spi_chip mmc_spi_chip_info = { }; #endif -#if defined(CONFIG_PBX) -static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { - .ctl_reg = 0x4, /* send zero */ - .enable_dma = 0, - .bits_per_word = 8, - .cs_change_per_word = 1, -}; -#endif - #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, @@ -376,24 +367,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_PBX) - { - .modalias = "fxs-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J11_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "fxo-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J19_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", @@ -596,7 +569,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { I2C_BOARD_INFO("pcf8574_lcd", 0x22), }, #endif -#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE) +#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE) { I2C_BOARD_INFO("pcf8574_keypad", 0x27), .irq = IRQ_PF8, diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 75e563d3f9d..2849b09abe9 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -292,6 +292,14 @@ static struct platform_device rtc_device = { #endif #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { { .name = "smc91x-regs", @@ -310,6 +318,9 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, }; #endif @@ -501,13 +512,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = { }; #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) -static struct bfin5xx_spi_chip ad9960_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) static struct bfin5xx_spi_chip mmc_spi_chip_info = { .enable_dma = 0, @@ -515,15 +519,6 @@ static struct bfin5xx_spi_chip mmc_spi_chip_info = { }; #endif -#if defined(CONFIG_PBX) -static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { - .ctl_reg = 0x4, /* send zero */ - .enable_dma = 0, - .bits_per_word = 8, - .cs_change_per_word = 1, -}; -#endif - #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, @@ -614,22 +609,13 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) \ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) { - .modalias = "ad1836-spi", + .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, .controller_data = &ad1836_spi_chip_info, }, #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) - { - .modalias = "ad9960-spi", - .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 1, - .controller_data = &ad9960_spi_chip_info, - }, -#endif #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) { .modalias = "mmc_spi", @@ -641,24 +627,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_PBX) - { - .modalias = "fxs-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J11_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "fxo-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J19_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", @@ -863,7 +831,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { I2C_BOARD_INFO("pcf8574_lcd", 0x22), }, #endif -#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE) +#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE) { I2C_BOARD_INFO("pcf8574_keypad", 0x27), .irq = IRQ_PF8, diff --git a/arch/blackfin/mach-bf527/include/mach/anomaly.h b/arch/blackfin/mach-bf527/include/mach/anomaly.h index c438ca89d8c..3f9052687fa 100644 --- a/arch/blackfin/mach-bf527/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf527/include/mach/anomaly.h @@ -7,7 +7,7 @@ */ /* This file should be up to date with: - * - Revision C, 03/13/2009; ADSP-BF526 Blackfin Processor Anomaly List + * - Revision D, 08/14/2009; ADSP-BF526 Blackfin Processor Anomaly List * - Revision F, 03/03/2009; ADSP-BF527 Blackfin Processor Anomaly List */ @@ -176,7 +176,7 @@ #define ANOMALY_05000443 (1) /* The WURESET Bit in the SYSCR Register is not Functional */ #define ANOMALY_05000445 (1) -/* USB DMA Short Packet Data Corruption */ +/* USB DMA Mode 1 Short Packet Data Corruption */ #define ANOMALY_05000450 (1) /* BCODE_QUICKBOOT, BCODE_ALLBOOT, and BCODE_FULLBOOT Settings in SYSCR Register Not Functional */ #define ANOMALY_05000451 (1) @@ -186,12 +186,20 @@ #define ANOMALY_05000456 (1) /* Host DMA Port Responds to Certain Bus Activity Without HOST_CE Assertion */ #define ANOMALY_05000457 (1) +/* USB DMA Mode 1 Failure When Multiple USB DMA Channels Are Concurrently Enabled */ +#define ANOMALY_05000460 (1) /* False Hardware Error when RETI Points to Invalid Memory */ #define ANOMALY_05000461 (1) +/* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */ +#define ANOMALY_05000462 (1) /* USB Rx DMA hang */ #define ANOMALY_05000465 (1) +/* TxPktRdy Bit Not Set for Transmit Endpoint When Core and DMA Access USB Endpoint FIFOs Simultaneously */ +#define ANOMALY_05000466 (1) /* Possible RX data corruption when control & data EP FIFOs are accessed via the core */ #define ANOMALY_05000467 (1) +/* PLL Latches Incorrect Settings During Reset */ +#define ANOMALY_05000469 (1) /* Anomalies that don't exist on this proc */ #define ANOMALY_05000099 (0) @@ -238,6 +246,7 @@ #define ANOMALY_05000362 (1) #define ANOMALY_05000363 (0) #define ANOMALY_05000400 (0) +#define ANOMALY_05000402 (0) #define ANOMALY_05000412 (0) #define ANOMALY_05000447 (0) #define ANOMALY_05000448 (0) diff --git a/arch/blackfin/mach-bf527/include/mach/blackfin.h b/arch/blackfin/mach-bf527/include/mach/blackfin.h index 03665a8e16b..ea9cb0fef8b 100644 --- a/arch/blackfin/mach-bf527/include/mach/blackfin.h +++ b/arch/blackfin/mach-bf527/include/mach/blackfin.h @@ -56,11 +56,6 @@ #endif #endif -/* UART_IIR Register */ -#define STATUS(x) ((x << 1) & 0x06) -#define STATUS_P1 0x02 -#define STATUS_P0 0x01 - #define BFIN_UART_NR_PORTS 2 #define OFFSET_THR 0x00 /* Transmit Holding register */ @@ -76,11 +71,6 @@ #define OFFSET_SCR 0x1C /* SCR Scratch Register */ #define OFFSET_GCTL 0x24 /* Global Control Register */ -/* DPMC*/ -#define bfin_read_STOPCK_OFF() bfin_read_STOPCK() -#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val) -#define STOPCK_OFF STOPCK - /* PLL_DIV Masks */ #define CCLK_DIV1 CSEL_DIV1 /* CCLK = VCO / 1 */ #define CCLK_DIV2 CSEL_DIV2 /* CCLK = VCO / 2 */ diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c index 38cf8ffd6d7..6c2b47fe4fe 100644 --- a/arch/blackfin/mach-bf533/boards/H8606.c +++ b/arch/blackfin/mach-bf533/boards/H8606.c @@ -88,6 +88,14 @@ static struct platform_device dm9000_device = { #endif #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { { .name = "smc91x-regs", @@ -110,6 +118,9 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, }; #endif @@ -190,15 +201,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = { }; #endif -#if defined(CONFIG_PBX) -static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { - .ctl_reg = 0x1c04, - .enable_dma = 0, - .bits_per_word = 8, - .cs_change_per_word = 1, -}; -#endif - /* Notice: for blackfin, the speed_hz is the value of register * SPI_BAUD, not the real baudrate */ static struct spi_board_info bfin_spi_board_info[] __initdata = { @@ -229,7 +231,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) { - .modalias = "ad1836-spi", + .modalias = "ad1836", .max_speed_hz = 16, .bus_num = 1, .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, @@ -237,23 +239,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_PBX) - { - .modalias = "fxs-spi", - .max_speed_hz = 4, - .bus_num = 1, - .chip_select = 3, - .controller_data = &spi_si3xxx_chip_info, - }, - - { - .modalias = "fxo-spi", - .max_speed_hz = 4, - .bus_num = 1, - .chip_select = 2, - .controller_data = &spi_si3xxx_chip_info, - }, -#endif }; /* SPI (0) */ diff --git a/arch/blackfin/mach-bf533/boards/blackstamp.c b/arch/blackfin/mach-bf533/boards/blackstamp.c index 9ecdc361fa6..8208d67e2c9 100644 --- a/arch/blackfin/mach-bf533/boards/blackstamp.c +++ b/arch/blackfin/mach-bf533/boards/blackstamp.c @@ -48,6 +48,14 @@ static struct platform_device rtc_device = { * Driver needs to know address, irq and flag pin. */ #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { { .name = "smc91x-regs", @@ -66,6 +74,9 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, }; #endif diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c index 1443e92d8b6..7443b26c80c 100644 --- a/arch/blackfin/mach-bf533/boards/cm_bf533.c +++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c @@ -31,8 +31,10 @@ #include <linux/platform_device.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> #include <linux/spi/spi.h> #include <linux/spi/flash.h> +#include <linux/spi/mmc_spi.h> #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) #include <linux/usb/isp1362.h> #endif @@ -130,7 +132,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) { - .modalias = "ad1836-spi", + .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, @@ -141,9 +143,9 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) { .modalias = "mmc_spi", - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, - .chip_select = 5, + .chip_select = 1, .controller_data = &mmc_spi_chip_info, .mode = SPI_MODE_3, }, @@ -195,6 +197,14 @@ static struct platform_device rtc_device = { #endif #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { { .start = 0x20200300, @@ -211,6 +221,43 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, +}; +#endif + +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) +#include <linux/smsc911x.h> + +static struct resource smsc911x_resources[] = { + { + .name = "smsc911x-memory", + .start = 0x20308000, + .end = 0x20308000 + 0xFF, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PF8, + .end = IRQ_PF8, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, +}; + +static struct smsc911x_platform_config smsc911x_config = { + .flags = SMSC911X_USE_16BIT, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct platform_device smsc911x_device = { + .name = "smsc911x", + .id = 0, + .num_resources = ARRAY_SIZE(smsc911x_resources), + .resource = smsc911x_resources, + .dev = { + .platform_data = &smsc911x_config, + }, }; #endif @@ -324,6 +371,68 @@ static struct platform_device isp1362_hcd_device = { }; #endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) +static struct resource net2272_bfin_resources[] = { + { + .start = 0x20300000, + .end = 0x20300000 + 0x100, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PF6, + .end = IRQ_PF6, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device net2272_bfin_device = { + .name = "net2272", + .id = -1, + .num_resources = ARRAY_SIZE(net2272_bfin_resources), + .resource = net2272_bfin_resources, +}; +#endif + + + +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition para_partitions[] = { + { + .name = "bootloader(nor)", + .size = 0x40000, + .offset = 0, + }, { + .name = "linux+rootfs(nor)", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + }, +}; + +static struct physmap_flash_data para_flash_data = { + .width = 2, + .parts = para_partitions, + .nr_parts = ARRAY_SIZE(para_partitions), +}; + +static struct resource para_flash_resource = { + .start = 0x20000000, + .end = 0x201fffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device para_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = ¶_flash_data, + }, + .num_resources = 1, + .resource = ¶_flash_resource, +}; +#endif + + + static const unsigned int cclk_vlev_datasheet[] = { VRPAIR(VLEV_085, 250000000), @@ -382,10 +491,22 @@ static struct platform_device *cm_bf533_devices[] __initdata = { &smc91x_device, #endif +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) + &smsc911x_device, +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) + &net2272_bfin_device, +#endif + #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) &bfin_spi0_device, #endif +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) + ¶_flash_device, +#endif + &bfin_gpios_device, }; diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c index 4e3e511bf14..fd518e383b7 100644 --- a/arch/blackfin/mach-bf533/boards/ezkit.c +++ b/arch/blackfin/mach-bf533/boards/ezkit.c @@ -67,6 +67,14 @@ static struct platform_device bfin_fb_adv7393_device = { * Driver needs to know address, irq and flag pin. */ #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { { .name = "smc91x-regs", @@ -84,6 +92,9 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, }; #endif @@ -263,7 +274,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) { - .modalias = "ad1836-spi", + .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index 3d743ccaff6..729fd7c2633 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -35,6 +35,7 @@ #include <linux/mtd/physmap.h> #include <linux/spi/spi.h> #include <linux/spi/flash.h> +#include <linux/spi/mmc_spi.h> #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) #include <linux/usb/isp1362.h> #endif @@ -62,6 +63,14 @@ static struct platform_device rtc_device = { * Driver needs to know address, irq and flag pin. */ #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { { .name = "smc91x-regs", @@ -80,6 +89,9 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, }; #endif @@ -207,19 +219,38 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = { }; #endif -#if defined(CONFIG_PBX) -static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { - .ctl_reg = 0x4, /* send zero */ - .enable_dma = 0, - .bits_per_word = 8, - .cs_change_per_word = 1, +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) +static struct bfin5xx_spi_chip spidev_chip_info = { + .enable_dma = 0, + .bits_per_word = 8, }; #endif -#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) -static struct bfin5xx_spi_chip spidev_chip_info = { +#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +#define MMC_SPI_CARD_DETECT_INT IRQ_PF5 +static int bfin_mmc_spi_init(struct device *dev, + irqreturn_t (*detect_int)(int, void *), void *data) +{ + return request_irq(MMC_SPI_CARD_DETECT_INT, detect_int, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "mmc-spi-detect", data); +} + +static void bfin_mmc_spi_exit(struct device *dev, void *data) +{ + free_irq(MMC_SPI_CARD_DETECT_INT, data); +} + +static struct mmc_spi_platform_data bfin_mmc_spi_pdata = { + .init = bfin_mmc_spi_init, + .exit = bfin_mmc_spi_exit, + .detect_delay = 100, /* msecs */ +}; + +static struct bfin5xx_spi_chip mmc_spi_chip_info = { .enable_dma = 0, .bits_per_word = 8, + .pio_interrupt = 0, }; #endif @@ -250,33 +281,14 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) { - .modalias = "ad1836-spi", - .max_speed_hz = 31250000, /* max spi clock (SCK) speed in HZ */ + .modalias = "ad1836", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, .controller_data = &ad1836_spi_chip_info, }, #endif -#if defined(CONFIG_PBX) - { - .modalias = "fxs-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J11_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "fxo-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J19_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, -#endif - #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) { .modalias = "spidev", @@ -286,6 +298,17 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .controller_data = &spidev_chip_info, }, #endif +#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) + { + .modalias = "mmc_spi", + .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 4, + .platform_data = &bfin_mmc_spi_pdata, + .controller_data = &mmc_spi_chip_info, + .mode = SPI_MODE_3, + }, +#endif }; #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) @@ -458,7 +481,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { I2C_BOARD_INFO("pcf8574_lcd", 0x22), }, #endif -#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE) +#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE) { I2C_BOARD_INFO("pcf8574_keypad", 0x27), .irq = 39, diff --git a/arch/blackfin/mach-bf533/dma.c b/arch/blackfin/mach-bf533/dma.c index 0a6eb8f24d9..7a443c37fb9 100644 --- a/arch/blackfin/mach-bf533/dma.c +++ b/arch/blackfin/mach-bf533/dma.c @@ -76,12 +76,12 @@ int channel2irq(unsigned int channel) ret_irq = IRQ_SPI; break; - case CH_UART_RX: - ret_irq = IRQ_UART_RX; + case CH_UART0_RX: + ret_irq = IRQ_UART0_RX; break; - case CH_UART_TX: - ret_irq = IRQ_UART_TX; + case CH_UART0_TX: + ret_irq = IRQ_UART0_TX; break; case CH_MEM_STREAM0_SRC: diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h index 4062e24e759..6965b4088c4 100644 --- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h @@ -131,11 +131,11 @@ struct bfin_serial_res { struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC00400, - IRQ_UART_RX, - IRQ_UART_ERROR, + IRQ_UART0_RX, + IRQ_UART0_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA - CH_UART_TX, - CH_UART_RX, + CH_UART0_TX, + CH_UART0_RX, #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS CONFIG_UART0_CTS_PIN, diff --git a/arch/blackfin/mach-bf533/include/mach/blackfin.h b/arch/blackfin/mach-bf533/include/mach/blackfin.h index 39aa175f19f..499e897a4f4 100644 --- a/arch/blackfin/mach-bf533/include/mach/blackfin.h +++ b/arch/blackfin/mach-bf533/include/mach/blackfin.h @@ -43,13 +43,6 @@ #define BFIN_UART_NR_PORTS 1 -#define CH_UART_RX CH_UART0_RX -#define CH_UART_TX CH_UART0_TX - -#define IRQ_UART_ERROR IRQ_UART0_ERROR -#define IRQ_UART_RX IRQ_UART0_RX -#define IRQ_UART_TX IRQ_UART0_TX - #define OFFSET_THR 0x00 /* Transmit Holding register */ #define OFFSET_RBR 0x00 /* Receive Buffer register */ #define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */ diff --git a/arch/blackfin/mach-bf537/boards/Kconfig b/arch/blackfin/mach-bf537/boards/Kconfig index 77c59da87e8..44132fda63b 100644 --- a/arch/blackfin/mach-bf537/boards/Kconfig +++ b/arch/blackfin/mach-bf537/boards/Kconfig @@ -9,11 +9,17 @@ config BFIN537_STAMP help BF537-STAMP board support. -config BFIN537_BLUETECHNIX_CM - bool "Bluetechnix CM-BF537" +config BFIN537_BLUETECHNIX_CM_E + bool "Bluetechnix CM-BF537E" depends on (BF537) help - CM-BF537 support for EVAL- and DEV-Board. + CM-BF537E support for EVAL- and DEV-Board. + +config BFIN537_BLUETECHNIX_CM_U + bool "Bluetechnix CM-BF537U" + depends on (BF537) + help + CM-BF537U support for EVAL- and DEV-Board. config BFIN537_BLUETECHNIX_TCM bool "Bluetechnix TCM-BF537" diff --git a/arch/blackfin/mach-bf537/boards/Makefile b/arch/blackfin/mach-bf537/boards/Makefile index 68b98a7af6a..7e6aa4e5b20 100644 --- a/arch/blackfin/mach-bf537/boards/Makefile +++ b/arch/blackfin/mach-bf537/boards/Makefile @@ -3,7 +3,8 @@ # obj-$(CONFIG_BFIN537_STAMP) += stamp.o -obj-$(CONFIG_BFIN537_BLUETECHNIX_CM) += cm_bf537.o +obj-$(CONFIG_BFIN537_BLUETECHNIX_CM_E) += cm_bf537e.o +obj-$(CONFIG_BFIN537_BLUETECHNIX_CM_U) += cm_bf537u.o obj-$(CONFIG_BFIN537_BLUETECHNIX_TCM) += tcm_bf537.o obj-$(CONFIG_PNAV10) += pnav10.o obj-$(CONFIG_CAMSIG_MINOTAUR) += minotaur.o diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c new file mode 100644 index 00000000000..87acb7dd2df --- /dev/null +++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c @@ -0,0 +1,727 @@ +/* + * File: arch/blackfin/mach-bf537/boards/cm_bf537.c + * Based on: arch/blackfin/mach-bf533/boards/ezkit.c + * Author: Aidan Williams <aidan@nicta.com.au> + * + * Created: 2005 + * Description: Board description file + * + * Modified: + * Copyright 2005 National ICT Australia (NICTA) + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/device.h> +#include <linux/etherdevice.h> +#include <linux/platform_device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/spi/spi.h> +#include <linux/spi/flash.h> +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) +#include <linux/usb/isp1362.h> +#endif +#include <linux/ata_platform.h> +#include <linux/irq.h> +#include <asm/dma.h> +#include <asm/bfin5xx_spi.h> +#include <asm/portmux.h> +#include <asm/dpmc.h> + +/* + * Name the Board for the /proc/cpuinfo + */ +const char bfin_board_name[] = "Bluetechnix CM BF537E"; + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI peripherals info goes here */ + +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) +static struct mtd_partition bfin_spi_flash_partitions[] = { + { + .name = "bootloader(spi)", + .size = 0x00020000, + .offset = 0, + .mask_flags = MTD_CAP_ROM + }, { + .name = "linux kernel(spi)", + .size = 0xe0000, + .offset = 0x20000 + }, { + .name = "file system(spi)", + .size = 0x700000, + .offset = 0x00100000, + } +}; + +static struct flash_platform_data bfin_spi_flash_data = { + .name = "m25p80", + .parts = bfin_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), + .type = "m25p64", +}; + +/* SPI flash chip (m25p64) */ +static struct bfin5xx_spi_chip spi_flash_chip_info = { + .enable_dma = 0, /* use dma transfer with this chip*/ + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE) +/* SPI ADC chip */ +static struct bfin5xx_spi_chip spi_adc_chip_info = { + .enable_dma = 1, /* use dma transfer with this chip*/ + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +static struct bfin5xx_spi_chip ad1836_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +static struct bfin5xx_spi_chip mmc_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 8, +}; +#endif + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) + { + /* the modalias must be the same as spi device driver name */ + .modalias = "m25p80", /* Name of spi_driver for this device */ + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ + .platform_data = &bfin_spi_flash_data, + .controller_data = &spi_flash_chip_info, + .mode = SPI_MODE_3, + }, +#endif + +#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE) + { + .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ + .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. */ + .platform_data = NULL, /* No spi_driver specific config */ + .controller_data = &spi_adc_chip_info, + }, +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) + { + .modalias = "ad1836", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, + .controller_data = &ad1836_spi_chip_info, + }, +#endif + +#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) + { + .modalias = "mmc_spi", + .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 1, + .controller_data = &mmc_spi_chip_info, + .mode = SPI_MODE_3, + }, +#endif +}; + +/* SPI (0) */ +static struct resource bfin_spi0_resource[] = { + [0] = { + .start = SPI0_REGBASE, + .end = SPI0_REGBASE + 0xFF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = CH_SPI, + .end = CH_SPI, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = IRQ_SPI, + .end = IRQ_SPI, + .flags = IORESOURCE_IRQ, + }, +}; + +/* SPI controller data */ +static struct bfin5xx_spi_master bfin_spi0_info = { + .num_chipselect = 8, + .enable_dma = 1, /* master has the ability to do dma transfer */ + .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, +}; + +static struct platform_device bfin_spi0_device = { + .name = "bfin-spi", + .id = 0, /* Bus number */ + .num_resources = ARRAY_SIZE(bfin_spi0_resource), + .resource = bfin_spi0_resource, + .dev = { + .platform_data = &bfin_spi0_info, /* Passed to driver */ + }, +}; +#endif /* spi master and devices */ + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) +static struct platform_device rtc_device = { + .name = "rtc-bfin", + .id = -1, +}; +#endif + +#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE) +static struct platform_device hitachi_fb_device = { + .name = "hitachi-tx09", +}; +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + +static struct resource smc91x_resources[] = { + { + .start = 0x20200300, + .end = 0x20200300 + 16, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PF14, + .end = IRQ_PF14, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, +}; +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) +static struct resource isp1362_hcd_resources[] = { + { + .start = 0x20308000, + .end = 0x20308000, + .flags = IORESOURCE_MEM, + }, { + .start = 0x20308004, + .end = 0x20308004, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PG15, + .end = IRQ_PG15, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct isp1362_platform_data isp1362_priv = { + .sel15Kres = 1, + .clknotstop = 0, + .oc_enable = 0, + .int_act_high = 0, + .int_edge_triggered = 0, + .remote_wakeup_connected = 0, + .no_power_switching = 1, + .power_switching_mode = 0, +}; + +static struct platform_device isp1362_hcd_device = { + .name = "isp1362-hcd", + .id = 0, + .dev = { + .platform_data = &isp1362_priv, + }, + .num_resources = ARRAY_SIZE(isp1362_hcd_resources), + .resource = isp1362_hcd_resources, +}; +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) +static struct resource net2272_bfin_resources[] = { + { + .start = 0x20300000, + .end = 0x20300000 + 0x100, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PG13, + .end = IRQ_PG13, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device net2272_bfin_device = { + .name = "net2272", + .id = -1, + .num_resources = ARRAY_SIZE(net2272_bfin_resources), + .resource = net2272_bfin_resources, +}; +#endif + +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + +#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE) +static struct mtd_partition cm_partitions[] = { + { + .name = "bootloader(nor)", + .size = 0x40000, + .offset = 0, + }, { + .name = "linux kernel(nor)", + .size = 0x100000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "file system(nor)", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct physmap_flash_data cm_flash_data = { + .width = 2, + .parts = cm_partitions, + .nr_parts = ARRAY_SIZE(cm_partitions), +}; + +static unsigned cm_flash_gpios[] = { GPIO_PF4 }; + +static struct resource cm_flash_resource[] = { + { + .name = "cfi_probe", + .start = 0x20000000, + .end = 0x201fffff, + .flags = IORESOURCE_MEM, + }, { + .start = (unsigned long)cm_flash_gpios, + .end = ARRAY_SIZE(cm_flash_gpios), + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device cm_flash_device = { + .name = "gpio-addr-flash", + .id = 0, + .dev = { + .platform_data = &cm_flash_data, + }, + .num_resources = ARRAY_SIZE(cm_flash_resource), + .resource = cm_flash_resource, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +#ifdef CONFIG_BFIN_UART0_CTSRTS + { + /* + * Refer to arch/blackfin/mach-xxx/include/mach/gpio.h for the GPIO map. + */ + .start = -1, + .end = -1, + .flags = IORESOURCE_IO, + }, + { + /* + * Refer to arch/blackfin/mach-xxx/include/mach/gpio.h for the GPIO map. + */ + .start = -1, + .end = -1, + .flags = IORESOURCE_IO, + }, +#endif +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { + { + .start = 0xFFC02000, + .end = 0xFFC020FF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, +#ifdef CONFIG_BFIN_UART1_CTSRTS + { + /* + * Refer to arch/blackfin/mach-xxx/include/mach/gpio.h for the GPIO map. + */ + .start = -1, + .end = -1, + .flags = IORESOURCE_IO, + }, + { + /* + * Refer to arch/blackfin/mach-xxx/include/mach/gpio.h for the GPIO map. + */ + .start = -1, + .end = -1, + .flags = IORESOURCE_IO, + }, +#endif +}; + +static struct platform_device bfin_uart1_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, +}; +#endif +#endif + +#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) +#ifdef CONFIG_BFIN_SIR0 +static struct resource bfin_sir0_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX+1, + .flags = IORESOURCE_DMA, + }, +}; +static struct platform_device bfin_sir0_device = { + .name = "bfin_sir", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_sir0_resources), + .resource = bfin_sir0_resources, +}; +#endif +#ifdef CONFIG_BFIN_SIR1 +static struct resource bfin_sir1_resources[] = { + { + .start = 0xFFC02000, + .end = 0xFFC020FF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX+1, + .flags = IORESOURCE_DMA, + }, +}; +static struct platform_device bfin_sir1_device = { + .name = "bfin_sir", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_sir1_resources), + .resource = bfin_sir1_resources, +}; +#endif +#endif + +#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static struct resource bfin_twi0_resource[] = { + [0] = { + .start = TWI0_REGBASE, + .end = TWI0_REGBASE, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TWI, + .end = IRQ_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device i2c_bfin_twi_device = { + .name = "i2c-bfin-twi", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_twi0_resource), + .resource = bfin_twi0_resource, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +static struct platform_device bfin_sport0_uart_device = { + .name = "bfin-sport-uart", + .id = 0, +}; + +static struct platform_device bfin_sport1_uart_device = { + .name = "bfin-sport-uart", + .id = 1, +}; +#endif + +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +static struct platform_device bfin_mii_bus = { + .name = "bfin_mii_bus", +}; + +static struct platform_device bfin_mac_device = { + .name = "bfin_mac", + .dev.platform_data = &bfin_mii_bus, +}; +#endif + +#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) +#define PATA_INT IRQ_PF14 + +static struct pata_platform_info bfin_pata_platform_data = { + .ioport_shift = 2, + .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED, +}; + +static struct resource bfin_pata_resources[] = { + { + .start = 0x2030C000, + .end = 0x2030C01F, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x2030D018, + .end = 0x2030D01B, + .flags = IORESOURCE_MEM, + }, + { + .start = PATA_INT, + .end = PATA_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pata_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(bfin_pata_resources), + .resource = bfin_pata_resources, + .dev = { + .platform_data = &bfin_pata_platform_data, + } +}; +#endif + +static const unsigned int cclk_vlev_datasheet[] = +{ + VRPAIR(VLEV_085, 250000000), + VRPAIR(VLEV_090, 376000000), + VRPAIR(VLEV_095, 426000000), + VRPAIR(VLEV_100, 426000000), + VRPAIR(VLEV_105, 476000000), + VRPAIR(VLEV_110, 476000000), + VRPAIR(VLEV_115, 476000000), + VRPAIR(VLEV_120, 500000000), + VRPAIR(VLEV_125, 533000000), + VRPAIR(VLEV_130, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + +static struct platform_device *cm_bf537e_devices[] __initdata = { + + &bfin_dpmc, + +#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE) + &hitachi_fb_device, +#endif + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) + &rtc_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) +#ifdef CONFIG_BFIN_SIR0 + &bfin_sir0_device, +#endif +#ifdef CONFIG_BFIN_SIR1 + &bfin_sir1_device, +#endif +#endif + +#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) + &i2c_bfin_twi_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) + &bfin_sport0_uart_device, + &bfin_sport1_uart_device, +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) + &isp1362_hcd_device, +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif + +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) + &bfin_mii_bus, + &bfin_mac_device, +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) + &net2272_bfin_device, +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &bfin_spi0_device, +#endif + +#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) + &bfin_pata_device, +#endif + +#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE) + &cm_flash_device, +#endif + + &bfin_gpios_device, +}; + +static int __init cm_bf537e_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __func__); + platform_add_devices(cm_bf537e_devices, ARRAY_SIZE(cm_bf537e_devices)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); +#endif + +#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) + irq_desc[PATA_INT].status |= IRQ_NOAUTOEN; +#endif + return 0; +} + +arch_initcall(cm_bf537e_init); + +void bfin_get_ether_addr(char *addr) +{ + random_ether_addr(addr); + printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__); +} +EXPORT_SYMBOL(bfin_get_ether_addr); diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c index 2a87d1cfcd0..8219dc3d65b 100644 --- a/arch/blackfin/mach-bf537/boards/cm_bf537.c +++ b/arch/blackfin/mach-bf537/boards/cm_bf537u.c @@ -1,5 +1,5 @@ /* - * File: arch/blackfin/mach-bf537/boards/cm_bf537.c + * File: arch/blackfin/mach-bf537/boards/cm_bf537u.c * Based on: arch/blackfin/mach-bf533/boards/ezkit.c * Author: Aidan Williams <aidan@nicta.com.au> * @@ -45,11 +45,12 @@ #include <asm/bfin5xx_spi.h> #include <asm/portmux.h> #include <asm/dpmc.h> +#include <linux/spi/mmc_spi.h> /* * Name the Board for the /proc/cpuinfo */ -const char bfin_board_name[] = "Bluetechnix CM BF537"; +const char bfin_board_name[] = "Bluetechnix CM BF537U"; #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) /* all SPI peripherals info goes here */ @@ -101,13 +102,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = { }; #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) -static struct bfin5xx_spi_chip ad9960_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) static struct bfin5xx_spi_chip mmc_spi_chip_info = { .enable_dma = 0, @@ -142,7 +136,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) { - .modalias = "ad1836-spi", + .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, @@ -150,16 +144,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) - { - .modalias = "ad9960-spi", - .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 1, - .controller_data = &ad9960_spi_chip_info, - }, -#endif - #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) { .modalias = "mmc_spi", @@ -223,6 +207,14 @@ static struct platform_device hitachi_fb_device = { #endif #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { { .start = 0x20200300, @@ -240,6 +232,9 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, }; #endif @@ -324,7 +319,7 @@ static struct mtd_partition cm_partitions[] = { .offset = 0, }, { .name = "linux kernel(nor)", - .size = 0xE0000, + .size = 0x100000, .offset = MTDPART_OFS_APPEND, }, { .name = "file system(nor)", @@ -339,7 +334,7 @@ static struct physmap_flash_data cm_flash_data = { .nr_parts = ARRAY_SIZE(cm_partitions), }; -static unsigned cm_flash_gpios[] = { GPIO_PF4 }; +static unsigned cm_flash_gpios[] = { GPIO_PH0 }; static struct resource cm_flash_resource[] = { { @@ -548,7 +543,7 @@ static struct platform_device bfin_dpmc = { }, }; -static struct platform_device *cm_bf537_devices[] __initdata = { +static struct platform_device *cm_bf537u_devices[] __initdata = { &bfin_dpmc, @@ -614,10 +609,10 @@ static struct platform_device *cm_bf537_devices[] __initdata = { &bfin_gpios_device, }; -static int __init cm_bf537_init(void) +static int __init cm_bf537u_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); - platform_add_devices(cm_bf537_devices, ARRAY_SIZE(cm_bf537_devices)); + platform_add_devices(cm_bf537u_devices, ARRAY_SIZE(cm_bf537u_devices)); #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); #endif @@ -628,7 +623,7 @@ static int __init cm_bf537_init(void) return 0; } -arch_initcall(cm_bf537_init); +arch_initcall(cm_bf537u_init); void bfin_get_ether_addr(char *addr) { diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c index 838240f151f..10b35b838ba 100644 --- a/arch/blackfin/mach-bf537/boards/pnav10.c +++ b/arch/blackfin/mach-bf537/boards/pnav10.c @@ -92,6 +92,14 @@ static struct platform_device rtc_device = { #endif #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { { .name = "smc91x-regs", @@ -110,6 +118,9 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, }; #endif @@ -282,13 +293,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = { }; #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) -static struct bfin5xx_spi_chip ad9960_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) static struct bfin5xx_spi_chip mmc_spi_chip_info = { .enable_dma = 0, @@ -348,22 +352,13 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) \ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) { - .modalias = "ad1836-spi", + .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, .controller_data = &ad1836_spi_chip_info, }, #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) - { - .modalias = "ad9960-spi", - .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 1, - .controller_data = &ad9960_spi_chip_info, - }, -#endif #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) { .modalias = "mmc_spi", diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index bd656907b8c..9db6b40743e 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -171,6 +171,14 @@ static struct platform_device rtc_device = { #endif #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { { .name = "smc91x-regs", @@ -189,6 +197,9 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, }; #endif @@ -196,10 +207,15 @@ static struct platform_device smc91x_device = { static struct resource dm9000_resources[] = { [0] = { .start = 0x203FB800, - .end = 0x203FB800 + 8, + .end = 0x203FB800 + 1, .flags = IORESOURCE_MEM, }, [1] = { + .start = 0x203FB804, + .end = 0x203FB804 + 1, + .flags = IORESOURCE_MEM, + }, + [2] = { .start = IRQ_PF9, .end = IRQ_PF9, .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE), @@ -516,19 +532,135 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ + || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, }; #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) -static struct bfin5xx_spi_chip ad9960_spi_chip_info = { +#if defined(CONFIG_SND_BF5XX_SOC_AD1938) \ + || defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE) +static struct bfin5xx_spi_chip ad1938_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 8, + .cs_gpio = GPIO_PF5, +}; +#endif + +#if defined(CONFIG_INPUT_EVAL_AD7147EBZ) +#include <linux/input.h> +#include <linux/input/ad714x.h> +static struct bfin5xx_spi_chip ad7147_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, }; + +static struct ad714x_slider_plat slider_plat[] = { + { + .start_stage = 0, + .end_stage = 7, + .max_coord = 128, + }, +}; + +static struct ad714x_button_plat button_plat[] = { + { + .keycode = BTN_FORWARD, + .l_mask = 0, + .h_mask = 0x600, + }, + { + .keycode = BTN_LEFT, + .l_mask = 0, + .h_mask = 0x500, + }, + { + .keycode = BTN_MIDDLE, + .l_mask = 0, + .h_mask = 0x800, + }, + { + .keycode = BTN_RIGHT, + .l_mask = 0x100, + .h_mask = 0x400, + }, + { + .keycode = BTN_BACK, + .l_mask = 0x200, + .h_mask = 0x400, + }, +}; +static struct ad714x_platform_data ad7147_platfrom_data = { + .slider_num = 1, + .button_num = 5, + .slider = slider_plat, + .button = button_plat, + .stage_cfg_reg = { + {0xFBFF, 0x1FFF, 0, 0x2626, 1600, 1600, 1600, 1600}, + {0xEFFF, 0x1FFF, 0, 0x2626, 1650, 1650, 1650, 1650}, + {0xFFFF, 0x1FFE, 0, 0x2626, 1650, 1650, 1650, 1650}, + {0xFFFF, 0x1FFB, 0, 0x2626, 1650, 1650, 1650, 1650}, + {0xFFFF, 0x1FEF, 0, 0x2626, 1650, 1650, 1650, 1650}, + {0xFFFF, 0x1FBF, 0, 0x2626, 1650, 1650, 1650, 1650}, + {0xFFFF, 0x1EFF, 0, 0x2626, 1650, 1650, 1650, 1650}, + {0xFFFF, 0x1BFF, 0, 0x2626, 1600, 1600, 1600, 1600}, + {0xFF7B, 0x3FFF, 0x506, 0x2626, 1100, 1100, 1150, 1150}, + {0xFDFE, 0x3FFF, 0x606, 0x2626, 1100, 1100, 1150, 1150}, + {0xFEBA, 0x1FFF, 0x1400, 0x2626, 1200, 1200, 1300, 1300}, + {0xFFEF, 0x1FFF, 0x0, 0x2626, 1100, 1100, 1150, 1150}, + }, + .sys_cfg_reg = {0x2B2, 0x0, 0x3233, 0x819, 0x832, 0xCFF, 0xCFF, 0x0}, +}; +#endif + +#if defined(CONFIG_INPUT_EVAL_AD7142EB) +#include <linux/input.h> +#include <linux/input/ad714x.h> +static struct ad714x_button_plat button_plat[] = { + { + .keycode = BTN_1, + .l_mask = 0, + .h_mask = 0x1, + }, + { + .keycode = BTN_2, + .l_mask = 0, + .h_mask = 0x2, + }, + { + .keycode = BTN_3, + .l_mask = 0, + .h_mask = 0x4, + }, + { + .keycode = BTN_4, + .l_mask = 0x0, + .h_mask = 0x8, + }, +}; +static struct ad714x_platform_data ad7142_platfrom_data = { + .button_num = 4, + .button = button_plat, + .stage_cfg_reg = { + /* fixme: figure out right setting for all comoponent according + * to hardware feature of EVAL-AD7142EB board */ + {0xE7FF, 0x3FFF, 0x0005, 0x2626, 0x01F4, 0x01F4, 0x028A, 0x028A}, + {0xFDBF, 0x3FFF, 0x0001, 0x2626, 0x01F4, 0x01F4, 0x028A, 0x028A}, + {0xFFFF, 0x2DFF, 0x0001, 0x2626, 0x01F4, 0x01F4, 0x028A, 0x028A}, + {0xFFFF, 0x37BF, 0x0001, 0x2626, 0x01F4, 0x01F4, 0x028A, 0x028A}, + {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320}, + {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320}, + {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320}, + {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320}, + {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320}, + {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320}, + {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320}, + {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320}, + }, + .sys_cfg_reg = {0x0B2, 0x0, 0x690, 0x664, 0x290F, 0xF, 0xF, 0x0}, +}; #endif #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) @@ -555,15 +687,7 @@ static struct mmc_spi_platform_data bfin_mmc_spi_pdata = { static struct bfin5xx_spi_chip mmc_spi_chip_info = { .enable_dma = 0, .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_PBX) -static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { - .ctl_reg = 0x4, /* send zero */ - .enable_dma = 0, - .bits_per_word = 8, - .cs_change_per_word = 1, + .pio_interrupt = 0, }; #endif @@ -743,25 +867,42 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ + || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) { - .modalias = "ad1836-spi", + .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, - .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, + .chip_select = 4,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */ .controller_data = &ad1836_spi_chip_info, + .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) + +#if defined(CONFIG_SND_BF5XX_SOC_AD1938) || defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE) { - .modalias = "ad9960-spi", - .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ + .modalias = "ad1938", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, - .chip_select = 1, - .controller_data = &ad9960_spi_chip_info, + .chip_select = 0,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */ + .controller_data = &ad1938_spi_chip_info, + .mode = SPI_MODE_3, }, #endif + +#if defined(CONFIG_INPUT_EVAL_AD7147EBZ) + { + .modalias = "ad714x_captouch", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .irq = IRQ_PF4, + .bus_num = 0, + .chip_select = 5, + .mode = SPI_MODE_3, + .platform_data = &ad7147_platfrom_data, + .controller_data = &ad7147_spi_chip_info, + }, +#endif + #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) { .modalias = "mmc_spi", @@ -773,24 +914,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_PBX) - { - .modalias = "fxs-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J11_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "fxo-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J19_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", @@ -864,6 +987,11 @@ static struct resource bfin_spi0_resource[] = { [1] = { .start = CH_SPI, .end = CH_SPI, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = IRQ_SPI, + .end = IRQ_SPI, .flags = IORESOURCE_IRQ, }, }; @@ -1089,7 +1217,7 @@ static struct platform_device i2c_bfin_twi_device = { #if defined(CONFIG_KEYBOARD_ADP5588) || defined(CONFIG_KEYBOARD_ADP5588_MODULE) #include <linux/input.h> -#include <linux/i2c/adp5588_keys.h> +#include <linux/i2c/adp5588.h> static const unsigned short adp5588_keymap[ADP5588_KEYMAPSIZE] = { [0] = KEY_GRAVE, [1] = KEY_1, @@ -1309,11 +1437,20 @@ static struct adp5520_platform_data adp5520_pdev_data = { #endif +#if defined(CONFIG_GPIO_ADP5588) || defined(CONFIG_GPIO_ADP5588_MODULE) +#include <linux/i2c/adp5588.h> +static struct adp5588_gpio_platfrom_data adp5588_gpio_data = { + .gpio_start = 50, + .pullup_dis_mask = 0, +}; +#endif + static struct i2c_board_info __initdata bfin_i2c_board_info[] = { -#if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE) +#if defined(CONFIG_INPUT_EVAL_AD7142EB) { - I2C_BOARD_INFO("ad7142_joystick", 0x2C), + I2C_BOARD_INFO("ad7142_captouch", 0x2C), .irq = IRQ_PG5, + .platform_data = (void *)&ad7142_platfrom_data, }, #endif #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) @@ -1321,7 +1458,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { I2C_BOARD_INFO("pcf8574_lcd", 0x22), }, #endif -#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE) +#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE) { I2C_BOARD_INFO("pcf8574_keypad", 0x27), .irq = IRQ_PG6, @@ -1355,6 +1492,12 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { .platform_data = (void *)&adxl34x_info, }, #endif +#if defined(CONFIG_GPIO_ADP5588) || defined(CONFIG_GPIO_ADP5588_MODULE) + { + I2C_BOARD_INFO("adp5588-gpio", 0x34), + .platform_data = (void *)&adp5588_gpio_data, + }, +#endif }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) @@ -1456,6 +1599,13 @@ static struct platform_device bfin_dpmc = { }, }; +#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) +static struct platform_device bfin_tdm = { + .name = "bfin-tdm", + /* TODO: add platform data here */ +}; +#endif + static struct platform_device *stamp_devices[] __initdata = { &bfin_dpmc, @@ -1561,6 +1711,10 @@ static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) &stamp_flash_device, #endif + +#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) + &bfin_tdm, +#endif }; static int __init stamp_init(void) @@ -1572,11 +1726,6 @@ static int __init stamp_init(void) platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); -#if (defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)) \ - && defined(PATA_INT) - irq_desc[PATA_INT].status |= IRQ_NOAUTOEN; -#endif - return 0; } diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c index e523e6e610d..61353f7bcb9 100644 --- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c +++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c @@ -45,6 +45,7 @@ #include <asm/bfin5xx_spi.h> #include <asm/portmux.h> #include <asm/dpmc.h> +#include <linux/spi/mmc_spi.h> /* * Name the Board for the /proc/cpuinfo @@ -101,13 +102,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = { }; #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) -static struct bfin5xx_spi_chip ad9960_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) static struct bfin5xx_spi_chip mmc_spi_chip_info = { .enable_dma = 0, @@ -142,7 +136,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) { - .modalias = "ad1836-spi", + .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, @@ -150,22 +144,12 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) - { - .modalias = "ad9960-spi", - .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 1, - .controller_data = &ad9960_spi_chip_info, - }, -#endif - #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) { .modalias = "mmc_spi", .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, - .chip_select = 5, + .chip_select = 1, .controller_data = &mmc_spi_chip_info, .mode = SPI_MODE_3, }, @@ -223,6 +207,14 @@ static struct platform_device hitachi_fb_device = { #endif #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { { .start = 0x20200300, @@ -240,6 +232,9 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, }; #endif @@ -285,12 +280,12 @@ static struct platform_device isp1362_hcd_device = { #if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) static struct resource net2272_bfin_resources[] = { { - .start = 0x20200000, - .end = 0x20200000 + 0x100, + .start = 0x20300000, + .end = 0x20300000 + 0x100, .flags = IORESOURCE_MEM, }, { - .start = IRQ_PH14, - .end = IRQ_PH14, + .start = IRQ_PG13, + .end = IRQ_PG13, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, }, }; @@ -324,7 +319,7 @@ static struct mtd_partition cm_partitions[] = { .offset = 0, }, { .name = "linux kernel(nor)", - .size = 0xE0000, + .size = 0x100000, .offset = MTDPART_OFS_APPEND, }, { .name = "file system(nor)", diff --git a/arch/blackfin/mach-bf537/dma.c b/arch/blackfin/mach-bf537/dma.c index 81185051de9..d23fc0edf2b 100644 --- a/arch/blackfin/mach-bf537/dma.c +++ b/arch/blackfin/mach-bf537/dma.c @@ -96,12 +96,12 @@ int channel2irq(unsigned int channel) ret_irq = IRQ_SPI; break; - case CH_UART_RX: - ret_irq = IRQ_UART_RX; + case CH_UART0_RX: + ret_irq = IRQ_UART0_RX; break; - case CH_UART_TX: - ret_irq = IRQ_UART_TX; + case CH_UART0_TX: + ret_irq = IRQ_UART0_TX; break; case CH_MEM_STREAM0_SRC: diff --git a/arch/blackfin/mach-bf537/include/mach/anomaly.h b/arch/blackfin/mach-bf537/include/mach/anomaly.h index e66aa131f51..f091ad2d8ea 100644 --- a/arch/blackfin/mach-bf537/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf537/include/mach/anomaly.h @@ -143,7 +143,7 @@ /* Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration */ #define ANOMALY_05000371 (1) /* SSYNC Stalls Processor when Executed from Non-Cacheable Memory */ -#define ANOMALY_05000402 (__SILICON_REVISION__ >= 5) +#define ANOMALY_05000402 (__SILICON_REVISION__ == 2) /* Level-Sensitive External GPIO Wakeups May Cause Indefinite Stall */ #define ANOMALY_05000403 (1) /* Speculative Fetches Can Cause Undesired External FIFO Operations */ diff --git a/arch/blackfin/mach-bf537/include/mach/blackfin.h b/arch/blackfin/mach-bf537/include/mach/blackfin.h index f5e5015ad83..9ee8834c8f1 100644 --- a/arch/blackfin/mach-bf537/include/mach/blackfin.h +++ b/arch/blackfin/mach-bf537/include/mach/blackfin.h @@ -45,96 +45,11 @@ #if !defined(__ASSEMBLY__) #include "cdefBF534.h" -/* UART 0*/ -#define bfin_read_UART_THR() bfin_read_UART0_THR() -#define bfin_write_UART_THR(val) bfin_write_UART0_THR(val) -#define bfin_read_UART_RBR() bfin_read_UART0_RBR() -#define bfin_write_UART_RBR(val) bfin_write_UART0_RBR(val) -#define bfin_read_UART_DLL() bfin_read_UART0_DLL() -#define bfin_write_UART_DLL(val) bfin_write_UART0_DLL(val) -#define bfin_read_UART_IER() bfin_read_UART0_IER() -#define bfin_write_UART_IER(val) bfin_write_UART0_IER(val) -#define bfin_read_UART_DLH() bfin_read_UART0_DLH() -#define bfin_write_UART_DLH(val) bfin_write_UART0_DLH(val) -#define bfin_read_UART_IIR() bfin_read_UART0_IIR() -#define bfin_write_UART_IIR(val) bfin_write_UART0_IIR(val) -#define bfin_read_UART_LCR() bfin_read_UART0_LCR() -#define bfin_write_UART_LCR(val) bfin_write_UART0_LCR(val) -#define bfin_read_UART_MCR() bfin_read_UART0_MCR() -#define bfin_write_UART_MCR(val) bfin_write_UART0_MCR(val) -#define bfin_read_UART_LSR() bfin_read_UART0_LSR() -#define bfin_write_UART_LSR(val) bfin_write_UART0_LSR(val) -#define bfin_read_UART_SCR() bfin_read_UART0_SCR() -#define bfin_write_UART_SCR(val) bfin_write_UART0_SCR(val) -#define bfin_read_UART_GCTL() bfin_read_UART0_GCTL() -#define bfin_write_UART_GCTL(val) bfin_write_UART0_GCTL(val) - #if defined(CONFIG_BF537) || defined(CONFIG_BF536) #include "cdefBF537.h" #endif #endif -/* MAP used DEFINES from BF533 to BF537 - so we don't need to change them in the driver, kernel, etc. */ - -/* UART_IIR Register */ -#define STATUS(x) ((x << 1) & 0x06) -#define STATUS_P1 0x02 -#define STATUS_P0 0x01 - -/* DMA Channel */ -#define bfin_read_CH_UART_RX() bfin_read_CH_UART0_RX() -#define bfin_write_CH_UART_RX(val) bfin_write_CH_UART0_RX(val) -#define CH_UART_RX CH_UART0_RX -#define bfin_read_CH_UART_TX() bfin_read_CH_UART0_TX() -#define bfin_write_CH_UART_TX(val) bfin_write_CH_UART0_TX(val) -#define CH_UART_TX CH_UART0_TX - -/* System Interrupt Controller */ -#define bfin_read_IRQ_UART_RX() bfin_read_IRQ_UART0_RX() -#define bfin_write_IRQ_UART_RX(val) bfin_write_IRQ_UART0_RX(val) -#define IRQ_UART_RX IRQ_UART0_RX -#define bfin_read_IRQ_UART_TX() bfin_read_IRQ_UART0_TX() -#define bfin_write_IRQ_UART_TX(val) bfin_write_IRQ_UART0_TX(val) -#define IRQ_UART_TX IRQ_UART0_TX -#define bfin_read_IRQ_UART_ERROR() bfin_read_IRQ_UART0_ERROR() -#define bfin_write_IRQ_UART_ERROR(val) bfin_write_IRQ_UART0_ERROR(val) -#define IRQ_UART_ERROR IRQ_UART0_ERROR - -/* MMR Registers*/ -#define bfin_read_UART_THR() bfin_read_UART0_THR() -#define bfin_write_UART_THR(val) bfin_write_UART0_THR(val) -#define BFIN_UART_THR UART0_THR -#define bfin_read_UART_RBR() bfin_read_UART0_RBR() -#define bfin_write_UART_RBR(val) bfin_write_UART0_RBR(val) -#define BFIN_UART_RBR UART0_RBR -#define bfin_read_UART_DLL() bfin_read_UART0_DLL() -#define bfin_write_UART_DLL(val) bfin_write_UART0_DLL(val) -#define BFIN_UART_DLL UART0_DLL -#define bfin_read_UART_IER() bfin_read_UART0_IER() -#define bfin_write_UART_IER(val) bfin_write_UART0_IER(val) -#define BFIN_UART_IER UART0_IER -#define bfin_read_UART_DLH() bfin_read_UART0_DLH() -#define bfin_write_UART_DLH(val) bfin_write_UART0_DLH(val) -#define BFIN_UART_DLH UART0_DLH -#define bfin_read_UART_IIR() bfin_read_UART0_IIR() -#define bfin_write_UART_IIR(val) bfin_write_UART0_IIR(val) -#define BFIN_UART_IIR UART0_IIR -#define bfin_read_UART_LCR() bfin_read_UART0_LCR() -#define bfin_write_UART_LCR(val) bfin_write_UART0_LCR(val) -#define BFIN_UART_LCR UART0_LCR -#define bfin_read_UART_MCR() bfin_read_UART0_MCR() -#define bfin_write_UART_MCR(val) bfin_write_UART0_MCR(val) -#define BFIN_UART_MCR UART0_MCR -#define bfin_read_UART_LSR() bfin_read_UART0_LSR() -#define bfin_write_UART_LSR(val) bfin_write_UART0_LSR(val) -#define BFIN_UART_LSR UART0_LSR -#define bfin_read_UART_SCR() bfin_read_UART0_SCR() -#define bfin_write_UART_SCR(val) bfin_write_UART0_SCR(val) -#define BFIN_UART_SCR UART0_SCR -#define bfin_read_UART_GCTL() bfin_read_UART0_GCTL() -#define bfin_write_UART_GCTL(val) bfin_write_UART0_GCTL(val) -#define BFIN_UART_GCTL UART0_GCTL - #define BFIN_UART_NR_PORTS 2 #define OFFSET_THR 0x00 /* Transmit Holding register */ @@ -150,11 +65,6 @@ #define OFFSET_SCR 0x1C /* SCR Scratch Register */ #define OFFSET_GCTL 0x24 /* Global Control Register */ -/* DPMC*/ -#define bfin_read_STOPCK_OFF() bfin_read_STOPCK() -#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val) -#define STOPCK_OFF STOPCK - /* PLL_DIV Masks */ #define CCLK_DIV1 CSEL_DIV1 /* CCLK = VCO / 1 */ #define CCLK_DIV2 CSEL_DIV2 /* CCLK = VCO / 2 */ diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c index 57695b4c3c0..f2ac3b0ebf2 100644 --- a/arch/blackfin/mach-bf538/boards/ezkit.c +++ b/arch/blackfin/mach-bf538/boards/ezkit.c @@ -31,6 +31,7 @@ #include <linux/device.h> #include <linux/platform_device.h> #include <linux/mtd/mtd.h> +#include <linux/mtd/physmap.h> #include <linux/mtd/partitions.h> #include <linux/spi/spi.h> #include <linux/spi/flash.h> @@ -177,6 +178,14 @@ static struct platform_device bfin_sir2_device = { * Driver needs to know address, irq and flag pin. */ #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { { .name = "smc91x-regs", @@ -194,6 +203,9 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, }; #endif @@ -390,6 +402,11 @@ static struct resource bfin_spi2_resource[] = { [1] = { .start = CH_SPI2, .end = CH_SPI2, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = IRQ_SPI2, + .end = IRQ_SPI2, .flags = IORESOURCE_IRQ, } }; @@ -550,6 +567,50 @@ static struct platform_device bfin_dpmc = { }, }; +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition ezkit_partitions[] = { + { + .name = "bootloader(nor)", + .size = 0x40000, + .offset = 0, + }, { + .name = "linux kernel(nor)", + .size = 0x180000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "file system(nor)", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct physmap_flash_data ezkit_flash_data = { + .width = 2, + .parts = ezkit_partitions, + .nr_parts = ARRAY_SIZE(ezkit_partitions), +}; + +static struct resource ezkit_flash_resource = { + .start = 0x20000000, +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + .end = 0x202fffff, +#else + .end = 0x203fffff, +#endif + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ezkit_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &ezkit_flash_data, + }, + .num_resources = 1, + .resource = &ezkit_flash_resource, +}; +#endif + static struct platform_device *cm_bf538_devices[] __initdata = { &bfin_dpmc, @@ -598,6 +659,10 @@ static struct platform_device *cm_bf538_devices[] __initdata = { #endif &bfin_gpios_device, + +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) + &ezkit_flash_device, +#endif }; static int __init ezkit_init(void) diff --git a/arch/blackfin/mach-bf538/include/mach/anomaly.h b/arch/blackfin/mach-bf538/include/mach/anomaly.h index 451cf8a82a4..26b76083e14 100644 --- a/arch/blackfin/mach-bf538/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf538/include/mach/anomaly.h @@ -113,7 +113,7 @@ /* GPIO Pins PC1 and PC4 Can Function as Normal Outputs */ #define ANOMALY_05000375 (__SILICON_REVISION__ < 4) /* SSYNC Stalls Processor when Executed from Non-Cacheable Memory */ -#define ANOMALY_05000402 (__SILICON_REVISION__ < 4) +#define ANOMALY_05000402 (__SILICON_REVISION__ == 3) /* Level-Sensitive External GPIO Wakeups May Cause Indefinite Stall */ #define ANOMALY_05000403 (1) /* Speculative Fetches Can Cause Undesired External FIFO Operations */ diff --git a/arch/blackfin/mach-bf538/include/mach/blackfin.h b/arch/blackfin/mach-bf538/include/mach/blackfin.h index 9496196ac16..5ecee169095 100644 --- a/arch/blackfin/mach-bf538/include/mach/blackfin.h +++ b/arch/blackfin/mach-bf538/include/mach/blackfin.h @@ -47,11 +47,6 @@ #endif #endif -/* UART_IIR Register */ -#define STATUS(x) ((x << 1) & 0x06) -#define STATUS_P1 0x02 -#define STATUS_P0 0x01 - #define BFIN_UART_NR_PORTS 3 #define OFFSET_THR 0x00 /* Transmit Holding register */ @@ -67,11 +62,6 @@ #define OFFSET_SCR 0x1C /* SCR Scratch Register */ #define OFFSET_GCTL 0x24 /* Global Control Register */ -/* DPMC*/ -#define bfin_read_STOPCK_OFF() bfin_read_STOPCK() -#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val) -#define STOPCK_OFF STOPCK - /* PLL_DIV Masks */ #define CCLK_DIV1 CSEL_DIV1 /* CCLK = VCO / 1 */ #define CCLK_DIV2 CSEL_DIV2 /* CCLK = VCO / 2 */ diff --git a/arch/blackfin/mach-bf538/include/mach/cdefBF538.h b/arch/blackfin/mach-bf538/include/mach/cdefBF538.h index 99ca3f4305e..1de67515dc9 100644 --- a/arch/blackfin/mach-bf538/include/mach/cdefBF538.h +++ b/arch/blackfin/mach-bf538/include/mach/cdefBF538.h @@ -1310,6 +1310,7 @@ #define bfin_write_PPI_CONTROL(val) bfin_write16(PPI_CONTROL, val) #define bfin_read_PPI_STATUS() bfin_read16(PPI_STATUS) #define bfin_write_PPI_STATUS(val) bfin_write16(PPI_STATUS, val) +#define bfin_clear_PPI_STATUS() bfin_read_PPI_STATUS() #define bfin_read_PPI_DELAY() bfin_read16(PPI_DELAY) #define bfin_write_PPI_DELAY(val) bfin_write16(PPI_DELAY, val) #define bfin_read_PPI_COUNT() bfin_read16(PPI_COUNT) diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c index f5a3c30a41b..e565aae11d7 100644 --- a/arch/blackfin/mach-bf548/boards/cm_bf548.c +++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c @@ -291,6 +291,8 @@ static struct platform_device bfin_sir3_device = { #endif #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) +#include <linux/smsc911x.h> + static struct resource smsc911x_resources[] = { { .name = "smsc911x-memory", @@ -304,11 +306,22 @@ static struct resource smsc911x_resources[] = { .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, }, }; + +static struct smsc911x_platform_config smsc911x_config = { + .flags = SMSC911X_USE_16BIT, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + static struct platform_device smsc911x_device = { .name = "smsc911x", .id = 0, .num_resources = ARRAY_SIZE(smsc911x_resources), .resource = smsc911x_resources, + .dev = { + .platform_data = &smsc911x_config, + }, }; #endif @@ -473,7 +486,7 @@ static struct mtd_partition para_partitions[] = { .offset = 0, }, { .name = "linux kernel(nor)", - .size = 0x400000, + .size = 0x100000, .offset = MTDPART_OFS_APPEND, }, { .name = "file system(nor)", @@ -642,7 +655,7 @@ static struct resource bfin_spi1_resource[] = { /* SPI controller data */ static struct bfin5xx_spi_master bf54x_spi_master_info0 = { - .num_chipselect = 8, + .num_chipselect = 3, .enable_dma = 1, /* master has the ability to do dma transfer */ .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, }; @@ -658,7 +671,7 @@ static struct platform_device bf54x_spi_master0 = { }; static struct bfin5xx_spi_master bf54x_spi_master_info1 = { - .num_chipselect = 8, + .num_chipselect = 3, .enable_dma = 1, /* master has the ability to do dma transfer */ .pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0}, }; diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index dc0dd9b2bce..c66f3801274 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -99,8 +99,8 @@ static struct platform_device bfin_isp1760_device = { #include <mach/bf54x-lq043.h> static struct bfin_bf54xfb_mach_info bf54x_lq043_data = { - .width = 480, - .height = 272, + .width = 95, + .height = 54, .xres = {480, 480, 480}, .yres = {272, 272, 272}, .bpp = {24, 24, 24}, @@ -702,7 +702,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) \ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) { - .modalias = "ad1836-spi", + .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 1, .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, @@ -783,7 +783,7 @@ static struct resource bfin_spi1_resource[] = { /* SPI controller data */ static struct bfin5xx_spi_master bf54x_spi_master_info0 = { - .num_chipselect = 8, + .num_chipselect = 3, .enable_dma = 1, /* master has the ability to do dma transfer */ .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, }; @@ -799,7 +799,7 @@ static struct platform_device bf54x_spi_master0 = { }; static struct bfin5xx_spi_master bf54x_spi_master_info1 = { - .num_chipselect = 8, + .num_chipselect = 3, .enable_dma = 1, /* master has the ability to do dma transfer */ .pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0}, }; @@ -869,7 +869,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info1[] = { I2C_BOARD_INFO("pcf8574_lcd", 0x22), }, #endif -#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE) +#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE) { I2C_BOARD_INFO("pcf8574_keypad", 0x27), .irq = 212, diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c index 535980652bf..d9239bc05dd 100644 --- a/arch/blackfin/mach-bf548/dma.c +++ b/arch/blackfin/mach-bf548/dma.c @@ -91,16 +91,16 @@ int channel2irq(unsigned int channel) ret_irq = IRQ_SPI1; break; case CH_UART0_RX: - ret_irq = IRQ_UART_RX; + ret_irq = IRQ_UART0_RX; break; case CH_UART0_TX: - ret_irq = IRQ_UART_TX; + ret_irq = IRQ_UART0_TX; break; case CH_UART1_RX: - ret_irq = IRQ_UART_RX; + ret_irq = IRQ_UART1_RX; break; case CH_UART1_TX: - ret_irq = IRQ_UART_TX; + ret_irq = IRQ_UART1_TX; break; case CH_EPPI0: ret_irq = IRQ_EPPI0; diff --git a/arch/blackfin/mach-bf548/include/mach/anomaly.h b/arch/blackfin/mach-bf548/include/mach/anomaly.h index cd040fe0bc5..52b116ae522 100644 --- a/arch/blackfin/mach-bf548/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf548/include/mach/anomaly.h @@ -7,7 +7,7 @@ */ /* This file should be up to date with: - * - Revision H, 01/16/2009; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List + * - Revision I, 07/23/2009; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List */ #ifndef _MACH_ANOMALY_H_ @@ -162,6 +162,8 @@ #define ANOMALY_05000430 (__SILICON_REVISION__ >= 2) /* Incorrect Use of Stack in Lockbox Firmware During Authentication */ #define ANOMALY_05000431 (__SILICON_REVISION__ < 3) +/* SW Breakpoints Ignored Upon Return From Lockbox Authentication */ +#define ANOMALY_05000434 (1) /* OTP Write Accesses Not Supported */ #define ANOMALY_05000442 (__SILICON_REVISION__ < 1) /* IFLUSH Instruction at End of Hardware Loop Causes Infinite Stall */ @@ -176,12 +178,26 @@ #define ANOMALY_05000449 (__SILICON_REVISION__ == 1) /* USB DMA Mode 1 Short Packet Data Corruption */ #define ANOMALY_05000450 (1) +/* Incorrect Default Hysteresis Setting for RESET, NMI, and BMODE Signals */ +#define ANOMALY_05000452 (__SILICON_REVISION__ < 1) /* USB Receive Interrupt Is Not Generated in DMA Mode 1 */ -#define ANOMALY_05000456 (__SILICON_REVISION__ < 3) +#define ANOMALY_05000456 (1) +/* Host DMA Port Responds to Certain Bus Activity Without HOST_CE Assertion */ +#define ANOMALY_05000457 (1) +/* USB DMA Mode 1 Failure When Multiple USB DMA Channels Are Concurrently Enabled */ +#define ANOMALY_05000460 (1) /* False Hardware Error when RETI Points to Invalid Memory */ #define ANOMALY_05000461 (1) +/* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */ +#define ANOMALY_05000462 (1) +/* USB DMA RX Data Corruption */ +#define ANOMALY_05000463 (1) +/* USB TX DMA Hang */ +#define ANOMALY_05000464 (1) /* USB Rx DMA hang */ #define ANOMALY_05000465 (1) +/* TxPktRdy Bit Not Set for Transmit Endpoint When Core and DMA Access USB Endpoint FIFOs Simultaneously */ +#define ANOMALY_05000466 (1) /* Possible RX data corruption when control & data EP FIFOs are accessed via the core */ #define ANOMALY_05000467 (1) @@ -230,6 +246,7 @@ #define ANOMALY_05000364 (0) #define ANOMALY_05000380 (0) #define ANOMALY_05000400 (0) +#define ANOMALY_05000402 (0) #define ANOMALY_05000412 (0) #define ANOMALY_05000432 (0) #define ANOMALY_05000435 (0) diff --git a/arch/blackfin/mach-bf548/include/mach/blackfin.h b/arch/blackfin/mach-bf548/include/mach/blackfin.h index 6b97396d817..318667b2f03 100644 --- a/arch/blackfin/mach-bf548/include/mach/blackfin.h +++ b/arch/blackfin/mach-bf548/include/mach/blackfin.h @@ -72,97 +72,8 @@ #include "cdefBF549.h" #endif -/* UART 1*/ -#define bfin_read_UART_THR() bfin_read_UART1_THR() -#define bfin_write_UART_THR(val) bfin_write_UART1_THR(val) -#define bfin_read_UART_RBR() bfin_read_UART1_RBR() -#define bfin_write_UART_RBR(val) bfin_write_UART1_RBR(val) -#define bfin_read_UART_DLL() bfin_read_UART1_DLL() -#define bfin_write_UART_DLL(val) bfin_write_UART1_DLL(val) -#define bfin_read_UART_IER() bfin_read_UART1_IER() -#define bfin_write_UART_IER(val) bfin_write_UART1_IER(val) -#define bfin_read_UART_DLH() bfin_read_UART1_DLH() -#define bfin_write_UART_DLH(val) bfin_write_UART1_DLH(val) -#define bfin_read_UART_IIR() bfin_read_UART1_IIR() -#define bfin_write_UART_IIR(val) bfin_write_UART1_IIR(val) -#define bfin_read_UART_LCR() bfin_read_UART1_LCR() -#define bfin_write_UART_LCR(val) bfin_write_UART1_LCR(val) -#define bfin_read_UART_MCR() bfin_read_UART1_MCR() -#define bfin_write_UART_MCR(val) bfin_write_UART1_MCR(val) -#define bfin_read_UART_LSR() bfin_read_UART1_LSR() -#define bfin_write_UART_LSR(val) bfin_write_UART1_LSR(val) -#define bfin_read_UART_SCR() bfin_read_UART1_SCR() -#define bfin_write_UART_SCR(val) bfin_write_UART1_SCR(val) -#define bfin_read_UART_GCTL() bfin_read_UART1_GCTL() -#define bfin_write_UART_GCTL(val) bfin_write_UART1_GCTL(val) - #endif -/* MAP used DEFINES from BF533 to BF54x - so we don't need to change - * them in the driver, kernel, etc. */ - -/* UART_IIR Register */ -#define STATUS(x) ((x << 1) & 0x06) -#define STATUS_P1 0x02 -#define STATUS_P0 0x01 - -/* UART 0*/ - -/* DMA Channel */ -#define bfin_read_CH_UART_RX() bfin_read_CH_UART1_RX() -#define bfin_write_CH_UART_RX(val) bfin_write_CH_UART1_RX(val) -#define bfin_read_CH_UART_TX() bfin_read_CH_UART1_TX() -#define bfin_write_CH_UART_TX(val) bfin_write_CH_UART1_TX(val) -#define CH_UART_RX CH_UART1_RX -#define CH_UART_TX CH_UART1_TX - -/* System Interrupt Controller */ -#define bfin_read_IRQ_UART_RX() bfin_read_IRQ_UART1_RX() -#define bfin_write_IRQ_UART_RX(val) bfin_write_IRQ_UART1_RX(val) -#define bfin_read_IRQ_UART_TX() bfin_read_IRQ_UART1_TX() -#define bfin_write_IRQ_UART_TX(val) bfin_write_IRQ_UART1_TX(val) -#define bfin_read_IRQ_UART_ERROR() bfin_read_IRQ_UART1_ERROR() -#define bfin_write_IRQ_UART_ERROR(val) bfin_write_IRQ_UART1_ERROR(val) -#define IRQ_UART_RX IRQ_UART1_RX -#define IRQ_UART_TX IRQ_UART1_TX -#define IRQ_UART_ERROR IRQ_UART1_ERROR - -/* MMR Registers*/ -#define bfin_read_UART_THR() bfin_read_UART1_THR() -#define bfin_write_UART_THR(val) bfin_write_UART1_THR(val) -#define bfin_read_UART_RBR() bfin_read_UART1_RBR() -#define bfin_write_UART_RBR(val) bfin_write_UART1_RBR(val) -#define bfin_read_UART_DLL() bfin_read_UART1_DLL() -#define bfin_write_UART_DLL(val) bfin_write_UART1_DLL(val) -#define bfin_read_UART_IER() bfin_read_UART1_IER() -#define bfin_write_UART_IER(val) bfin_write_UART1_IER(val) -#define bfin_read_UART_DLH() bfin_read_UART1_DLH() -#define bfin_write_UART_DLH(val) bfin_write_UART1_DLH(val) -#define bfin_read_UART_IIR() bfin_read_UART1_IIR() -#define bfin_write_UART_IIR(val) bfin_write_UART1_IIR(val) -#define bfin_read_UART_LCR() bfin_read_UART1_LCR() -#define bfin_write_UART_LCR(val) bfin_write_UART1_LCR(val) -#define bfin_read_UART_MCR() bfin_read_UART1_MCR() -#define bfin_write_UART_MCR(val) bfin_write_UART1_MCR(val) -#define bfin_read_UART_LSR() bfin_read_UART1_LSR() -#define bfin_write_UART_LSR(val) bfin_write_UART1_LSR(val) -#define bfin_read_UART_SCR() bfin_read_UART1_SCR() -#define bfin_write_UART_SCR(val) bfin_write_UART1_SCR(val) -#define bfin_read_UART_GCTL() bfin_read_UART1_GCTL() -#define bfin_write_UART_GCTL(val) bfin_write_UART1_GCTL(val) - -#define BFIN_UART_THR UART1_THR -#define BFIN_UART_RBR UART1_RBR -#define BFIN_UART_DLL UART1_DLL -#define BFIN_UART_IER UART1_IER -#define BFIN_UART_DLH UART1_DLH -#define BFIN_UART_IIR UART1_IIR -#define BFIN_UART_LCR UART1_LCR -#define BFIN_UART_MCR UART1_MCR -#define BFIN_UART_LSR UART1_LSR -#define BFIN_UART_SCR UART1_SCR -#define BFIN_UART_GCTL UART1_GCTL - #define BFIN_UART_NR_PORTS 4 #define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */ diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c index 0c9d72c5f5b..6577ecfcf11 100644 --- a/arch/blackfin/mach-bf561/boards/cm_bf561.c +++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c @@ -42,6 +42,7 @@ #include <asm/bfin5xx_spi.h> #include <asm/portmux.h> #include <asm/dpmc.h> +#include <linux/mtd/physmap.h> /* * Name the Board for the /proc/cpuinfo @@ -98,13 +99,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = { }; #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) -static struct bfin5xx_spi_chip ad9960_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) static struct bfin5xx_spi_chip mmc_spi_chip_info = { .enable_dma = 0, @@ -139,28 +133,19 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) { - .modalias = "ad1836-spi", + .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, .controller_data = &ad1836_spi_chip_info, }, #endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) - { - .modalias = "ad9960-spi", - .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 1, - .controller_data = &ad9960_spi_chip_info, - }, -#endif #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) { .modalias = "mmc_spi", - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, - .chip_select = 5, + .chip_select = 1, .controller_data = &mmc_spi_chip_info, .mode = SPI_MODE_3, }, @@ -213,6 +198,13 @@ static struct platform_device hitachi_fb_device = { #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_32BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; static struct resource smc91x_resources[] = { { @@ -231,6 +223,65 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, +}; +#endif + +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) +#include <linux/smsc911x.h> + +static struct resource smsc911x_resources[] = { + { + .name = "smsc911x-memory", + .start = 0x24008000, + .end = 0x24008000 + 0xFF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PF43, + .end = IRQ_PF43, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, +}; + +static struct smsc911x_platform_config smsc911x_config = { + .flags = SMSC911X_USE_16BIT, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct platform_device smsc911x_device = { + .name = "smsc911x", + .id = 0, + .num_resources = ARRAY_SIZE(smsc911x_resources), + .resource = smsc911x_resources, + .dev = { + .platform_data = &smsc911x_config, + }, +}; +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) +static struct resource net2272_bfin_resources[] = { + { + .start = 0x24000000, + .end = 0x24000000 + 0x100, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PF45, + .end = IRQ_PF45, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device net2272_bfin_device = { + .name = "net2272", + .id = -1, + .num_resources = ARRAY_SIZE(net2272_bfin_resources), + .resource = net2272_bfin_resources, }; #endif @@ -369,6 +420,46 @@ static struct platform_device bfin_pata_device = { }; #endif +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition para_partitions[] = { + { + .name = "bootloader(nor)", + .size = 0x40000, + .offset = 0, + }, { + .name = "linux kernel(nor)", + .size = 0x100000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "file system(nor)", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct physmap_flash_data para_flash_data = { + .width = 2, + .parts = para_partitions, + .nr_parts = ARRAY_SIZE(para_partitions), +}; + +static struct resource para_flash_resource = { + .start = 0x20000000, + .end = 0x207fffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device para_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = ¶_flash_data, + }, + .num_resources = 1, + .resource = ¶_flash_resource, +}; +#endif + static const unsigned int cclk_vlev_datasheet[] = { VRPAIR(VLEV_085, 250000000), @@ -422,6 +513,14 @@ static struct platform_device *cm_bf561_devices[] __initdata = { &smc91x_device, #endif +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) + &smsc911x_device, +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) + &net2272_bfin_device, +#endif + #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) &bfin_spi0_device, #endif @@ -430,6 +529,10 @@ static struct platform_device *cm_bf561_devices[] __initdata = { &bfin_pata_device, #endif +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) + ¶_flash_device, +#endif + &bfin_gpios_device, }; diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index 4df904f9e90..caed96bb957 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c @@ -147,6 +147,14 @@ static struct platform_device net2272_bfin_device = { * Driver needs to know address, irq and flag pin. */ #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +#include <linux/smc91x.h> + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_32BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { { .name = "smc91x-regs", @@ -166,6 +174,9 @@ static struct platform_device smc91x_device = { .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &smc91x_info, + }, }; #endif @@ -334,7 +345,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) \ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) { - .modalias = "ad1836-spi", + .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, diff --git a/arch/blackfin/mach-bf561/include/mach/anomaly.h b/arch/blackfin/mach-bf561/include/mach/anomaly.h index a5312b2d267..70da495c966 100644 --- a/arch/blackfin/mach-bf561/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf561/include/mach/anomaly.h @@ -262,6 +262,8 @@ #define ANOMALY_05000366 (1) /* Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration */ #define ANOMALY_05000371 (1) +/* SSYNC Stalls Processor when Executed from Non-Cacheable Memory */ +#define ANOMALY_05000402 (__SILICON_REVISION__ == 4) /* Level-Sensitive External GPIO Wakeups May Cause Indefinite Stall */ #define ANOMALY_05000403 (1) /* TESTSET Instruction Causes Data Corruption with Writeback Data Cache Enabled */ diff --git a/arch/blackfin/mach-bf561/secondary.S b/arch/blackfin/mach-bf561/secondary.S index 35280f06b7b..f72a6af20c4 100644 --- a/arch/blackfin/mach-bf561/secondary.S +++ b/arch/blackfin/mach-bf561/secondary.S @@ -85,16 +85,10 @@ ENTRY(_coreb_trampoline_start) R0 = ~ENICPLB; R0 = R0 & R1; - /* Anomaly 05000125 */ -#ifdef ANOMALY_05000125 - CLI R2; - SSYNC; -#endif + /* Disabling of CPLBs should be proceeded by a CSYNC */ + CSYNC; [p0] = R0; SSYNC; -#ifdef ANOMALY_05000125 - STI R2; -#endif /* Turn off the dcache */ p0.l = LO(DMEM_CONTROL); @@ -103,16 +97,10 @@ ENTRY(_coreb_trampoline_start) R0 = ~ENDCPLB; R0 = R0 & R1; - /* Anomaly 05000125 */ -#ifdef ANOMALY_05000125 - CLI R2; - SSYNC; -#endif + /* Disabling of CPLBs should be proceeded by a CSYNC */ + CSYNC; [p0] = R0; SSYNC; -#ifdef ANOMALY_05000125 - STI R2; -#endif /* in case of double faults, save a few things */ p0.l = _init_retx_coreb; @@ -126,22 +114,22 @@ ENTRY(_coreb_trampoline_start) * below */ GET_PDA(p0, r0); - r7 = [p0 + PDA_RETX]; + r7 = [p0 + PDA_DF_RETX]; p1.l = _init_saved_retx_coreb; p1.h = _init_saved_retx_coreb; [p1] = r7; - r7 = [p0 + PDA_DCPLB]; + r7 = [p0 + PDA_DF_DCPLB]; p1.l = _init_saved_dcplb_fault_addr_coreb; p1.h = _init_saved_dcplb_fault_addr_coreb; [p1] = r7; - r7 = [p0 + PDA_ICPLB]; + r7 = [p0 + PDA_DF_ICPLB]; p1.l = _init_saved_icplb_fault_addr_coreb; p1.h = _init_saved_icplb_fault_addr_coreb; [p1] = r7; - r7 = [p0 + PDA_SEQSTAT]; + r7 = [p0 + PDA_DF_SEQSTAT]; p1.l = _init_saved_seqstat_coreb; p1.h = _init_saved_seqstat_coreb; [p1] = r7; diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile index dd8b2dc97f5..814cb483853 100644 --- a/arch/blackfin/mach-common/Makefile +++ b/arch/blackfin/mach-common/Makefile @@ -6,7 +6,6 @@ obj-y := \ cache.o cache-c.o entry.o head.o \ interrupt.o arch_checks.o ints-priority.o -obj-$(CONFIG_BFIN_ICACHE_LOCK) += lock.o obj-$(CONFIG_PM) += pm.o dpmc_modes.o obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o diff --git a/arch/blackfin/mach-common/cache-c.c b/arch/blackfin/mach-common/cache-c.c index b59ce3cb380..4ebbd78db3a 100644 --- a/arch/blackfin/mach-common/cache-c.c +++ b/arch/blackfin/mach-common/cache-c.c @@ -1,14 +1,16 @@ /* * Blackfin cache control code (simpler control-style functions) * - * Copyright 2004-2008 Analog Devices Inc. + * Copyright 2004-2009 Analog Devices Inc. * * Enter bugs at http://blackfin.uclinux.org/ * * Licensed under the GPL-2 or later. */ +#include <linux/init.h> #include <asm/blackfin.h> +#include <asm/cplbinit.h> /* Invalidate the Entire Data cache by * clearing DMC[1:0] bits @@ -34,3 +36,43 @@ void blackfin_invalidate_entire_icache(void) SSYNC(); } +#if defined(CONFIG_BFIN_ICACHE) || defined(CONFIG_BFIN_DCACHE) + +static void +bfin_cache_init(struct cplb_entry *cplb_tbl, unsigned long cplb_addr, + unsigned long cplb_data, unsigned long mem_control, + unsigned long mem_mask) +{ + int i; + + for (i = 0; i < MAX_CPLBS; i++) { + bfin_write32(cplb_addr + i * 4, cplb_tbl[i].addr); + bfin_write32(cplb_data + i * 4, cplb_tbl[i].data); + } + + _enable_cplb(mem_control, mem_mask); +} + +#ifdef CONFIG_BFIN_ICACHE +void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl) +{ + bfin_cache_init(icplb_tbl, ICPLB_ADDR0, ICPLB_DATA0, IMEM_CONTROL, + (IMC | ENICPLB)); +} +#endif + +#ifdef CONFIG_BFIN_DCACHE +void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl) +{ + /* + * Anomaly notes: + * 05000287 - We implement workaround #2 - Change the DMEM_CONTROL + * register, so that the port preferences for DAG0 and DAG1 are set + * to port B + */ + bfin_cache_init(dcplb_tbl, DCPLB_ADDR0, DCPLB_DATA0, DMEM_CONTROL, + (DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0))); +} +#endif + +#endif diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index fb1795d5be2..01af24cde36 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -301,27 +301,31 @@ ENTRY(_ex_replaceable) nop; ENTRY(_ex_trap_c) + /* The only thing that has been saved in this context is + * (R7:6,P5:4), ASTAT & SP - don't use anything else + */ + + GET_PDA(p5, r6); + /* Make sure we are not in a double fault */ p4.l = lo(IPEND); p4.h = hi(IPEND); r7 = [p4]; CC = BITTST (r7, 5); if CC jump _double_fault; + [p5 + PDA_EXIPEND] = r7; /* Call C code (trap_c) to handle the exception, which most * likely involves sending a signal to the current process. * To avoid double faults, lower our priority to IRQ5 first. */ - P5.h = _exception_to_level5; - P5.l = _exception_to_level5; + r7.h = _exception_to_level5; + r7.l = _exception_to_level5; p4.l = lo(EVT5); p4.h = hi(EVT5); - [p4] = p5; + [p4] = r7; csync; - GET_PDA(p5, r6); -#ifndef CONFIG_DEBUG_DOUBLEFAULT - /* * Save these registers, as they are only valid in exception context * (where we are now - as soon as we defer to IRQ5, they can change) @@ -341,7 +345,10 @@ ENTRY(_ex_trap_c) r6 = retx; [p5 + PDA_RETX] = r6; -#endif + + r6 = SEQSTAT; + [p5 + PDA_SEQSTAT] = r6; + /* Save the state of single stepping */ r6 = SYSCFG; [p5 + PDA_SYSCFG] = r6; @@ -349,8 +356,7 @@ ENTRY(_ex_trap_c) BITCLR(r6, SYSCFG_SSSTEP_P); SYSCFG = r6; - /* Disable all interrupts, but make sure level 5 is enabled so - * we can switch to that level. Save the old mask. */ + /* Save the current IMASK, since we change in order to jump to level 5 */ cli r6; [p5 + PDA_EXIMASK] = r6; @@ -358,9 +364,21 @@ ENTRY(_ex_trap_c) p4.h = hi(SAFE_USER_INSTRUCTION); retx = p4; + /* Disable all interrupts, but make sure level 5 is enabled so + * we can switch to that level. + */ r6 = 0x3f; sti r6; + /* In case interrupts are disabled IPEND[4] (global interrupt disable bit) + * clear it (re-enabling interrupts again) by the special sequence of pushing + * RETI onto the stack. This way we can lower ourselves to IVG5 even if the + * exception was taken after the interrupt handler was called but before it + * got a chance to enable global interrupts itself. + */ + [--sp] = reti; + sp += 4; + raise 5; jump.s _bfin_return_from_exception; ENDPROC(_ex_trap_c) @@ -379,8 +397,7 @@ ENTRY(_double_fault) R5 = [P4]; /* Control Register*/ BITCLR(R5,ENICPLB_P); - SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ - .align 8; + CSYNC; /* Disabling of CPLBs should be proceeded by a CSYNC */ [P4] = R5; SSYNC; @@ -388,8 +405,7 @@ ENTRY(_double_fault) P4.H = HI(DMEM_CONTROL); R5 = [P4]; BITCLR(R5,ENDCPLB_P); - SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ - .align 8; + CSYNC; /* Disabling of CPLBs should be proceeded by a CSYNC */ [P4] = R5; SSYNC; @@ -420,47 +436,55 @@ ENDPROC(_double_fault) ENTRY(_exception_to_level5) SAVE_ALL_SYS - GET_PDA(p4, r7); /* Fetch current PDA */ - r6 = [p4 + PDA_RETX]; + GET_PDA(p5, r7); /* Fetch current PDA */ + r6 = [p5 + PDA_RETX]; [sp + PT_PC] = r6; - r6 = [p4 + PDA_SYSCFG]; + r6 = [p5 + PDA_SYSCFG]; [sp + PT_SYSCFG] = r6; - /* Restore interrupt mask. We haven't pushed RETI, so this - * doesn't enable interrupts until we return from this handler. */ - r6 = [p4 + PDA_EXIMASK]; - sti r6; + r6 = [p5 + PDA_SEQSTAT]; /* Read back seqstat */ + [sp + PT_SEQSTAT] = r6; /* Restore the hardware error vector. */ - P5.h = _evt_ivhw; - P5.l = _evt_ivhw; + r7.h = _evt_ivhw; + r7.l = _evt_ivhw; p4.l = lo(EVT5); p4.h = hi(EVT5); - [p4] = p5; + [p4] = r7; csync; - p2.l = lo(IPEND); - p2.h = hi(IPEND); - csync; - r0 = [p2]; /* Read current IPEND */ - [sp + PT_IPEND] = r0; /* Store IPEND */ +#ifdef CONFIG_DEBUG_DOUBLEFAULT + /* Now that we have the hardware error vector programmed properly + * we can re-enable interrupts (IPEND[4]), so if the _trap_c causes + * another hardware error, we can catch it (self-nesting). + */ + [--sp] = reti; + sp += 4; +#endif + + r7 = [p5 + PDA_EXIPEND] /* Read the IPEND from the Exception state */ + [sp + PT_IPEND] = r7; /* Store IPEND onto the stack */ r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ SP += -12; call _trap_c; SP += 12; -#ifdef CONFIG_DEBUG_DOUBLEFAULT - /* Grab ILAT */ - p2.l = lo(ILAT); - p2.h = hi(ILAT); - r0 = [p2]; - r1 = 0x20; /* Did I just cause anther HW error? */ - r0 = r0 & r1; - CC = R0 == R1; - if CC JUMP _double_fault; -#endif + /* If interrupts were off during the exception (IPEND[4] = 1), turn them off + * before we return. + */ + CC = BITTST(r7, EVT_IRPTEN_P) + if !CC jump 1f; + /* this will load a random value into the reti register - but that is OK, + * since we do restore it to the correct value in the 'RESTORE_ALL_SYS' macro + */ + sp += -4; + reti = [sp++]; +1: + /* restore the interrupt mask (IMASK) */ + r6 = [p5 + PDA_EXIMASK]; + sti r6; call _ret_from_exception; RESTORE_ALL_SYS @@ -474,7 +498,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ */ EX_SCRATCH_REG = sp; GET_PDA_SAFE(sp); - sp = [sp + PDA_EXSTACK] + sp = [sp + PDA_EXSTACK]; /* Try to deal with syscalls quickly. */ [--sp] = ASTAT; [--sp] = (R7:6,P5:4); @@ -489,14 +513,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ ssync; #endif -#if ANOMALY_05000283 || ANOMALY_05000315 - cc = r7 == r7; - p5.h = HI(CHIPID); - p5.l = LO(CHIPID); - if cc jump 1f; - r7.l = W[p5]; -1: -#endif + ANOMALY_283_315_WORKAROUND(p5, r7) #ifdef CONFIG_DEBUG_DOUBLEFAULT /* @@ -510,18 +527,18 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ p4.l = lo(DCPLB_FAULT_ADDR); p4.h = hi(DCPLB_FAULT_ADDR); r7 = [p4]; - [p5 + PDA_DCPLB] = r7; + [p5 + PDA_DF_DCPLB] = r7; p4.l = lo(ICPLB_FAULT_ADDR); p4.h = hi(ICPLB_FAULT_ADDR); r7 = [p4]; - [p5 + PDA_ICPLB] = r7; + [p5 + PDA_DF_ICPLB] = r7; - r6 = retx; - [p5 + PDA_RETX] = r6; + r7 = retx; + [p5 + PDA_DF_RETX] = r7; r7 = SEQSTAT; /* reason code is in bit 5:0 */ - [p5 + PDA_SEQSTAT] = r7; + [p5 + PDA_DF_SEQSTAT] = r7; #else r7 = SEQSTAT; /* reason code is in bit 5:0 */ #endif @@ -686,8 +703,14 @@ ENTRY(_system_call) #ifdef CONFIG_IPIPE cc = BITTST(r7, TIF_IRQ_SYNC); if !cc jump .Lsyscall_no_irqsync; + /* + * Clear IPEND[4] manually to undo what resume_userspace_1 just did; + * we need this so that high priority domain interrupts may still + * preempt the current domain while the pipeline log is being played + * back. + */ [--sp] = reti; - r0 = [sp++]; + SP += 4; /* don't merge with next insn to keep the pattern obvious */ SP += -12; call ___ipipe_sync_root; SP += 12; @@ -699,7 +722,7 @@ ENTRY(_system_call) /* Reenable interrupts. */ [--sp] = reti; - r0 = [sp++]; + sp += 4; SP += -12; call _schedule; @@ -715,7 +738,7 @@ ENTRY(_system_call) .Lsyscall_do_signals: /* Reenable interrupts. */ [--sp] = reti; - r0 = [sp++]; + sp += 4; r0 = sp; SP += -12; @@ -725,10 +748,6 @@ ENTRY(_system_call) .Lsyscall_really_exit: r5 = [sp + PT_RESERVED]; rets = r5; -#ifdef CONFIG_IPIPE - [--sp] = reti; - r5 = [sp++]; -#endif /* CONFIG_IPIPE */ rts; ENDPROC(_system_call) @@ -816,13 +835,13 @@ ENDPROC(_resume) ENTRY(_ret_from_exception) #ifdef CONFIG_IPIPE - [--sp] = rets; - SP += -12; - call ___ipipe_check_root - SP += 12 - rets = [sp++]; - cc = r0 == 0; - if cc jump 4f; /* not on behalf of Linux, get out */ + p2.l = _per_cpu__ipipe_percpu_domain; + p2.h = _per_cpu__ipipe_percpu_domain; + r0.l = _ipipe_root; + r0.h = _ipipe_root; + r2 = [p2]; + cc = r0 == r2; + if !cc jump 4f; /* not on behalf of the root domain, get out */ #endif /* CONFIG_IPIPE */ p2.l = lo(IPEND); p2.h = hi(IPEND); @@ -882,14 +901,9 @@ ENDPROC(_ret_from_exception) #ifdef CONFIG_IPIPE -_sync_root_irqs: - [--sp] = reti; /* Reenable interrupts */ - r0 = [sp++]; - jump.l ___ipipe_sync_root - _resume_kernel_from_int: - r0.l = _sync_root_irqs - r0.h = _sync_root_irqs + r0.l = ___ipipe_sync_root; + r0.h = ___ipipe_sync_root; [--sp] = rets; [--sp] = ( r7:4, p5:3 ); SP += -12; @@ -953,10 +967,10 @@ ENTRY(_lower_to_irq14) #endif #ifdef CONFIG_DEBUG_HWERR - /* enable irq14 & hwerr interrupt, until we transition to _evt14_softirq */ + /* enable irq14 & hwerr interrupt, until we transition to _evt_evt14 */ r0 = (EVT_IVG14 | EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU); #else - /* Only enable irq14 interrupt, until we transition to _evt14_softirq */ + /* Only enable irq14 interrupt, until we transition to _evt_evt14 */ r0 = (EVT_IVG14 | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU); #endif sti r0; @@ -964,7 +978,7 @@ ENTRY(_lower_to_irq14) rti; ENDPROC(_lower_to_irq14) -ENTRY(_evt14_softirq) +ENTRY(_evt_evt14) #ifdef CONFIG_DEBUG_HWERR r0 = (EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU); sti r0; @@ -974,7 +988,7 @@ ENTRY(_evt14_softirq) [--sp] = RETI; SP += 4; rts; -ENDPROC(_evt14_softirq) +ENDPROC(_evt_evt14) ENTRY(_schedule_and_signal_from_int) /* To end up here, vector 15 was changed - so we have to change it @@ -1004,6 +1018,12 @@ ENTRY(_schedule_and_signal_from_int) #endif sti r0; + /* finish the userspace "atomic" functions for it */ + r1 = FIXED_CODE_END; + r2 = [sp + PT_PC]; + cc = r1 <= r2; + if cc jump .Lresume_userspace (bp); + r0 = sp; sp += -12; call _finish_atomic_sections; @@ -1107,14 +1127,7 @@ ENTRY(_early_trap) SAVE_ALL_SYS trace_buffer_stop(p0,r0); -#if ANOMALY_05000283 || ANOMALY_05000315 - cc = r5 == r5; - p4.h = HI(CHIPID); - p4.l = LO(CHIPID); - if cc jump 1f; - r5.l = W[p4]; -1: -#endif + ANOMALY_283_315_WORKAROUND(p4, r5) /* Turn caches off, to ensure we don't get double exceptions */ @@ -1123,9 +1136,7 @@ ENTRY(_early_trap) R5 = [P4]; /* Control Register*/ BITCLR(R5,ENICPLB_P); - CLI R1; - SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ - .align 8; + CSYNC; /* Disabling of CPLBs should be proceeded by a CSYNC */ [P4] = R5; SSYNC; @@ -1133,11 +1144,9 @@ ENTRY(_early_trap) P4.H = HI(DMEM_CONTROL); R5 = [P4]; BITCLR(R5,ENDCPLB_P); - SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ - .align 8; + CSYNC; /* Disabling of CPLBs should be proceeded by a CSYNC */ [P4] = R5; SSYNC; - STI R1; r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ r1 = RETX; diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S index f826f6b9f91..9c79dfea2a5 100644 --- a/arch/blackfin/mach-common/head.S +++ b/arch/blackfin/mach-common/head.S @@ -124,22 +124,22 @@ ENTRY(__start) * below */ GET_PDA(p0, r0); - r6 = [p0 + PDA_RETX]; + r6 = [p0 + PDA_DF_RETX]; p1.l = _init_saved_retx; p1.h = _init_saved_retx; [p1] = r6; - r6 = [p0 + PDA_DCPLB]; + r6 = [p0 + PDA_DF_DCPLB]; p1.l = _init_saved_dcplb_fault_addr; p1.h = _init_saved_dcplb_fault_addr; [p1] = r6; - r6 = [p0 + PDA_ICPLB]; + r6 = [p0 + PDA_DF_ICPLB]; p1.l = _init_saved_icplb_fault_addr; p1.h = _init_saved_icplb_fault_addr; [p1] = r6; - r6 = [p0 + PDA_SEQSTAT]; + r6 = [p0 + PDA_DF_SEQSTAT]; p1.l = _init_saved_seqstat; p1.h = _init_saved_seqstat; [p1] = r6; @@ -153,6 +153,8 @@ ENTRY(__start) #ifdef CONFIG_EARLY_PRINTK call _init_early_exception_vectors; + r0 = (EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU); + sti r0; #endif r0 = 0 (x); @@ -212,12 +214,21 @@ ENTRY(__start) [p0] = p1; csync; +#ifdef CONFIG_EARLY_PRINTK + r0 = (EVT_IVG15 | EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU) (z); +#else r0 = EVT_IVG15 (z); +#endif sti r0; raise 15; +#ifdef CONFIG_EARLY_PRINTK + p0.l = _early_trap; + p0.h = _early_trap; +#else p0.l = .LWAIT_HERE; p0.h = .LWAIT_HERE; +#endif reti = p0; #if ANOMALY_05000281 nop; nop; nop; diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S index 9c46680186e..82d417ef4b5 100644 --- a/arch/blackfin/mach-common/interrupt.S +++ b/arch/blackfin/mach-common/interrupt.S @@ -119,14 +119,8 @@ __common_int_entry: fp = 0; #endif -#if ANOMALY_05000283 || ANOMALY_05000315 - cc = r7 == r7; - p5.h = HI(CHIPID); - p5.l = LO(CHIPID); - if cc jump 1f; - r7.l = W[p5]; -1: -#endif + ANOMALY_283_315_WORKAROUND(p5, r7) + r1 = sp; SP += -12; #ifdef CONFIG_IPIPE @@ -158,14 +152,7 @@ ENTRY(_evt_ivhw) fp = 0; #endif -#if ANOMALY_05000283 || ANOMALY_05000315 - cc = r7 == r7; - p5.h = HI(CHIPID); - p5.l = LO(CHIPID); - if cc jump 1f; - r7.l = W[p5]; -1: -#endif + ANOMALY_283_315_WORKAROUND(p5, r7) /* Handle all stacked hardware errors * To make sure we don't hang forever, only do it 10 times @@ -261,6 +248,31 @@ ENTRY(_evt_system_call) ENDPROC(_evt_system_call) #ifdef CONFIG_IPIPE +/* + * __ipipe_call_irqtail: lowers the current priority level to EVT15 + * before running a user-defined routine, then raises the priority + * level to EVT14 to prepare the caller for a normal interrupt + * return through RTI. + * + * We currently use this facility in two occasions: + * + * - to branch to __ipipe_irq_tail_hook as requested by a high + * priority domain after the pipeline delivered an interrupt, + * e.g. such as Xenomai, in order to start its rescheduling + * procedure, since we may not switch tasks when IRQ levels are + * nested on the Blackfin, so we have to fake an interrupt return + * so that we may reschedule immediately. + * + * - to branch to sync_root_irqs, in order to play any interrupt + * pending for the root domain (i.e. the Linux kernel). This lowers + * the core priority level enough so that Linux IRQ handlers may + * never delay interrupts handled by high priority domains; we defer + * those handlers until this point instead. This is a substitute + * to using a threaded interrupt model for the Linux kernel. + * + * r0: address of user-defined routine + * context: caller must have preempted EVT15, hw interrupts must be off. + */ ENTRY(___ipipe_call_irqtail) p0 = r0; r0.l = 1f; @@ -276,33 +288,19 @@ ENTRY(___ipipe_call_irqtail) ( r7:4, p5:3 ) = [sp++]; rets = [sp++]; - [--sp] = reti; - reti = [sp++]; /* IRQs are off. */ - r0.h = 3f; - r0.l = 3f; - p0.l = lo(EVT14); - p0.h = hi(EVT14); - [p0] = r0; - csync; - r0 = 0x401f (z); +#ifdef CONFIG_DEBUG_HWERR + /* enable irq14 & hwerr interrupt, until we transition to _evt_evt14 */ + r0 = (EVT_IVG14 | EVT_IVHW | \ + EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU); +#else + /* Only enable irq14 interrupt, until we transition to _evt_evt14 */ + r0 = (EVT_IVG14 | \ + EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU); +#endif sti r0; - raise 14; - [--sp] = reti; /* IRQs on. */ + raise 14; /* Branches to _evt_evt14 */ 2: jump 2b; /* Likely paranoid. */ -3: - sp += 4; /* Discard saved RETI */ - r0.h = _evt14_softirq; - r0.l = _evt14_softirq; - p0.l = lo(EVT14); - p0.h = hi(EVT14); - [p0] = r0; - csync; - p0.l = _bfin_irq_flags; - p0.h = _bfin_irq_flags; - r0 = [p0]; - sti r0; - rts; ENDPROC(___ipipe_call_irqtail) #endif /* CONFIG_IPIPE */ diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index b42150190d0..6ffda78aaf9 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -967,7 +967,7 @@ void __cpuinit init_exception_vectors(void) bfin_write_EVT11(evt_evt11); bfin_write_EVT12(evt_evt12); bfin_write_EVT13(evt_evt13); - bfin_write_EVT14(evt14_softirq); + bfin_write_EVT14(evt_evt14); bfin_write_EVT15(evt_system_call); CSYNC(); } @@ -1052,18 +1052,26 @@ int __init init_arch_irq(void) set_irq_chained_handler(irq, bfin_demux_error_irq); break; #endif + #ifdef CONFIG_SMP +#ifdef CONFIG_TICKSOURCE_GPTMR0 + case IRQ_TIMER0: +#endif +#ifdef CONFIG_TICKSOURCE_CORETMR + case IRQ_CORETMR: +#endif case IRQ_SUPPLE_0: case IRQ_SUPPLE_1: set_irq_handler(irq, handle_percpu_irq); break; #endif + #ifdef CONFIG_IPIPE #ifndef CONFIG_TICKSOURCE_CORETMR case IRQ_TIMER0: set_irq_handler(irq, handle_simple_irq); break; -#endif /* !CONFIG_TICKSOURCE_CORETMR */ +#endif case IRQ_CORETMR: set_irq_handler(irq, handle_simple_irq); break; @@ -1071,15 +1079,10 @@ int __init init_arch_irq(void) set_irq_handler(irq, handle_level_irq); break; #else /* !CONFIG_IPIPE */ -#ifdef CONFIG_TICKSOURCE_GPTMR0 - case IRQ_TIMER0: - set_irq_handler(irq, handle_percpu_irq); - break; -#endif /* CONFIG_TICKSOURCE_GPTMR0 */ default: set_irq_handler(irq, handle_simple_irq); break; -#endif /* !CONFIG_IPIPE */ +#endif /* !CONFIG_IPIPE */ } } diff --git a/arch/blackfin/mach-common/lock.S b/arch/blackfin/mach-common/lock.S deleted file mode 100644 index 6c5f5f0ea7f..00000000000 --- a/arch/blackfin/mach-common/lock.S +++ /dev/null @@ -1,223 +0,0 @@ -/* - * File: arch/blackfin/mach-common/lock.S - * Based on: - * Author: LG Soft India - * - * Created: ? - * Description: kernel locks - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <linux/linkage.h> -#include <asm/blackfin.h> - -.text - -/* When you come here, it is assumed that - * R0 - Which way to be locked - */ - -ENTRY(_cache_grab_lock) - - [--SP]=( R7:0,P5:0 ); - - P1.H = HI(IMEM_CONTROL); - P1.L = LO(IMEM_CONTROL); - P5.H = HI(ICPLB_ADDR0); - P5.L = LO(ICPLB_ADDR0); - P4.H = HI(ICPLB_DATA0); - P4.L = LO(ICPLB_DATA0); - R7 = R0; - - /* If the code of interest already resides in the cache - * invalidate the entire cache itself. - * invalidate_entire_icache; - */ - - SP += -12; - [--SP] = RETS; - CALL _invalidate_entire_icache; - RETS = [SP++]; - SP += 12; - - /* Disable the Interrupts*/ - - CLI R3; - -.LLOCK_WAY: - - /* Way0 - 0xFFA133E0 - * Way1 - 0xFFA137E0 - * Way2 - 0xFFA13BE0 Total Way Size = 4K - * Way3 - 0xFFA13FE0 - */ - - /* Procedure Ex. -Set the locks for other ways by setting ILOC[3:1] - * Only Way0 of the instruction cache can now be - * replaced by a new code - */ - - R5 = R7; - CC = BITTST(R7,0); - IF CC JUMP .LCLEAR1; - R7 = 0; - BITSET(R7,0); - JUMP .LDONE1; - -.LCLEAR1: - R7 = 0; - BITCLR(R7,0); -.LDONE1: R4 = R7 << 3; - R7 = [P1]; - R7 = R7 | R4; - SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ - .align 8; - [P1] = R7; - SSYNC; - - R7 = R5; - CC = BITTST(R7,1); - IF CC JUMP .LCLEAR2; - R7 = 0; - BITSET(R7,1); - JUMP .LDONE2; - -.LCLEAR2: - R7 = 0; - BITCLR(R7,1); -.LDONE2: R4 = R7 << 3; - R7 = [P1]; - R7 = R7 | R4; - SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ - .align 8; - [P1] = R7; - SSYNC; - - R7 = R5; - CC = BITTST(R7,2); - IF CC JUMP .LCLEAR3; - R7 = 0; - BITSET(R7,2); - JUMP .LDONE3; -.LCLEAR3: - R7 = 0; - BITCLR(R7,2); -.LDONE3: R4 = R7 << 3; - R7 = [P1]; - R7 = R7 | R4; - SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ - .align 8; - [P1] = R7; - SSYNC; - - - R7 = R5; - CC = BITTST(R7,3); - IF CC JUMP .LCLEAR4; - R7 = 0; - BITSET(R7,3); - JUMP .LDONE4; -.LCLEAR4: - R7 = 0; - BITCLR(R7,3); -.LDONE4: R4 = R7 << 3; - R7 = [P1]; - R7 = R7 | R4; - SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ - .align 8; - [P1] = R7; - SSYNC; - - STI R3; - - ( R7:0,P5:0 ) = [SP++]; - - RTS; -ENDPROC(_cache_grab_lock) - -/* After the execution of critical code, the code is now locked into - * the cache way. Now we need to set ILOC. - * - * R0 - Which way to be locked - */ - -ENTRY(_bfin_cache_lock) - - [--SP]=( R7:0,P5:0 ); - - P1.H = HI(IMEM_CONTROL); - P1.L = LO(IMEM_CONTROL); - - /* Disable the Interrupts*/ - CLI R3; - - R7 = [P1]; - R2 = ~(0x78) (X); /* mask out ILOC */ - R7 = R7 & R2; - R0 = R0 << 3; - R7 = R0 | R7; - SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ - .align 8; - [P1] = R7; - SSYNC; - /* Renable the Interrupts */ - STI R3; - - ( R7:0,P5:0 ) = [SP++]; - RTS; -ENDPROC(_bfin_cache_lock) - -/* Invalidate the Entire Instruction cache by - * disabling IMC bit - */ -ENTRY(_invalidate_entire_icache) - [--SP] = ( R7:5); - - P0.L = LO(IMEM_CONTROL); - P0.H = HI(IMEM_CONTROL); - R7 = [P0]; - - /* Clear the IMC bit , All valid bits in the instruction - * cache are set to the invalid state - */ - BITCLR(R7,IMC_P); - CLI R6; - SSYNC; /* SSYNC required before invalidating cache. */ - .align 8; - [P0] = R7; - SSYNC; - STI R6; - - /* Configures the instruction cache agian */ - R6 = (IMC | ENICPLB); - R7 = R7 | R6; - - CLI R6; - SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ - .align 8; - [P0] = R7; - SSYNC; - STI R6; - - ( R7:5) = [SP++]; - RTS; -ENDPROC(_invalidate_entire_icache) diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index 9e7e27b7fc8..0e3d4ff9d8b 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c @@ -38,6 +38,7 @@ #include <linux/io.h> #include <linux/irq.h> +#include <asm/cplb.h> #include <asm/gpio.h> #include <asm/dma.h> #include <asm/dpmc.h> @@ -170,58 +171,6 @@ static void flushinv_all_dcache(void) } #endif -static inline void dcache_disable(void) -{ -#ifdef CONFIG_BFIN_DCACHE - unsigned long ctrl; - -#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK) - flushinv_all_dcache(); -#endif - SSYNC(); - ctrl = bfin_read_DMEM_CONTROL(); - ctrl &= ~ENDCPLB; - bfin_write_DMEM_CONTROL(ctrl); - SSYNC(); -#endif -} - -static inline void dcache_enable(void) -{ -#ifdef CONFIG_BFIN_DCACHE - unsigned long ctrl; - SSYNC(); - ctrl = bfin_read_DMEM_CONTROL(); - ctrl |= ENDCPLB; - bfin_write_DMEM_CONTROL(ctrl); - SSYNC(); -#endif -} - -static inline void icache_disable(void) -{ -#ifdef CONFIG_BFIN_ICACHE - unsigned long ctrl; - SSYNC(); - ctrl = bfin_read_IMEM_CONTROL(); - ctrl &= ~ENICPLB; - bfin_write_IMEM_CONTROL(ctrl); - SSYNC(); -#endif -} - -static inline void icache_enable(void) -{ -#ifdef CONFIG_BFIN_ICACHE - unsigned long ctrl; - SSYNC(); - ctrl = bfin_read_IMEM_CONTROL(); - ctrl |= ENICPLB; - bfin_write_IMEM_CONTROL(ctrl); - SSYNC(); -#endif -} - int bfin_pm_suspend_mem_enter(void) { unsigned long flags; @@ -258,16 +207,19 @@ int bfin_pm_suspend_mem_enter(void) bfin_gpio_pm_hibernate_suspend(); - dcache_disable(); - icache_disable(); +#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK) + flushinv_all_dcache(); +#endif + _disable_dcplb(); + _disable_icplb(); bf53x_suspend_l1_mem(memptr); do_hibernate(wakeup | vr_wakeup); /* Goodbye */ bf53x_resume_l1_mem(memptr); - icache_enable(); - dcache_enable(); + _enable_icplb(); + _enable_dcplb(); bfin_gpio_pm_hibernate_restore(); blackfin_dma_resume(); diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index 68bd0bd680c..b88ce7fda54 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c @@ -33,6 +33,7 @@ #include <asm/bfin-global.h> #include <asm/pda.h> #include <asm/cplbinit.h> +#include <asm/early_printk.h> #include "blackfin_sram.h" /* @@ -113,6 +114,8 @@ asmlinkage void __init init_pda(void) { unsigned int cpu = raw_smp_processor_id(); + early_shadow_stamp(); + /* Initialize the PDA fields holding references to other parts of the memory. The content of such memory is still undefined at the time of the call, we are only setting up diff --git a/arch/blackfin/mm/isram-driver.c b/arch/blackfin/mm/isram-driver.c index c080e70f98b..beb1a608824 100644 --- a/arch/blackfin/mm/isram-driver.c +++ b/arch/blackfin/mm/isram-driver.c @@ -16,6 +16,8 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#define pr_fmt(fmt) "isram: " fmt + #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> @@ -23,6 +25,7 @@ #include <linux/sched.h> #include <asm/blackfin.h> +#include <asm/dma.h> /* * IMPORTANT WARNING ABOUT THESE FUNCTIONS @@ -50,10 +53,12 @@ static DEFINE_SPINLOCK(dtest_lock); #define IADDR2DTEST(x) \ ({ unsigned long __addr = (unsigned long)(x); \ (__addr & 0x47F8) | /* address bits 14 & 10:3 */ \ + (__addr & 0x8000) << 23 | /* Bank A/B */ \ (__addr & 0x0800) << 15 | /* address bit 11 */ \ - (__addr & 0x3000) << 4 | /* address bits 13:12 */ \ - (__addr & 0x8000) << 8 | /* address bit 15 */ \ - (0x1000004); /* isram access */ \ + (__addr & 0x3000) << 4 | /* address bits 13:12 */ \ + (__addr & 0x8000) << 8 | /* address bit 15 */ \ + (0x1000000) | /* instruction access = 1 */ \ + (0x4); /* data array = 1 */ \ }) /* Takes a pointer, and returns the offset (in bits) which things should be shifted */ @@ -70,7 +75,7 @@ static void isram_write(const void *addr, uint64_t data) if (addr >= (void *)(L1_CODE_START + L1_CODE_LENGTH)) return; - cmd = IADDR2DTEST(addr) | 1; /* write */ + cmd = IADDR2DTEST(addr) | 2; /* write */ /* * Writes to DTEST_DATA[0:1] need to be atomic with write to DTEST_COMMAND @@ -127,8 +132,7 @@ static bool isram_check_addr(const void *addr, size_t n) (addr < (void *)(L1_CODE_START + L1_CODE_LENGTH))) { if ((addr + n) > (void *)(L1_CODE_START + L1_CODE_LENGTH)) { show_stack(NULL, NULL); - printk(KERN_ERR "isram_memcpy: copy involving %p length " - "(%zu) too long\n", addr, n); + pr_err("copy involving %p length (%zu) too long\n", addr, n); } return true; } @@ -199,3 +203,209 @@ void *isram_memcpy(void *dest, const void *src, size_t n) } EXPORT_SYMBOL(isram_memcpy); +#ifdef CONFIG_BFIN_ISRAM_SELF_TEST + +#define TEST_LEN 0x100 + +static __init void hex_dump(unsigned char *buf, int len) +{ + while (len--) + pr_cont("%02x", *buf++); +} + +static __init int isram_read_test(char *sdram, void *l1inst) +{ + int i, ret = 0; + uint64_t data1, data2; + + pr_info("INFO: running isram_read tests\n"); + + /* setup some different data to play with */ + for (i = 0; i < TEST_LEN; ++i) + sdram[i] = i; + dma_memcpy(l1inst, sdram, TEST_LEN); + + /* make sure we can read the L1 inst */ + for (i = 0; i < TEST_LEN; i += sizeof(uint64_t)) { + data1 = isram_read(l1inst + i); + memcpy(&data2, sdram + i, sizeof(data2)); + if (memcmp(&data1, &data2, sizeof(uint64_t))) { + pr_err("FAIL: isram_read(%p) returned %#llx but wanted %#llx\n", + l1inst + i, data1, data2); + ++ret; + } + } + + return ret; +} + +static __init int isram_write_test(char *sdram, void *l1inst) +{ + int i, ret = 0; + uint64_t data1, data2; + + pr_info("INFO: running isram_write tests\n"); + + /* setup some different data to play with */ + memset(sdram, 0, TEST_LEN * 2); + dma_memcpy(l1inst, sdram, TEST_LEN); + for (i = 0; i < TEST_LEN; ++i) + sdram[i] = i; + + /* make sure we can write the L1 inst */ + for (i = 0; i < TEST_LEN; i += sizeof(uint64_t)) { + memcpy(&data1, sdram + i, sizeof(data1)); + isram_write(l1inst + i, data1); + data2 = isram_read(l1inst + i); + if (memcmp(&data1, &data2, sizeof(uint64_t))) { + pr_err("FAIL: isram_write(%p, %#llx) != %#llx\n", + l1inst + i, data1, data2); + ++ret; + } + } + + dma_memcpy(sdram + TEST_LEN, l1inst, TEST_LEN); + if (memcmp(sdram, sdram + TEST_LEN, TEST_LEN)) { + pr_err("FAIL: isram_write() did not work properly\n"); + ++ret; + } + + return ret; +} + +static __init int +_isram_memcpy_test(char pattern, void *sdram, void *l1inst, const char *smemcpy, + void *(*fmemcpy)(void *, const void *, size_t)) +{ + memset(sdram, pattern, TEST_LEN); + fmemcpy(l1inst, sdram, TEST_LEN); + fmemcpy(sdram + TEST_LEN, l1inst, TEST_LEN); + if (memcmp(sdram, sdram + TEST_LEN, TEST_LEN)) { + pr_err("FAIL: %s(%p <=> %p, %#x) failed (data is %#x)\n", + smemcpy, l1inst, sdram, TEST_LEN, pattern); + return 1; + } + return 0; +} +#define _isram_memcpy_test(a, b, c, d) _isram_memcpy_test(a, b, c, #d, d) + +static __init int isram_memcpy_test(char *sdram, void *l1inst) +{ + int i, j, thisret, ret = 0; + + /* check broad isram_memcpy() */ + pr_info("INFO: running broad isram_memcpy tests\n"); + for (i = 0xf; i >= 0; --i) + ret += _isram_memcpy_test(i, sdram, l1inst, isram_memcpy); + + /* check read of small, unaligned, and hardware 64bit limits */ + pr_info("INFO: running isram_memcpy (read) tests\n"); + + for (i = 0; i < TEST_LEN; ++i) + sdram[i] = i; + dma_memcpy(l1inst, sdram, TEST_LEN); + + thisret = 0; + for (i = 0; i < TEST_LEN - 32; ++i) { + unsigned char cmp[32]; + for (j = 1; j <= 32; ++j) { + memset(cmp, 0, sizeof(cmp)); + isram_memcpy(cmp, l1inst + i, j); + if (memcmp(cmp, sdram + i, j)) { + pr_err("FAIL: %p:", l1inst + 1); + hex_dump(cmp, j); + pr_cont(" SDRAM:"); + hex_dump(sdram + i, j); + pr_cont("\n"); + if (++thisret > 20) { + pr_err("FAIL: skipping remaining series\n"); + i = TEST_LEN; + break; + } + } + } + } + ret += thisret; + + /* check write of small, unaligned, and hardware 64bit limits */ + pr_info("INFO: running isram_memcpy (write) tests\n"); + + memset(sdram + TEST_LEN, 0, TEST_LEN); + dma_memcpy(l1inst, sdram + TEST_LEN, TEST_LEN); + + thisret = 0; + for (i = 0; i < TEST_LEN - 32; ++i) { + unsigned char cmp[32]; + for (j = 1; j <= 32; ++j) { + isram_memcpy(l1inst + i, sdram + i, j); + dma_memcpy(cmp, l1inst + i, j); + if (memcmp(cmp, sdram + i, j)) { + pr_err("FAIL: %p:", l1inst + i); + hex_dump(cmp, j); + pr_cont(" SDRAM:"); + hex_dump(sdram + i, j); + pr_cont("\n"); + if (++thisret > 20) { + pr_err("FAIL: skipping remaining series\n"); + i = TEST_LEN; + break; + } + } + } + } + ret += thisret; + + return ret; +} + +static __init int isram_test_init(void) +{ + int ret; + char *sdram; + void *l1inst; + + sdram = kmalloc(TEST_LEN * 2, GFP_KERNEL); + if (!sdram) { + pr_warning("SKIP: could not allocate sdram\n"); + return 0; + } + + l1inst = l1_inst_sram_alloc(TEST_LEN); + if (!l1inst) { + kfree(sdram); + pr_warning("SKIP: could not allocate L1 inst\n"); + return 0; + } + + /* sanity check initial L1 inst state */ + ret = 1; + pr_info("INFO: running initial dma_memcpy checks\n"); + if (_isram_memcpy_test(0xa, sdram, l1inst, dma_memcpy)) + goto abort; + if (_isram_memcpy_test(0x5, sdram, l1inst, dma_memcpy)) + goto abort; + + ret = 0; + ret += isram_read_test(sdram, l1inst); + ret += isram_write_test(sdram, l1inst); + ret += isram_memcpy_test(sdram, l1inst); + + abort: + sram_free(l1inst); + kfree(sdram); + + if (ret) + return -EIO; + + pr_info("PASS: all tests worked !\n"); + return 0; +} +late_initcall(isram_test_init); + +static __exit void isram_test_exit(void) +{ + /* stub to allow unloading */ +} +module_exit(isram_test_exit); + +#endif diff --git a/arch/blackfin/mm/sram-alloc.c b/arch/blackfin/mm/sram-alloc.c index 99e4dbb1dfd..eb63ab353e5 100644 --- a/arch/blackfin/mm/sram-alloc.c +++ b/arch/blackfin/mm/sram-alloc.c @@ -42,11 +42,6 @@ #include <asm/mem_map.h> #include "blackfin_sram.h" -static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1sram_lock); -static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1_data_sram_lock); -static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1_inst_sram_lock); -static spinlock_t l2_sram_lock ____cacheline_aligned_in_smp; - /* the data structure for L1 scratchpad and DATA SRAM */ struct sram_piece { void *paddr; @@ -55,6 +50,7 @@ struct sram_piece { struct sram_piece *next; }; +static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1sram_lock); static DEFINE_PER_CPU(struct sram_piece, free_l1_ssram_head); static DEFINE_PER_CPU(struct sram_piece, used_l1_ssram_head); @@ -68,12 +64,18 @@ static DEFINE_PER_CPU(struct sram_piece, free_l1_data_B_sram_head); static DEFINE_PER_CPU(struct sram_piece, used_l1_data_B_sram_head); #endif +#if L1_DATA_A_LENGTH || L1_DATA_B_LENGTH +static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1_data_sram_lock); +#endif + #if L1_CODE_LENGTH != 0 +static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1_inst_sram_lock); static DEFINE_PER_CPU(struct sram_piece, free_l1_inst_sram_head); static DEFINE_PER_CPU(struct sram_piece, used_l1_inst_sram_head); #endif #if L2_LENGTH != 0 +static spinlock_t l2_sram_lock ____cacheline_aligned_in_smp; static struct sram_piece free_l2_sram_head, used_l2_sram_head; #endif @@ -225,10 +227,10 @@ static void __init l2_sram_init(void) printk(KERN_INFO "Blackfin L2 SRAM: %d KB (%d KB free)\n", L2_LENGTH >> 10, free_l2_sram_head.next->size >> 10); -#endif /* mutex initialize */ spin_lock_init(&l2_sram_lock); +#endif } static int __init bfin_sram_init(void) @@ -416,18 +418,17 @@ EXPORT_SYMBOL(sram_free); void *l1_data_A_sram_alloc(size_t size) { +#if L1_DATA_A_LENGTH != 0 unsigned long flags; - void *addr = NULL; + void *addr; unsigned int cpu; cpu = get_cpu(); /* add mutex operation */ spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags); -#if L1_DATA_A_LENGTH != 0 addr = _sram_alloc(size, &per_cpu(free_l1_data_A_sram_head, cpu), &per_cpu(used_l1_data_A_sram_head, cpu)); -#endif /* add mutex operation */ spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags); @@ -437,11 +438,15 @@ void *l1_data_A_sram_alloc(size_t size) (long unsigned int)addr, size); return addr; +#else + return NULL; +#endif } EXPORT_SYMBOL(l1_data_A_sram_alloc); int l1_data_A_sram_free(const void *addr) { +#if L1_DATA_A_LENGTH != 0 unsigned long flags; int ret; unsigned int cpu; @@ -450,18 +455,17 @@ int l1_data_A_sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags); -#if L1_DATA_A_LENGTH != 0 ret = _sram_free(addr, &per_cpu(free_l1_data_A_sram_head, cpu), &per_cpu(used_l1_data_A_sram_head, cpu)); -#else - ret = -1; -#endif /* add mutex operation */ spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags); put_cpu(); return ret; +#else + return -1; +#endif } EXPORT_SYMBOL(l1_data_A_sram_free); diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index e6c5c3d5e1f..23f846de62d 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -34,7 +34,6 @@ #include <asm/mca_asm.h> #include <linux/init.h> #include <linux/linkage.h> -#include "head.h" #ifdef CONFIG_HOTPLUG_CPU #define SAL_PSR_BITS_TO_SET \ diff --git a/arch/ia64/kernel/head.h b/arch/ia64/kernel/head.h deleted file mode 100644 index 2e2ac6824e6..00000000000 --- a/arch/ia64/kernel/head.h +++ /dev/null @@ -1 +0,0 @@ -extern void console_print(const char *s); diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h index 1cf54476745..ec514485c8b 100644 --- a/arch/m68k/include/asm/checksum.h +++ b/arch/m68k/include/asm/checksum.h @@ -1,5 +1,170 @@ -#ifdef __uClinux__ -#include "checksum_no.h" +#ifndef _M68K_CHECKSUM_H +#define _M68K_CHECKSUM_H + +#include <linux/in6.h> + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +__wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +extern __wsum csum_partial_copy_from_user(const void __user *src, + void *dst, + int len, __wsum sum, + int *csum_err); + +extern __wsum csum_partial_copy_nocheck(const void *src, + void *dst, int len, + __wsum sum); + + +#ifdef CONFIG_COLDFIRE + +/* + * The ColdFire cores don't support all the 68k instructions used + * in the optimized checksum code below. So it reverts back to using + * more standard C coded checksums. The fast checksum code is + * significantly larger than the optimized version, so it is not + * inlined here. + */ +__sum16 ip_fast_csum(const void *iph, unsigned int ihl); + +static inline __sum16 csum_fold(__wsum sum) +{ + unsigned int tmp = (__force u32)sum; + + tmp = (tmp & 0xffff) + (tmp >> 16); + tmp = (tmp & 0xffff) + (tmp >> 16); + + return (__force __sum16)~tmp; +} + #else -#include "checksum_mm.h" -#endif + +/* + * This is a version of ip_fast_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + */ +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) +{ + unsigned int sum = 0; + unsigned long tmp; + + __asm__ ("subqw #1,%2\n" + "1:\t" + "movel %1@+,%3\n\t" + "addxl %3,%0\n\t" + "dbra %2,1b\n\t" + "movel %0,%3\n\t" + "swap %3\n\t" + "addxw %3,%0\n\t" + "clrw %3\n\t" + "addxw %3,%0\n\t" + : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp) + : "0" (sum), "1" (iph), "2" (ihl) + : "memory"); + return (__force __sum16)~sum; +} + +static inline __sum16 csum_fold(__wsum sum) +{ + unsigned int tmp = (__force u32)sum; + + __asm__("swap %1\n\t" + "addw %1, %0\n\t" + "clrw %1\n\t" + "addxw %1, %0" + : "=&d" (sum), "=&d" (tmp) + : "0" (sum), "1" (tmp)); + + return (__force __sum16)~sum; +} + +#endif /* CONFIG_COLDFIRE */ + +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + __asm__ ("addl %2,%0\n\t" + "addxl %3,%0\n\t" + "addxl %4,%0\n\t" + "clrl %1\n\t" + "addxl %1,%0" + : "=&d" (sum), "=d" (saddr) + : "g" (daddr), "1" (saddr), "d" (len + proto), + "0" (sum)); + return sum; +} + + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 +csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +static inline __sum16 ip_compute_csum(const void *buff, int len) +{ + return csum_fold (csum_partial(buff, len, 0)); +} + +#define _HAVE_ARCH_IPV6_CSUM +static __inline__ __sum16 +csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, + __u32 len, unsigned short proto, __wsum sum) +{ + register unsigned long tmp; + __asm__("addl %2@,%0\n\t" + "movel %2@(4),%1\n\t" + "addxl %1,%0\n\t" + "movel %2@(8),%1\n\t" + "addxl %1,%0\n\t" + "movel %2@(12),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@,%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(4),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(8),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(12),%1\n\t" + "addxl %1,%0\n\t" + "addxl %4,%0\n\t" + "clrl %1\n\t" + "addxl %1,%0" + : "=&d" (sum), "=&d" (tmp) + : "a" (saddr), "a" (daddr), "d" (len + proto), + "0" (sum)); + + return csum_fold(sum); +} + +#endif /* _M68K_CHECKSUM_H */ diff --git a/arch/m68k/include/asm/checksum_mm.h b/arch/m68k/include/asm/checksum_mm.h deleted file mode 100644 index 494f9aec37e..00000000000 --- a/arch/m68k/include/asm/checksum_mm.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef _M68K_CHECKSUM_H -#define _M68K_CHECKSUM_H - -#include <linux/in6.h> - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * the same as csum_partial, but copies from src while it - * checksums - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -extern __wsum csum_partial_copy_from_user(const void __user *src, - void *dst, - int len, __wsum sum, - int *csum_err); - -extern __wsum csum_partial_copy_nocheck(const void *src, - void *dst, int len, - __wsum sum); - -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - * - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum = 0; - unsigned long tmp; - - __asm__ ("subqw #1,%2\n" - "1:\t" - "movel %1@+,%3\n\t" - "addxl %3,%0\n\t" - "dbra %2,1b\n\t" - "movel %0,%3\n\t" - "swap %3\n\t" - "addxw %3,%0\n\t" - "clrw %3\n\t" - "addxw %3,%0\n\t" - : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp) - : "0" (sum), "1" (iph), "2" (ihl) - : "memory"); - return (__force __sum16)~sum; -} - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - unsigned int tmp = (__force u32)sum; - __asm__("swap %1\n\t" - "addw %1, %0\n\t" - "clrw %1\n\t" - "addxw %1, %0" - : "=&d" (sum), "=&d" (tmp) - : "0" (sum), "1" (tmp)); - return (__force __sum16)~sum; -} - - -static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - __asm__ ("addl %2,%0\n\t" - "addxl %3,%0\n\t" - "addxl %4,%0\n\t" - "clrl %1\n\t" - "addxl %1,%0" - : "=&d" (sum), "=d" (saddr) - : "g" (daddr), "1" (saddr), "d" (len + proto), - "0" (sum)); - return sum; -} - - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -static inline __sum16 ip_compute_csum(const void *buff, int len) -{ - return csum_fold (csum_partial(buff, len, 0)); -} - -#define _HAVE_ARCH_IPV6_CSUM -static __inline__ __sum16 -csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, __wsum sum) -{ - register unsigned long tmp; - __asm__("addl %2@,%0\n\t" - "movel %2@(4),%1\n\t" - "addxl %1,%0\n\t" - "movel %2@(8),%1\n\t" - "addxl %1,%0\n\t" - "movel %2@(12),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@,%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(4),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(8),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(12),%1\n\t" - "addxl %1,%0\n\t" - "addxl %4,%0\n\t" - "clrl %1\n\t" - "addxl %1,%0" - : "=&d" (sum), "=&d" (tmp) - : "a" (saddr), "a" (daddr), "d" (len + proto), - "0" (sum)); - - return csum_fold(sum); -} - -#endif /* _M68K_CHECKSUM_H */ diff --git a/arch/m68k/include/asm/checksum_no.h b/arch/m68k/include/asm/checksum_no.h deleted file mode 100644 index 81883482ffb..00000000000 --- a/arch/m68k/include/asm/checksum_no.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef _M68K_CHECKSUM_H -#define _M68K_CHECKSUM_H - -#include <linux/in6.h> - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * the same as csum_partial, but copies from src while it - * checksums - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum); - - -/* - * the same as csum_partial_copy, but copies from user space. - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -extern __wsum csum_partial_copy_from_user(const void __user *src, - void *dst, int len, __wsum sum, int *csum_err); - -__sum16 ip_fast_csum(const void *iph, unsigned int ihl); - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - unsigned int tmp = (__force u32)sum; -#ifdef CONFIG_COLDFIRE - tmp = (tmp & 0xffff) + (tmp >> 16); - tmp = (tmp & 0xffff) + (tmp >> 16); - return (__force __sum16)~tmp; -#else - __asm__("swap %1\n\t" - "addw %1, %0\n\t" - "clrw %1\n\t" - "addxw %1, %0" - : "=&d" (sum), "=&d" (tmp) - : "0" (sum), "1" (sum)); - return (__force __sum16)~sum; -#endif -} - - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ - -static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - __asm__ ("addl %1,%0\n\t" - "addxl %4,%0\n\t" - "addxl %5,%0\n\t" - "clrl %1\n\t" - "addxl %1,%0" - : "=&d" (sum), "=&d" (saddr) - : "0" (daddr), "1" (saddr), "d" (len + proto), - "d"(sum)); - return sum; -} - -static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -extern __sum16 ip_compute_csum(const void *buff, int len); - -#define _HAVE_ARCH_IPV6_CSUM -static __inline__ __sum16 -csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, __wsum sum) -{ - register unsigned long tmp; - __asm__("addl %2@,%0\n\t" - "movel %2@(4),%1\n\t" - "addxl %1,%0\n\t" - "movel %2@(8),%1\n\t" - "addxl %1,%0\n\t" - "movel %2@(12),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@,%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(4),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(8),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(12),%1\n\t" - "addxl %1,%0\n\t" - "addxl %4,%0\n\t" - "clrl %1\n\t" - "addxl %1,%0" - : "=&d" (sum), "=&d" (tmp) - : "a" (saddr), "a" (daddr), "d" (len + proto), - "0" (sum)); - - return csum_fold(sum); -} - -#endif /* _M68K_CHECKSUM_H */ diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h index b82e660cf1c..6fbdfe89510 100644 --- a/arch/m68k/include/asm/dma.h +++ b/arch/m68k/include/asm/dma.h @@ -1,5 +1,491 @@ -#ifdef __uClinux__ -#include "dma_no.h" +#ifndef _M68K_DMA_H +#define _M68K_DMA_H 1 + +#ifdef CONFIG_COLDFIRE +/* + * ColdFire DMA Model: + * ColdFire DMA supports two forms of DMA: Single and Dual address. Single + * address mode emits a source address, and expects that the device will either + * pick up the data (DMA READ) or source data (DMA WRITE). This implies that + * the device will place data on the correct byte(s) of the data bus, as the + * memory transactions are always 32 bits. This implies that only 32 bit + * devices will find single mode transfers useful. Dual address DMA mode + * performs two cycles: source read and destination write. ColdFire will + * align the data so that the device will always get the correct bytes, thus + * is useful for 8 and 16 bit devices. This is the mode that is supported + * below. + * + * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000 + * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de) + * + * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000 + * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de) + * + * APR/18/2002 : added proper support for MCF5272 DMA controller. + * Arthur Shipkowski (art@videon-central.com) + */ + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfdma.h> + +/* + * Set number of channels of DMA on ColdFire for different implementations. + */ +#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \ + defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) +#define MAX_M68K_DMA_CHANNELS 4 +#elif defined(CONFIG_M5272) +#define MAX_M68K_DMA_CHANNELS 1 +#elif defined(CONFIG_M532x) +#define MAX_M68K_DMA_CHANNELS 0 #else -#include "dma_mm.h" +#define MAX_M68K_DMA_CHANNELS 2 #endif + +extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS]; +extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; + +#if !defined(CONFIG_M5272) +#define DMA_MODE_WRITE_BIT 0x01 /* Memory/IO to IO/Memory select */ +#define DMA_MODE_WORD_BIT 0x02 /* 8 or 16 bit transfers */ +#define DMA_MODE_LONG_BIT 0x04 /* or 32 bit transfers */ +#define DMA_MODE_SINGLE_BIT 0x08 /* single-address-mode */ + +/* I/O to memory, 8 bits, mode */ +#define DMA_MODE_READ 0 +/* memory to I/O, 8 bits, mode */ +#define DMA_MODE_WRITE 1 +/* I/O to memory, 16 bits, mode */ +#define DMA_MODE_READ_WORD 2 +/* memory to I/O, 16 bits, mode */ +#define DMA_MODE_WRITE_WORD 3 +/* I/O to memory, 32 bits, mode */ +#define DMA_MODE_READ_LONG 4 +/* memory to I/O, 32 bits, mode */ +#define DMA_MODE_WRITE_LONG 5 +/* I/O to memory, 8 bits, single-address-mode */ +#define DMA_MODE_READ_SINGLE 8 +/* memory to I/O, 8 bits, single-address-mode */ +#define DMA_MODE_WRITE_SINGLE 9 +/* I/O to memory, 16 bits, single-address-mode */ +#define DMA_MODE_READ_WORD_SINGLE 10 +/* memory to I/O, 16 bits, single-address-mode */ +#define DMA_MODE_WRITE_WORD_SINGLE 11 +/* I/O to memory, 32 bits, single-address-mode */ +#define DMA_MODE_READ_LONG_SINGLE 12 +/* memory to I/O, 32 bits, single-address-mode */ +#define DMA_MODE_WRITE_LONG_SINGLE 13 + +#else /* CONFIG_M5272 is defined */ + +/* Source static-address mode */ +#define DMA_MODE_SRC_SA_BIT 0x01 +/* Two bits to select between all four modes */ +#define DMA_MODE_SSIZE_MASK 0x06 +/* Offset to shift bits in */ +#define DMA_MODE_SSIZE_OFF 0x01 +/* Destination static-address mode */ +#define DMA_MODE_DES_SA_BIT 0x10 +/* Two bits to select between all four modes */ +#define DMA_MODE_DSIZE_MASK 0x60 +/* Offset to shift bits in */ +#define DMA_MODE_DSIZE_OFF 0x05 +/* Size modifiers */ +#define DMA_MODE_SIZE_LONG 0x00 +#define DMA_MODE_SIZE_BYTE 0x01 +#define DMA_MODE_SIZE_WORD 0x02 +#define DMA_MODE_SIZE_LINE 0x03 + +/* + * Aliases to help speed quick ports; these may be suboptimal, however. They + * do not include the SINGLE mode modifiers since the MCF5272 does not have a + * mode where the device is in control of its addressing. + */ + +/* I/O to memory, 8 bits, mode */ +#define DMA_MODE_READ ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) +/* memory to I/O, 8 bits, mode */ +#define DMA_MODE_WRITE ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) +/* I/O to memory, 16 bits, mode */ +#define DMA_MODE_READ_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) +/* memory to I/O, 16 bits, mode */ +#define DMA_MODE_WRITE_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) +/* I/O to memory, 32 bits, mode */ +#define DMA_MODE_READ_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) +/* memory to I/O, 32 bits, mode */ +#define DMA_MODE_WRITE_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) + +#endif /* !defined(CONFIG_M5272) */ + +#if !defined(CONFIG_M5272) +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + volatile unsigned short *dmawp; + +#ifdef DMA_DEBUG + printk("enable_dma(dmanr=%d)\n", dmanr); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT; +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + volatile unsigned short *dmawp; + volatile unsigned char *dmapb; + +#ifdef DMA_DEBUG + printk("disable_dma(dmanr=%d)\n", dmanr); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + dmapb = (unsigned char *) dma_base_addr[dmanr]; + + /* Turn off external requests, and stop any DMA in progress */ + dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT; + dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE; +} + +/* + * Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + * + * This is a NOP for ColdFire. Provide a stub for compatibility. + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + + volatile unsigned char *dmabp; + volatile unsigned short *dmawp; + +#ifdef DMA_DEBUG + printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode); +#endif + + dmabp = (unsigned char *) dma_base_addr[dmanr]; + dmawp = (unsigned short *) dma_base_addr[dmanr]; + + /* Clear config errors */ + dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE; + + /* Set command register */ + dmawp[MCFDMA_DCR] = + MCFDMA_DCR_INT | /* Enable completion irq */ + MCFDMA_DCR_CS | /* Force one xfer per request */ + MCFDMA_DCR_AA | /* Enable auto alignment */ + /* single-address-mode */ + ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) | + /* sets s_rw (-> r/w) high if Memory to I/0 */ + ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) | + /* Memory to I/O or I/O to Memory */ + ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) | + /* 32 bit, 16 bit or 8 bit transfers */ + ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_SSIZE_WORD : + ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG : + MCFDMA_DCR_SSIZE_BYTE)) | + ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_DSIZE_WORD : + ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG : + MCFDMA_DCR_DSIZE_BYTE)); + +#ifdef DEBUG_DMA + printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__, + dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR], + (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]); +#endif +} + +/* Set transfer address for specific DMA channel */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + volatile unsigned short *dmawp; + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + dmalp = (unsigned int *) dma_base_addr[dmanr]; + + /* Determine which address registers are used for memory/device accesses */ + if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) { + /* Source incrementing, must be memory */ + dmalp[MCFDMA_SAR] = a; + /* Set dest address, must be device */ + dmalp[MCFDMA_DAR] = dma_device_address[dmanr]; + } else { + /* Destination incrementing, must be memory */ + dmalp[MCFDMA_DAR] = a; + /* Set source address, must be device */ + dmalp[MCFDMA_SAR] = dma_device_address[dmanr]; + } + +#ifdef DEBUG_DMA + printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n", + __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR], + (int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR], + (int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]); +#endif +} + +/* + * Specific for Coldfire - sets device address. + * Should be called after the mode set call, and before set DMA address. + */ +static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a) +{ +#ifdef DMA_DEBUG + printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a); +#endif + + dma_device_address[dmanr] = a; +} + +/* + * NOTE 2: "count" represents _bytes_. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + volatile unsigned short *dmawp; + +#ifdef DMA_DEBUG + printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + dmawp[MCFDMA_BCR] = (unsigned short)count; +} + +/* + * Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * Otherwise, it returns the number of _bytes_ left to transfer. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + volatile unsigned short *dmawp; + unsigned short count; + +#ifdef DMA_DEBUG + printk("get_dma_residue(dmanr=%d)\n", dmanr); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + count = dmawp[MCFDMA_BCR]; + return((int) count); +} +#else /* CONFIG_M5272 is defined */ + +/* + * The MCF5272 DMA controller is very different than the controller defined above + * in terms of register mapping. For instance, with the exception of the 16-bit + * interrupt register (IRQ#85, for reference), all of the registers are 32-bit. + * + * The big difference, however, is the lack of device-requested DMA. All modes + * are dual address transfer, and there is no 'device' setup or direction bit. + * You can DMA between a device and memory, between memory and memory, or even between + * two devices directly, with any combination of incrementing and non-incrementing + * addresses you choose. This puts a crimp in distinguishing between the 'device + * address' set up by set_dma_device_addr. + * + * Therefore, there are two options. One is to use set_dma_addr and set_dma_device_addr, + * which will act exactly as above in -- it will look to see if the source is set to + * autoincrement, and if so it will make the source use the set_dma_addr value and the + * destination the set_dma_device_addr value. Otherwise the source will be set to the + * set_dma_device_addr value and the destination will get the set_dma_addr value. + * + * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions + * and make it explicit. Depending on what you're doing, one of these two should work + * for you, but don't mix them in the same transfer setup. + */ + +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("enable_dma(dmanr=%d)\n", dmanr); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN; +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("disable_dma(dmanr=%d)\n", dmanr); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + + /* Turn off external requests, and stop any DMA in progress */ + dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN; + dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; +} + +/* + * Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + * + * This is a NOP for ColdFire. Provide a stub for compatibility. + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + + volatile unsigned int *dmalp; + volatile unsigned short *dmawp; + +#ifdef DMA_DEBUG + printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode); +#endif + dmalp = (unsigned int *) dma_base_addr[dmanr]; + dmawp = (unsigned short *) dma_base_addr[dmanr]; + + /* Clear config errors */ + dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; + + /* Set command register */ + dmalp[MCFDMA_DMR] = + MCFDMA_DMR_RQM_DUAL | /* Mandatory Request Mode setting */ + MCFDMA_DMR_DSTT_SD | /* Set up addressing types; set to supervisor-data. */ + MCFDMA_DMR_SRCT_SD | /* Set up addressing types; set to supervisor-data. */ + /* source static-address-mode */ + ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) | + /* dest static-address-mode */ + ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) | + /* burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272 */ + (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) | + (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF); + + dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN; /* Enable completion interrupts */ + +#ifdef DEBUG_DMA + printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__, + dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR], + (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]); +#endif +} + +/* Set transfer address for specific DMA channel */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + + /* Determine which address registers are used for memory/device accesses */ + if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) { + /* Source incrementing, must be memory */ + dmalp[MCFDMA_DSAR] = a; + /* Set dest address, must be device */ + dmalp[MCFDMA_DDAR] = dma_device_address[dmanr]; + } else { + /* Destination incrementing, must be memory */ + dmalp[MCFDMA_DDAR] = a; + /* Set source address, must be device */ + dmalp[MCFDMA_DSAR] = dma_device_address[dmanr]; + } + +#ifdef DEBUG_DMA + printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n", + __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR], + (int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR], + (int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]); +#endif +} + +/* + * Specific for Coldfire - sets device address. + * Should be called after the mode set call, and before set DMA address. + */ +static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a) +{ +#ifdef DMA_DEBUG + printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a); +#endif + + dma_device_address[dmanr] = a; +} + +/* + * NOTE 2: "count" represents _bytes_. + * + * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + dmalp[MCFDMA_DBCR] = count; +} + +/* + * Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * Otherwise, it returns the number of _bytes_ left to transfer. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + volatile unsigned int *dmalp; + unsigned int count; + +#ifdef DMA_DEBUG + printk("get_dma_residue(dmanr=%d)\n", dmanr); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + count = dmalp[MCFDMA_DBCR]; + return(count); +} + +#endif /* !defined(CONFIG_M5272) */ +#endif /* CONFIG_COLDFIRE */ + +/* it's useless on the m68k, but unfortunately needed by the new + bootmem allocator (but this should do it for this) */ +#define MAX_DMA_ADDRESS PAGE_OFFSET + +#define MAX_DMA_CHANNELS 8 + +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + +#define isa_dma_bridge_buggy (0) + +#endif /* _M68K_DMA_H */ diff --git a/arch/m68k/include/asm/dma_mm.h b/arch/m68k/include/asm/dma_mm.h deleted file mode 100644 index 4240fbc946f..00000000000 --- a/arch/m68k/include/asm/dma_mm.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _M68K_DMA_H -#define _M68K_DMA_H 1 - - -/* it's useless on the m68k, but unfortunately needed by the new - bootmem allocator (but this should do it for this) */ -#define MAX_DMA_ADDRESS PAGE_OFFSET - -#define MAX_DMA_CHANNELS 8 - -extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it again */ - -#define isa_dma_bridge_buggy (0) - -#endif /* _M68K_DMA_H */ diff --git a/arch/m68k/include/asm/dma_no.h b/arch/m68k/include/asm/dma_no.h deleted file mode 100644 index 939a0205621..00000000000 --- a/arch/m68k/include/asm/dma_no.h +++ /dev/null @@ -1,494 +0,0 @@ -#ifndef _M68K_DMA_H -#define _M68K_DMA_H 1 - -//#define DMA_DEBUG 1 - - -#ifdef CONFIG_COLDFIRE -/* - * ColdFire DMA Model: - * ColdFire DMA supports two forms of DMA: Single and Dual address. Single - * address mode emits a source address, and expects that the device will either - * pick up the data (DMA READ) or source data (DMA WRITE). This implies that - * the device will place data on the correct byte(s) of the data bus, as the - * memory transactions are always 32 bits. This implies that only 32 bit - * devices will find single mode transfers useful. Dual address DMA mode - * performs two cycles: source read and destination write. ColdFire will - * align the data so that the device will always get the correct bytes, thus - * is useful for 8 and 16 bit devices. This is the mode that is supported - * below. - * - * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000 - * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de) - * - * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000 - * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de) - * - * APR/18/2002 : added proper support for MCF5272 DMA controller. - * Arthur Shipkowski (art@videon-central.com) - */ - -#include <asm/coldfire.h> -#include <asm/mcfsim.h> -#include <asm/mcfdma.h> - -/* - * Set number of channels of DMA on ColdFire for different implementations. - */ -#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \ - defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) -#define MAX_M68K_DMA_CHANNELS 4 -#elif defined(CONFIG_M5272) -#define MAX_M68K_DMA_CHANNELS 1 -#elif defined(CONFIG_M532x) -#define MAX_M68K_DMA_CHANNELS 0 -#else -#define MAX_M68K_DMA_CHANNELS 2 -#endif - -extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS]; -extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; - -#if !defined(CONFIG_M5272) -#define DMA_MODE_WRITE_BIT 0x01 /* Memory/IO to IO/Memory select */ -#define DMA_MODE_WORD_BIT 0x02 /* 8 or 16 bit transfers */ -#define DMA_MODE_LONG_BIT 0x04 /* or 32 bit transfers */ -#define DMA_MODE_SINGLE_BIT 0x08 /* single-address-mode */ - -/* I/O to memory, 8 bits, mode */ -#define DMA_MODE_READ 0 -/* memory to I/O, 8 bits, mode */ -#define DMA_MODE_WRITE 1 -/* I/O to memory, 16 bits, mode */ -#define DMA_MODE_READ_WORD 2 -/* memory to I/O, 16 bits, mode */ -#define DMA_MODE_WRITE_WORD 3 -/* I/O to memory, 32 bits, mode */ -#define DMA_MODE_READ_LONG 4 -/* memory to I/O, 32 bits, mode */ -#define DMA_MODE_WRITE_LONG 5 -/* I/O to memory, 8 bits, single-address-mode */ -#define DMA_MODE_READ_SINGLE 8 -/* memory to I/O, 8 bits, single-address-mode */ -#define DMA_MODE_WRITE_SINGLE 9 -/* I/O to memory, 16 bits, single-address-mode */ -#define DMA_MODE_READ_WORD_SINGLE 10 -/* memory to I/O, 16 bits, single-address-mode */ -#define DMA_MODE_WRITE_WORD_SINGLE 11 -/* I/O to memory, 32 bits, single-address-mode */ -#define DMA_MODE_READ_LONG_SINGLE 12 -/* memory to I/O, 32 bits, single-address-mode */ -#define DMA_MODE_WRITE_LONG_SINGLE 13 - -#else /* CONFIG_M5272 is defined */ - -/* Source static-address mode */ -#define DMA_MODE_SRC_SA_BIT 0x01 -/* Two bits to select between all four modes */ -#define DMA_MODE_SSIZE_MASK 0x06 -/* Offset to shift bits in */ -#define DMA_MODE_SSIZE_OFF 0x01 -/* Destination static-address mode */ -#define DMA_MODE_DES_SA_BIT 0x10 -/* Two bits to select between all four modes */ -#define DMA_MODE_DSIZE_MASK 0x60 -/* Offset to shift bits in */ -#define DMA_MODE_DSIZE_OFF 0x05 -/* Size modifiers */ -#define DMA_MODE_SIZE_LONG 0x00 -#define DMA_MODE_SIZE_BYTE 0x01 -#define DMA_MODE_SIZE_WORD 0x02 -#define DMA_MODE_SIZE_LINE 0x03 - -/* - * Aliases to help speed quick ports; these may be suboptimal, however. They - * do not include the SINGLE mode modifiers since the MCF5272 does not have a - * mode where the device is in control of its addressing. - */ - -/* I/O to memory, 8 bits, mode */ -#define DMA_MODE_READ ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) -/* memory to I/O, 8 bits, mode */ -#define DMA_MODE_WRITE ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) -/* I/O to memory, 16 bits, mode */ -#define DMA_MODE_READ_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) -/* memory to I/O, 16 bits, mode */ -#define DMA_MODE_WRITE_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) -/* I/O to memory, 32 bits, mode */ -#define DMA_MODE_READ_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) -/* memory to I/O, 32 bits, mode */ -#define DMA_MODE_WRITE_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) - -#endif /* !defined(CONFIG_M5272) */ - -#if !defined(CONFIG_M5272) -/* enable/disable a specific DMA channel */ -static __inline__ void enable_dma(unsigned int dmanr) -{ - volatile unsigned short *dmawp; - -#ifdef DMA_DEBUG - printk("enable_dma(dmanr=%d)\n", dmanr); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT; -} - -static __inline__ void disable_dma(unsigned int dmanr) -{ - volatile unsigned short *dmawp; - volatile unsigned char *dmapb; - -#ifdef DMA_DEBUG - printk("disable_dma(dmanr=%d)\n", dmanr); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - dmapb = (unsigned char *) dma_base_addr[dmanr]; - - /* Turn off external requests, and stop any DMA in progress */ - dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT; - dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE; -} - -/* - * Clear the 'DMA Pointer Flip Flop'. - * Write 0 for LSB/MSB, 1 for MSB/LSB access. - * Use this once to initialize the FF to a known state. - * After that, keep track of it. :-) - * --- In order to do that, the DMA routines below should --- - * --- only be used while interrupts are disabled! --- - * - * This is a NOP for ColdFire. Provide a stub for compatibility. - */ -static __inline__ void clear_dma_ff(unsigned int dmanr) -{ -} - -/* set mode (above) for a specific DMA channel */ -static __inline__ void set_dma_mode(unsigned int dmanr, char mode) -{ - - volatile unsigned char *dmabp; - volatile unsigned short *dmawp; - -#ifdef DMA_DEBUG - printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode); -#endif - - dmabp = (unsigned char *) dma_base_addr[dmanr]; - dmawp = (unsigned short *) dma_base_addr[dmanr]; - - // Clear config errors - dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE; - - // Set command register - dmawp[MCFDMA_DCR] = - MCFDMA_DCR_INT | // Enable completion irq - MCFDMA_DCR_CS | // Force one xfer per request - MCFDMA_DCR_AA | // Enable auto alignment - // single-address-mode - ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) | - // sets s_rw (-> r/w) high if Memory to I/0 - ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) | - // Memory to I/O or I/O to Memory - ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) | - // 32 bit, 16 bit or 8 bit transfers - ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_SSIZE_WORD : - ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG : - MCFDMA_DCR_SSIZE_BYTE)) | - ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_DSIZE_WORD : - ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG : - MCFDMA_DCR_DSIZE_BYTE)); - -#ifdef DEBUG_DMA - printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__, - dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR], - (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]); -#endif -} - -/* Set transfer address for specific DMA channel */ -static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) -{ - volatile unsigned short *dmawp; - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - dmalp = (unsigned int *) dma_base_addr[dmanr]; - - // Determine which address registers are used for memory/device accesses - if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) { - // Source incrementing, must be memory - dmalp[MCFDMA_SAR] = a; - // Set dest address, must be device - dmalp[MCFDMA_DAR] = dma_device_address[dmanr]; - } else { - // Destination incrementing, must be memory - dmalp[MCFDMA_DAR] = a; - // Set source address, must be device - dmalp[MCFDMA_SAR] = dma_device_address[dmanr]; - } - -#ifdef DEBUG_DMA - printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n", - __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR], - (int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR], - (int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]); -#endif -} - -/* - * Specific for Coldfire - sets device address. - * Should be called after the mode set call, and before set DMA address. - */ -static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a) -{ -#ifdef DMA_DEBUG - printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a); -#endif - - dma_device_address[dmanr] = a; -} - -/* - * NOTE 2: "count" represents _bytes_. - */ -static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) -{ - volatile unsigned short *dmawp; - -#ifdef DMA_DEBUG - printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - dmawp[MCFDMA_BCR] = (unsigned short)count; -} - -/* - * Get DMA residue count. After a DMA transfer, this - * should return zero. Reading this while a DMA transfer is - * still in progress will return unpredictable results. - * Otherwise, it returns the number of _bytes_ left to transfer. - */ -static __inline__ int get_dma_residue(unsigned int dmanr) -{ - volatile unsigned short *dmawp; - unsigned short count; - -#ifdef DMA_DEBUG - printk("get_dma_residue(dmanr=%d)\n", dmanr); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - count = dmawp[MCFDMA_BCR]; - return((int) count); -} -#else /* CONFIG_M5272 is defined */ - -/* - * The MCF5272 DMA controller is very different than the controller defined above - * in terms of register mapping. For instance, with the exception of the 16-bit - * interrupt register (IRQ#85, for reference), all of the registers are 32-bit. - * - * The big difference, however, is the lack of device-requested DMA. All modes - * are dual address transfer, and there is no 'device' setup or direction bit. - * You can DMA between a device and memory, between memory and memory, or even between - * two devices directly, with any combination of incrementing and non-incrementing - * addresses you choose. This puts a crimp in distinguishing between the 'device - * address' set up by set_dma_device_addr. - * - * Therefore, there are two options. One is to use set_dma_addr and set_dma_device_addr, - * which will act exactly as above in -- it will look to see if the source is set to - * autoincrement, and if so it will make the source use the set_dma_addr value and the - * destination the set_dma_device_addr value. Otherwise the source will be set to the - * set_dma_device_addr value and the destination will get the set_dma_addr value. - * - * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions - * and make it explicit. Depending on what you're doing, one of these two should work - * for you, but don't mix them in the same transfer setup. - */ - -/* enable/disable a specific DMA channel */ -static __inline__ void enable_dma(unsigned int dmanr) -{ - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("enable_dma(dmanr=%d)\n", dmanr); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN; -} - -static __inline__ void disable_dma(unsigned int dmanr) -{ - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("disable_dma(dmanr=%d)\n", dmanr); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - - /* Turn off external requests, and stop any DMA in progress */ - dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN; - dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; -} - -/* - * Clear the 'DMA Pointer Flip Flop'. - * Write 0 for LSB/MSB, 1 for MSB/LSB access. - * Use this once to initialize the FF to a known state. - * After that, keep track of it. :-) - * --- In order to do that, the DMA routines below should --- - * --- only be used while interrupts are disabled! --- - * - * This is a NOP for ColdFire. Provide a stub for compatibility. - */ -static __inline__ void clear_dma_ff(unsigned int dmanr) -{ -} - -/* set mode (above) for a specific DMA channel */ -static __inline__ void set_dma_mode(unsigned int dmanr, char mode) -{ - - volatile unsigned int *dmalp; - volatile unsigned short *dmawp; - -#ifdef DMA_DEBUG - printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode); -#endif - dmalp = (unsigned int *) dma_base_addr[dmanr]; - dmawp = (unsigned short *) dma_base_addr[dmanr]; - - // Clear config errors - dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; - - // Set command register - dmalp[MCFDMA_DMR] = - MCFDMA_DMR_RQM_DUAL | // Mandatory Request Mode setting - MCFDMA_DMR_DSTT_SD | // Set up addressing types; set to supervisor-data. - MCFDMA_DMR_SRCT_SD | // Set up addressing types; set to supervisor-data. - // source static-address-mode - ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) | - // dest static-address-mode - ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) | - // burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272 - (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) | - (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF); - - dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN; /* Enable completion interrupts */ - -#ifdef DEBUG_DMA - printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__, - dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR], - (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]); -#endif -} - -/* Set transfer address for specific DMA channel */ -static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) -{ - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - - // Determine which address registers are used for memory/device accesses - if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) { - // Source incrementing, must be memory - dmalp[MCFDMA_DSAR] = a; - // Set dest address, must be device - dmalp[MCFDMA_DDAR] = dma_device_address[dmanr]; - } else { - // Destination incrementing, must be memory - dmalp[MCFDMA_DDAR] = a; - // Set source address, must be device - dmalp[MCFDMA_DSAR] = dma_device_address[dmanr]; - } - -#ifdef DEBUG_DMA - printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n", - __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR], - (int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR], - (int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]); -#endif -} - -/* - * Specific for Coldfire - sets device address. - * Should be called after the mode set call, and before set DMA address. - */ -static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a) -{ -#ifdef DMA_DEBUG - printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a); -#endif - - dma_device_address[dmanr] = a; -} - -/* - * NOTE 2: "count" represents _bytes_. - * - * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value. - */ -static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) -{ - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - dmalp[MCFDMA_DBCR] = count; -} - -/* - * Get DMA residue count. After a DMA transfer, this - * should return zero. Reading this while a DMA transfer is - * still in progress will return unpredictable results. - * Otherwise, it returns the number of _bytes_ left to transfer. - */ -static __inline__ int get_dma_residue(unsigned int dmanr) -{ - volatile unsigned int *dmalp; - unsigned int count; - -#ifdef DMA_DEBUG - printk("get_dma_residue(dmanr=%d)\n", dmanr); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - count = dmalp[MCFDMA_DBCR]; - return(count); -} - -#endif /* !defined(CONFIG_M5272) */ -#endif /* CONFIG_COLDFIRE */ - -#define MAX_DMA_CHANNELS 8 - -/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k/coldfire and any - occurrence should be flagged as an error. */ -/* under 2.4 it is actually needed by the new bootmem allocator */ -#define MAX_DMA_ADDRESS PAGE_OFFSET - -/* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, const char *device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it again */ - -#endif /* _M68K_DMA_H */ diff --git a/arch/m68k/include/asm/elia.h b/arch/m68k/include/asm/elia.h deleted file mode 100644 index e037d4e2de3..00000000000 --- a/arch/m68k/include/asm/elia.h +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************/ - -/* - * elia.h -- Lineo (formerly Moreton Bay) eLIA platform support. - * - * (C) Copyright 1999-2000, Moreton Bay (www.moreton.com.au) - * (C) Copyright 1999-2000, Lineo (www.lineo.com) - */ - -/****************************************************************************/ -#ifndef elia_h -#define elia_h -/****************************************************************************/ - -#include <asm/coldfire.h> - -#ifdef CONFIG_eLIA - -/* - * The serial port DTR and DCD lines are also on the Parallel I/O - * as well, so define those too. - */ - -#define eLIA_DCD1 0x0001 -#define eLIA_DCD0 0x0002 -#define eLIA_DTR1 0x0004 -#define eLIA_DTR0 0x0008 - -#define eLIA_PCIRESET 0x0020 - -/* - * Kernel macros to set and unset the LEDs. - */ -#ifndef __ASSEMBLY__ -extern unsigned short ppdata; -#endif /* __ASSEMBLY__ */ - -#endif /* CONFIG_eLIA */ - -/****************************************************************************/ -#endif /* elia_h */ diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h new file mode 100644 index 00000000000..283214dc65a --- /dev/null +++ b/arch/m68k/include/asm/gpio.h @@ -0,0 +1,238 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. +*/ + +#ifndef coldfire_gpio_h +#define coldfire_gpio_h + +#include <linux/io.h> +#include <asm-generic/gpio.h> +#include <asm/coldfire.h> +#include <asm/mcfsim.h> + +/* + * The Freescale Coldfire family is quite varied in how they implement GPIO. + * Some parts have 8 bit ports, some have 16bit and some have 32bit; some have + * only one port, others have multiple ports; some have a single data latch + * for both input and output, others have a separate pin data register to read + * input; some require a read-modify-write access to change an output, others + * have set and clear registers for some of the outputs; Some have all the + * GPIOs in a single control area, others have some GPIOs implemented in + * different modules. + * + * This implementation attempts accomodate the differences while presenting + * a generic interface that will optimize to as few instructions as possible. + */ +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ + defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) + +/* These parts have GPIO organized by 8 bit ports */ + +#define MCFGPIO_PORTTYPE u8 +#define MCFGPIO_PORTSIZE 8 +#define mcfgpio_read(port) __raw_readb(port) +#define mcfgpio_write(data, port) __raw_writeb(data, port) + +#elif defined(CONFIG_M5307) || defined(CONFIG_M5407) || defined(CONFIG_M5272) + +/* These parts have GPIO organized by 16 bit ports */ + +#define MCFGPIO_PORTTYPE u16 +#define MCFGPIO_PORTSIZE 16 +#define mcfgpio_read(port) __raw_readw(port) +#define mcfgpio_write(data, port) __raw_writew(data, port) + +#elif defined(CONFIG_M5249) + +/* These parts have GPIO organized by 32 bit ports */ + +#define MCFGPIO_PORTTYPE u32 +#define MCFGPIO_PORTSIZE 32 +#define mcfgpio_read(port) __raw_readl(port) +#define mcfgpio_write(data, port) __raw_writel(data, port) + +#endif + +#define mcfgpio_bit(gpio) (1 << ((gpio) % MCFGPIO_PORTSIZE)) +#define mcfgpio_port(gpio) ((gpio) / MCFGPIO_PORTSIZE) + +#if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) +/* + * These parts have an 'Edge' Port module (external interrupt/GPIO) which uses + * read-modify-write to change an output and a GPIO module which has separate + * set/clr registers to directly change outputs with a single write access. + */ +#if defined(CONFIG_M528x) +/* + * The 528x also has GPIOs in other modules (GPT, QADC) which use + * read-modify-write as well as those controlled by the EPORT and GPIO modules. + */ +#define MCFGPIO_SCR_START 40 +#else +#define MCFGPIO_SCR_START 8 +#endif + +#define MCFGPIO_SETR_PORT(gpio) (MCFGPIO_SETR + \ + mcfgpio_port(gpio - MCFGPIO_SCR_START)) + +#define MCFGPIO_CLRR_PORT(gpio) (MCFGPIO_CLRR + \ + mcfgpio_port(gpio - MCFGPIO_SCR_START)) +#else + +#define MCFGPIO_SCR_START MCFGPIO_PIN_MAX +/* with MCFGPIO_SCR == MCFGPIO_PIN_MAX, these will be optimized away */ +#define MCFGPIO_SETR_PORT(gpio) 0 +#define MCFGPIO_CLRR_PORT(gpio) 0 + +#endif +/* + * Coldfire specific helper functions + */ + +/* return the port pin data register for a gpio */ +static inline u32 __mcf_gpio_ppdr(unsigned gpio) +{ +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ + defined(CONFIG_M5307) || defined(CONFIG_M5407) + return MCFSIM_PADAT; +#elif defined(CONFIG_M5272) + if (gpio < 16) + return MCFSIM_PADAT; + else if (gpio < 32) + return MCFSIM_PBDAT; + else + return MCFSIM_PCDAT; +#elif defined(CONFIG_M5249) + if (gpio < 32) + return MCFSIM2_GPIOREAD; + else + return MCFSIM2_GPIO1READ; +#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) + if (gpio < 8) + return MCFEPORT_EPPDR; +#if defined(CONFIG_M528x) + else if (gpio < 16) + return MCFGPTA_GPTPORT; + else if (gpio < 24) + return MCFGPTB_GPTPORT; + else if (gpio < 32) + return MCFQADC_PORTQA; + else if (gpio < 40) + return MCFQADC_PORTQB; +#endif + else + return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START); +#endif +} + +/* return the port output data register for a gpio */ +static inline u32 __mcf_gpio_podr(unsigned gpio) +{ +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ + defined(CONFIG_M5307) || defined(CONFIG_M5407) + return MCFSIM_PADAT; +#elif defined(CONFIG_M5272) + if (gpio < 16) + return MCFSIM_PADAT; + else if (gpio < 32) + return MCFSIM_PBDAT; + else + return MCFSIM_PCDAT; +#elif defined(CONFIG_M5249) + if (gpio < 32) + return MCFSIM2_GPIOWRITE; + else + return MCFSIM2_GPIO1WRITE; +#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) + if (gpio < 8) + return MCFEPORT_EPDR; +#if defined(CONFIG_M528x) + else if (gpio < 16) + return MCFGPTA_GPTPORT; + else if (gpio < 24) + return MCFGPTB_GPTPORT; + else if (gpio < 32) + return MCFQADC_PORTQA; + else if (gpio < 40) + return MCFQADC_PORTQB; +#endif + else + return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START); +#endif +} + +/* + * The Generic GPIO functions + * + * If the gpio is a compile time constant and is one of the Coldfire gpios, + * use the inline version, otherwise dispatch thru gpiolib. + */ + +static inline int gpio_get_value(unsigned gpio) +{ + if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) + return mcfgpio_read(__mcf_gpio_ppdr(gpio)) & mcfgpio_bit(gpio); + else + return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) { + if (gpio < MCFGPIO_SCR_START) { + unsigned long flags; + MCFGPIO_PORTTYPE data; + + local_irq_save(flags); + data = mcfgpio_read(__mcf_gpio_podr(gpio)); + if (value) + data |= mcfgpio_bit(gpio); + else + data &= ~mcfgpio_bit(gpio); + mcfgpio_write(data, __mcf_gpio_podr(gpio)); + local_irq_restore(flags); + } else { + if (value) + mcfgpio_write(mcfgpio_bit(gpio), + MCFGPIO_SETR_PORT(gpio)); + else + mcfgpio_write(~mcfgpio_bit(gpio), + MCFGPIO_CLRR_PORT(gpio)); + } + } else + __gpio_set_value(gpio, value); +} + +static inline int gpio_to_irq(unsigned gpio) +{ + return (gpio < MCFGPIO_IRQ_MAX) ? gpio + MCFGPIO_IRQ_VECBASE : -EINVAL; +} + +static inline int irq_to_gpio(unsigned irq) +{ + return (irq >= MCFGPIO_IRQ_VECBASE && + irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) ? + irq - MCFGPIO_IRQ_VECBASE : -ENXIO; +} + +static inline int gpio_cansleep(unsigned gpio) +{ + return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio); +} + +#endif diff --git a/arch/m68k/include/asm/hardirq_no.h b/arch/m68k/include/asm/hardirq_no.h index bfad28149a4..b44b14be87d 100644 --- a/arch/m68k/include/asm/hardirq_no.h +++ b/arch/m68k/include/asm/hardirq_no.h @@ -1,16 +1,8 @@ #ifndef __M68K_HARDIRQ_H #define __M68K_HARDIRQ_H -#include <linux/cache.h> -#include <linux/threads.h> #include <asm/irq.h> -typedef struct { - unsigned int __softirq_pending; -} ____cacheline_aligned irq_cpustat_t; - -#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ - #define HARDIRQ_BITS 8 /* @@ -22,6 +14,6 @@ typedef struct { # error HARDIRQ_BITS is too low! #endif -void ack_bad_irq(unsigned int irq); +#include <asm-generic/hardirq.h> #endif /* __M68K_HARDIRQ_H */ diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index 6adef1ee208..7f57436ec18 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -134,7 +134,7 @@ static inline void io_insl(unsigned int addr, void *buf, int len) #define insw(a,b,l) io_insw(a,b,l) #define insl(a,b,l) io_insl(a,b,l) -#define IO_SPACE_LIMIT 0xffff +#define IO_SPACE_LIMIT 0xffffffff /* Values for nocacheflag and cmode */ diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index d031416595b..907eff1edd2 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -1,5 +1,134 @@ -#ifdef __uClinux__ -#include "irq_no.h" +#ifndef _M68K_IRQ_H_ +#define _M68K_IRQ_H_ + +/* + * This should be the same as the max(NUM_X_SOURCES) for all the + * different m68k hosts compiled into the kernel. + * Currently the Atari has 72 and the Amiga 24, but if both are + * supported in the kernel it is better to make room for 72. + */ +#if defined(CONFIG_COLDFIRE) +#define NR_IRQS 256 +#elif defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X) +#define NR_IRQS 200 +#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) +#define NR_IRQS 72 +#elif defined(CONFIG_Q40) +#define NR_IRQS 43 +#elif defined(CONFIG_AMIGA) || !defined(CONFIG_MMU) +#define NR_IRQS 32 +#elif defined(CONFIG_APOLLO) +#define NR_IRQS 24 +#elif defined(CONFIG_HP300) +#define NR_IRQS 8 #else -#include "irq_mm.h" +#define NR_IRQS 0 #endif + +#ifdef CONFIG_MMU + +#include <linux/linkage.h> +#include <linux/hardirq.h> +#include <linux/irqreturn.h> +#include <linux/spinlock_types.h> + +/* + * The hardirq mask has to be large enough to have + * space for potentially all IRQ sources in the system + * nesting on a single CPU: + */ +#if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +#endif + +/* + * Interrupt source definitions + * General interrupt sources are the level 1-7. + * Adding an interrupt service routine for one of these sources + * results in the addition of that routine to a chain of routines. + * Each one is called in succession. Each individual interrupt + * service routine should determine if the device associated with + * that routine requires service. + */ + +#define IRQ_SPURIOUS 0 + +#define IRQ_AUTO_1 1 /* level 1 interrupt */ +#define IRQ_AUTO_2 2 /* level 2 interrupt */ +#define IRQ_AUTO_3 3 /* level 3 interrupt */ +#define IRQ_AUTO_4 4 /* level 4 interrupt */ +#define IRQ_AUTO_5 5 /* level 5 interrupt */ +#define IRQ_AUTO_6 6 /* level 6 interrupt */ +#define IRQ_AUTO_7 7 /* level 7 interrupt (non-maskable) */ + +#define IRQ_USER 8 + +extern unsigned int irq_canonicalize(unsigned int irq); + +struct pt_regs; + +/* + * various flags for request_irq() - the Amiga now uses the standard + * mechanism like all other architectures - IRQF_DISABLED and + * IRQF_SHARED are your friends. + */ +#ifndef MACH_AMIGA_ONLY +#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */ +#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */ +#define IRQ_FLG_FAST (0x0004) +#define IRQ_FLG_SLOW (0x0008) +#define IRQ_FLG_STD (0x8000) /* internally used */ +#endif + +/* + * This structure is used to chain together the ISRs for a particular + * interrupt source (if it supports chaining). + */ +typedef struct irq_node { + irqreturn_t (*handler)(int, void *); + void *dev_id; + struct irq_node *next; + unsigned long flags; + const char *devname; +} irq_node_t; + +/* + * This structure has only 4 elements for speed reasons + */ +struct irq_handler { + int (*handler)(int, void *); + unsigned long flags; + void *dev_id; + const char *devname; +}; + +struct irq_controller { + const char *name; + spinlock_t lock; + int (*startup)(unsigned int irq); + void (*shutdown)(unsigned int irq); + void (*enable)(unsigned int irq); + void (*disable)(unsigned int irq); +}; + +extern int m68k_irq_startup(unsigned int); +extern void m68k_irq_shutdown(unsigned int); + +/* + * This function returns a new irq_node_t + */ +extern irq_node_t *new_irq_node(void); + +extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); +extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, + void (*handler)(unsigned int, struct pt_regs *)); +extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int); + +asmlinkage void m68k_handle_int(unsigned int); +asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *); + +#else +#define irq_canonicalize(irq) (irq) +#endif /* CONFIG_MMU */ + +#endif /* _M68K_IRQ_H_ */ diff --git a/arch/m68k/include/asm/irq_mm.h b/arch/m68k/include/asm/irq_mm.h deleted file mode 100644 index 0cab42cad79..00000000000 --- a/arch/m68k/include/asm/irq_mm.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef _M68K_IRQ_H_ -#define _M68K_IRQ_H_ - -#include <linux/linkage.h> -#include <linux/hardirq.h> -#include <linux/irqreturn.h> -#include <linux/spinlock_types.h> - -/* - * This should be the same as the max(NUM_X_SOURCES) for all the - * different m68k hosts compiled into the kernel. - * Currently the Atari has 72 and the Amiga 24, but if both are - * supported in the kernel it is better to make room for 72. - */ -#if defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X) -#define NR_IRQS 200 -#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) -#define NR_IRQS 72 -#elif defined(CONFIG_Q40) -#define NR_IRQS 43 -#elif defined(CONFIG_AMIGA) -#define NR_IRQS 32 -#elif defined(CONFIG_APOLLO) -#define NR_IRQS 24 -#elif defined(CONFIG_HP300) -#define NR_IRQS 8 -#else -#define NR_IRQS 0 -#endif - -/* - * The hardirq mask has to be large enough to have - * space for potentially all IRQ sources in the system - * nesting on a single CPU: - */ -#if (1 << HARDIRQ_BITS) < NR_IRQS -# error HARDIRQ_BITS is too low! -#endif - -/* - * Interrupt source definitions - * General interrupt sources are the level 1-7. - * Adding an interrupt service routine for one of these sources - * results in the addition of that routine to a chain of routines. - * Each one is called in succession. Each individual interrupt - * service routine should determine if the device associated with - * that routine requires service. - */ - -#define IRQ_SPURIOUS 0 - -#define IRQ_AUTO_1 1 /* level 1 interrupt */ -#define IRQ_AUTO_2 2 /* level 2 interrupt */ -#define IRQ_AUTO_3 3 /* level 3 interrupt */ -#define IRQ_AUTO_4 4 /* level 4 interrupt */ -#define IRQ_AUTO_5 5 /* level 5 interrupt */ -#define IRQ_AUTO_6 6 /* level 6 interrupt */ -#define IRQ_AUTO_7 7 /* level 7 interrupt (non-maskable) */ - -#define IRQ_USER 8 - -extern unsigned int irq_canonicalize(unsigned int irq); - -struct pt_regs; - -/* - * various flags for request_irq() - the Amiga now uses the standard - * mechanism like all other architectures - IRQF_DISABLED and - * IRQF_SHARED are your friends. - */ -#ifndef MACH_AMIGA_ONLY -#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */ -#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */ -#define IRQ_FLG_FAST (0x0004) -#define IRQ_FLG_SLOW (0x0008) -#define IRQ_FLG_STD (0x8000) /* internally used */ -#endif - -/* - * This structure is used to chain together the ISRs for a particular - * interrupt source (if it supports chaining). - */ -typedef struct irq_node { - irqreturn_t (*handler)(int, void *); - void *dev_id; - struct irq_node *next; - unsigned long flags; - const char *devname; -} irq_node_t; - -/* - * This structure has only 4 elements for speed reasons - */ -struct irq_handler { - int (*handler)(int, void *); - unsigned long flags; - void *dev_id; - const char *devname; -}; - -struct irq_controller { - const char *name; - spinlock_t lock; - int (*startup)(unsigned int irq); - void (*shutdown)(unsigned int irq); - void (*enable)(unsigned int irq); - void (*disable)(unsigned int irq); -}; - -extern int m68k_irq_startup(unsigned int); -extern void m68k_irq_shutdown(unsigned int); - -/* - * This function returns a new irq_node_t - */ -extern irq_node_t *new_irq_node(void); - -extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); -extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, - void (*handler)(unsigned int, struct pt_regs *)); -extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int); - -asmlinkage void m68k_handle_int(unsigned int); -asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *); - -#endif /* _M68K_IRQ_H_ */ diff --git a/arch/m68k/include/asm/irq_no.h b/arch/m68k/include/asm/irq_no.h deleted file mode 100644 index 9373c31ac87..00000000000 --- a/arch/m68k/include/asm/irq_no.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _M68KNOMMU_IRQ_H_ -#define _M68KNOMMU_IRQ_H_ - -#ifdef CONFIG_COLDFIRE -/* - * On the ColdFire we keep track of all vectors. That way drivers - * can register whatever vector number they wish, and we can deal - * with it. - */ -#define SYS_IRQS 256 -#define NR_IRQS SYS_IRQS - -#else - -/* - * # of m68k interrupts - */ -#define SYS_IRQS 8 -#define NR_IRQS (24 + SYS_IRQS) - -#endif /* CONFIG_COLDFIRE */ - - -#define irq_canonicalize(irq) (irq) - -#endif /* _M68KNOMMU_IRQ_H_ */ diff --git a/arch/m68k/include/asm/m5206sim.h b/arch/m68k/include/asm/m5206sim.h index 7e3594dea88..9c384e294af 100644 --- a/arch/m68k/include/asm/m5206sim.h +++ b/arch/m68k/include/asm/m5206sim.h @@ -85,8 +85,21 @@ #define MCFSIM_PAR 0xcb /* Pin Assignment reg (r/w) */ #endif -#define MCFSIM_PADDR 0x1c5 /* Parallel Direction (r/w) */ -#define MCFSIM_PADAT 0x1c9 /* Parallel Port Value (r/w) */ +#define MCFSIM_PADDR (MCF_MBAR + 0x1c5) /* Parallel Direction (r/w) */ +#define MCFSIM_PADAT (MCF_MBAR + 0x1c9) /* Parallel Port Value (r/w) */ + +/* + * Define system peripheral IRQ usage. + */ +#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */ +#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */ + +/* + * Generic GPIO + */ +#define MCFGPIO_PIN_MAX 8 +#define MCFGPIO_IRQ_VECBASE -1 +#define MCFGPIO_IRQ_MAX -1 /* * Some symbol defines for the Parallel Port Pin Assignment Register @@ -111,21 +124,5 @@ #define MCFSIM_DMA2ICR MCFSIM_ICR15 /* DMA 2 ICR */ #endif -#if defined(CONFIG_M5206e) -#define MCFSIM_IMR_MASKALL 0xfffe /* All SIM intr sources */ -#endif - -/* - * Macro to get and set IMR register. It is 16 bits on the 5206. - */ -#define mcf_getimr() \ - *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR)) = (imr) - -#define mcf_getipr() \ - *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IPR)) - /****************************************************************************/ #endif /* m5206sim_h */ diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h index 83bbcfd6e8f..ed2b69b9680 100644 --- a/arch/m68k/include/asm/m520xsim.h +++ b/arch/m68k/include/asm/m520xsim.h @@ -11,9 +11,8 @@ #define m520xsim_h /****************************************************************************/ - /* - * Define the 5282 SIM register set addresses. + * Define the 520x SIM register set addresses. */ #define MCFICM_INTC0 0x48000 /* Base for Interrupt Ctrl 0 */ #define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */ @@ -22,8 +21,22 @@ #define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */ #define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */ #define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */ +#define MCFINTC_SIMR 0x1c /* Set interrupt mask 0-63 */ +#define MCFINTC_CIMR 0x1d /* Clear interrupt mask 0-63 */ #define MCFINTC_ICR0 0x40 /* Base ICR register */ +/* + * The common interrupt controller code just wants to know the absolute + * address to the SIMR and CIMR registers (not offsets into IPSBAR). + * The 520x family only has a single INTC unit. + */ +#define MCFINTC0_SIMR (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_SIMR) +#define MCFINTC0_CIMR (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_CIMR) +#define MCFINTC0_ICR0 (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0) +#define MCFINTC1_SIMR (0) +#define MCFINTC1_CIMR (0) +#define MCFINTC1_ICR0 (0) + #define MCFINT_VECBASE 64 #define MCFINT_UART0 26 /* Interrupt number for UART0 */ #define MCFINT_UART1 27 /* Interrupt number for UART1 */ @@ -41,6 +54,62 @@ #define MCFSIM_SDCS0 0x000a8110 /* SDRAM Chip Select 0 Configuration */ #define MCFSIM_SDCS1 0x000a8114 /* SDRAM Chip Select 1 Configuration */ +#define MCFEPORT_EPDDR 0xFC088002 +#define MCFEPORT_EPDR 0xFC088004 +#define MCFEPORT_EPPDR 0xFC088005 + +#define MCFGPIO_PODR_BUSCTL 0xFC0A4000 +#define MCFGPIO_PODR_BE 0xFC0A4001 +#define MCFGPIO_PODR_CS 0xFC0A4002 +#define MCFGPIO_PODR_FECI2C 0xFC0A4003 +#define MCFGPIO_PODR_QSPI 0xFC0A4004 +#define MCFGPIO_PODR_TIMER 0xFC0A4005 +#define MCFGPIO_PODR_UART 0xFC0A4006 +#define MCFGPIO_PODR_FECH 0xFC0A4007 +#define MCFGPIO_PODR_FECL 0xFC0A4008 + +#define MCFGPIO_PDDR_BUSCTL 0xFC0A400C +#define MCFGPIO_PDDR_BE 0xFC0A400D +#define MCFGPIO_PDDR_CS 0xFC0A400E +#define MCFGPIO_PDDR_FECI2C 0xFC0A400F +#define MCFGPIO_PDDR_QSPI 0xFC0A4010 +#define MCFGPIO_PDDR_TIMER 0xFC0A4011 +#define MCFGPIO_PDDR_UART 0xFC0A4012 +#define MCFGPIO_PDDR_FECH 0xFC0A4013 +#define MCFGPIO_PDDR_FECL 0xFC0A4014 + +#define MCFGPIO_PPDSDR_BUSCTL 0xFC0A401A +#define MCFGPIO_PPDSDR_BE 0xFC0A401B +#define MCFGPIO_PPDSDR_CS 0xFC0A401C +#define MCFGPIO_PPDSDR_FECI2C 0xFC0A401D +#define MCFGPIO_PPDSDR_QSPI 0xFC0A401E +#define MCFGPIO_PPDSDR_TIMER 0xFC0A401F +#define MCFGPIO_PPDSDR_UART 0xFC0A4021 +#define MCFGPIO_PPDSDR_FECH 0xFC0A4021 +#define MCFGPIO_PPDSDR_FECL 0xFC0A4022 + +#define MCFGPIO_PCLRR_BUSCTL 0xFC0A4024 +#define MCFGPIO_PCLRR_BE 0xFC0A4025 +#define MCFGPIO_PCLRR_CS 0xFC0A4026 +#define MCFGPIO_PCLRR_FECI2C 0xFC0A4027 +#define MCFGPIO_PCLRR_QSPI 0xFC0A4028 +#define MCFGPIO_PCLRR_TIMER 0xFC0A4029 +#define MCFGPIO_PCLRR_UART 0xFC0A402A +#define MCFGPIO_PCLRR_FECH 0xFC0A402B +#define MCFGPIO_PCLRR_FECL 0xFC0A402C +/* + * Generic GPIO support + */ +#define MCFGPIO_PODR MCFGPIO_PODR_BUSCTL +#define MCFGPIO_PDDR MCFGPIO_PDDR_BUSCTL +#define MCFGPIO_PPDR MCFGPIO_PPDSDR_BUSCTL +#define MCFGPIO_SETR MCFGPIO_PPDSDR_BUSCTL +#define MCFGPIO_CLRR MCFGPIO_PCLRR_BUSCTL + +#define MCFGPIO_PIN_MAX 80 +#define MCFGPIO_IRQ_MAX 8 +#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE +/****************************************************************************/ #define MCF_GPIO_PAR_UART (0xA4036) #define MCF_GPIO_PAR_FECI2C (0xA4033) @@ -55,10 +124,6 @@ #define MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2 (0x02) #define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 (0x04) -#define ICR_INTRCONF 0x05 -#define MCFPIT_IMR MCFINTC_IMRL -#define MCFPIT_IMR_IBIT (1 << MCFINT_PIT1) - /* * Reset Controll Unit. */ diff --git a/arch/m68k/include/asm/m523xsim.h b/arch/m68k/include/asm/m523xsim.h index 55183b5df1b..a34894cf8e6 100644 --- a/arch/m68k/include/asm/m523xsim.h +++ b/arch/m68k/include/asm/m523xsim.h @@ -50,5 +50,82 @@ #define MCF_RCR_SWRESET 0x80 /* Software reset bit */ #define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */ +#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000) +#define MCFGPIO_PODR_DATAH (MCF_IPSBAR + 0x100001) +#define MCFGPIO_PODR_DATAL (MCF_IPSBAR + 0x100002) +#define MCFGPIO_PODR_BUSCTL (MCF_IPSBAR + 0x100003) +#define MCFGPIO_PODR_BS (MCF_IPSBAR + 0x100004) +#define MCFGPIO_PODR_CS (MCF_IPSBAR + 0x100005) +#define MCFGPIO_PODR_SDRAM (MCF_IPSBAR + 0x100006) +#define MCFGPIO_PODR_FECI2C (MCF_IPSBAR + 0x100007) +#define MCFGPIO_PODR_UARTH (MCF_IPSBAR + 0x100008) +#define MCFGPIO_PODR_UARTL (MCF_IPSBAR + 0x100009) +#define MCFGPIO_PODR_QSPI (MCF_IPSBAR + 0x10000A) +#define MCFGPIO_PODR_TIMER (MCF_IPSBAR + 0x10000B) +#define MCFGPIO_PODR_ETPU (MCF_IPSBAR + 0x10000C) + +#define MCFGPIO_PDDR_ADDR (MCF_IPSBAR + 0x100010) +#define MCFGPIO_PDDR_DATAH (MCF_IPSBAR + 0x100011) +#define MCFGPIO_PDDR_DATAL (MCF_IPSBAR + 0x100012) +#define MCFGPIO_PDDR_BUSCTL (MCF_IPSBAR + 0x100013) +#define MCFGPIO_PDDR_BS (MCF_IPSBAR + 0x100014) +#define MCFGPIO_PDDR_CS (MCF_IPSBAR + 0x100015) +#define MCFGPIO_PDDR_SDRAM (MCF_IPSBAR + 0x100016) +#define MCFGPIO_PDDR_FECI2C (MCF_IPSBAR + 0x100017) +#define MCFGPIO_PDDR_UARTH (MCF_IPSBAR + 0x100018) +#define MCFGPIO_PDDR_UARTL (MCF_IPSBAR + 0x100019) +#define MCFGPIO_PDDR_QSPI (MCF_IPSBAR + 0x10001A) +#define MCFGPIO_PDDR_TIMER (MCF_IPSBAR + 0x10001B) +#define MCFGPIO_PDDR_ETPU (MCF_IPSBAR + 0x10001C) + +#define MCFGPIO_PPDSDR_ADDR (MCF_IPSBAR + 0x100020) +#define MCFGPIO_PPDSDR_DATAH (MCF_IPSBAR + 0x100021) +#define MCFGPIO_PPDSDR_DATAL (MCF_IPSBAR + 0x100022) +#define MCFGPIO_PPDSDR_BUSCTL (MCF_IPSBAR + 0x100023) +#define MCFGPIO_PPDSDR_BS (MCF_IPSBAR + 0x100024) +#define MCFGPIO_PPDSDR_CS (MCF_IPSBAR + 0x100025) +#define MCFGPIO_PPDSDR_SDRAM (MCF_IPSBAR + 0x100026) +#define MCFGPIO_PPDSDR_FECI2C (MCF_IPSBAR + 0x100027) +#define MCFGPIO_PPDSDR_UARTH (MCF_IPSBAR + 0x100028) +#define MCFGPIO_PPDSDR_UARTL (MCF_IPSBAR + 0x100029) +#define MCFGPIO_PPDSDR_QSPI (MCF_IPSBAR + 0x10002A) +#define MCFGPIO_PPDSDR_TIMER (MCF_IPSBAR + 0x10002B) +#define MCFGPIO_PPDSDR_ETPU (MCF_IPSBAR + 0x10002C) + +#define MCFGPIO_PCLRR_ADDR (MCF_IPSBAR + 0x100030) +#define MCFGPIO_PCLRR_DATAH (MCF_IPSBAR + 0x100031) +#define MCFGPIO_PCLRR_DATAL (MCF_IPSBAR + 0x100032) +#define MCFGPIO_PCLRR_BUSCTL (MCF_IPSBAR + 0x100033) +#define MCFGPIO_PCLRR_BS (MCF_IPSBAR + 0x100034) +#define MCFGPIO_PCLRR_CS (MCF_IPSBAR + 0x100035) +#define MCFGPIO_PCLRR_SDRAM (MCF_IPSBAR + 0x100036) +#define MCFGPIO_PCLRR_FECI2C (MCF_IPSBAR + 0x100037) +#define MCFGPIO_PCLRR_UARTH (MCF_IPSBAR + 0x100038) +#define MCFGPIO_PCLRR_UARTL (MCF_IPSBAR + 0x100039) +#define MCFGPIO_PCLRR_QSPI (MCF_IPSBAR + 0x10003A) +#define MCFGPIO_PCLRR_TIMER (MCF_IPSBAR + 0x10003B) +#define MCFGPIO_PCLRR_ETPU (MCF_IPSBAR + 0x10003C) + +/* + * EPort + */ + +#define MCFEPORT_EPDDR (MCF_IPSBAR + 0x130002) +#define MCFEPORT_EPDR (MCF_IPSBAR + 0x130004) +#define MCFEPORT_EPPDR (MCF_IPSBAR + 0x130005) + +/* + * Generic GPIO support + */ +#define MCFGPIO_PODR MCFGPIO_PODR_ADDR +#define MCFGPIO_PDDR MCFGPIO_PDDR_ADDR +#define MCFGPIO_PPDR MCFGPIO_PPDSDR_ADDR +#define MCFGPIO_SETR MCFGPIO_PPDSDR_ADDR +#define MCFGPIO_CLRR MCFGPIO_PCLRR_ADDR + +#define MCFGPIO_PIN_MAX 107 +#define MCFGPIO_IRQ_MAX 8 +#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE + /****************************************************************************/ #endif /* m523xsim_h */ diff --git a/arch/m68k/include/asm/m5249sim.h b/arch/m68k/include/asm/m5249sim.h index 366eb8602d2..14bce877ed8 100644 --- a/arch/m68k/include/asm/m5249sim.h +++ b/arch/m68k/include/asm/m5249sim.h @@ -71,16 +71,22 @@ #define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ /* + * Define system peripheral IRQ usage. + */ +#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */ +#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */ + +/* * General purpose IO registers (in MBAR2). */ -#define MCFSIM2_GPIOREAD 0x0 /* GPIO read values */ -#define MCFSIM2_GPIOWRITE 0x4 /* GPIO write values */ -#define MCFSIM2_GPIOENABLE 0x8 /* GPIO enabled */ -#define MCFSIM2_GPIOFUNC 0xc /* GPIO function */ -#define MCFSIM2_GPIO1READ 0xb0 /* GPIO1 read values */ -#define MCFSIM2_GPIO1WRITE 0xb4 /* GPIO1 write values */ -#define MCFSIM2_GPIO1ENABLE 0xb8 /* GPIO1 enabled */ -#define MCFSIM2_GPIO1FUNC 0xbc /* GPIO1 function */ +#define MCFSIM2_GPIOREAD (MCF_MBAR2 + 0x000) /* GPIO read values */ +#define MCFSIM2_GPIOWRITE (MCF_MBAR2 + 0x004) /* GPIO write values */ +#define MCFSIM2_GPIOENABLE (MCF_MBAR2 + 0x008) /* GPIO enabled */ +#define MCFSIM2_GPIOFUNC (MCF_MBAR2 + 0x00C) /* GPIO function */ +#define MCFSIM2_GPIO1READ (MCF_MBAR2 + 0x0B0) /* GPIO1 read values */ +#define MCFSIM2_GPIO1WRITE (MCF_MBAR2 + 0x0B4) /* GPIO1 write values */ +#define MCFSIM2_GPIO1ENABLE (MCF_MBAR2 + 0x0B8) /* GPIO1 enabled */ +#define MCFSIM2_GPIO1FUNC (MCF_MBAR2 + 0x0BC) /* GPIO1 function */ #define MCFSIM2_GPIOINTSTAT 0xc0 /* GPIO interrupt status */ #define MCFSIM2_GPIOINTCLEAR 0xc0 /* GPIO interrupt clear */ @@ -100,20 +106,28 @@ #define MCFSIM2_IDECONFIG1 0x18c /* IDEconfig1 */ #define MCFSIM2_IDECONFIG2 0x190 /* IDEconfig2 */ - /* - * Macro to set IMR register. It is 32 bits on the 5249. + * Define the base interrupt for the second interrupt controller. + * We set it to 128, out of the way of the base interrupts, and plenty + * of room for its 64 interrupts. */ -#define MCFSIM_IMR_MASKALL 0x7fffe /* All SIM intr sources */ +#define MCFINTC2_VECBASE 128 -#define mcf_getimr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) +#define MCFINTC2_GPIOIRQ0 (MCFINTC2_VECBASE + 32) +#define MCFINTC2_GPIOIRQ1 (MCFINTC2_VECBASE + 33) +#define MCFINTC2_GPIOIRQ2 (MCFINTC2_VECBASE + 34) +#define MCFINTC2_GPIOIRQ3 (MCFINTC2_VECBASE + 35) +#define MCFINTC2_GPIOIRQ4 (MCFINTC2_VECBASE + 36) +#define MCFINTC2_GPIOIRQ5 (MCFINTC2_VECBASE + 37) +#define MCFINTC2_GPIOIRQ6 (MCFINTC2_VECBASE + 38) +#define MCFINTC2_GPIOIRQ7 (MCFINTC2_VECBASE + 39) -#define mcf_setimr(imr) \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); - -#define mcf_getipr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) +/* + * Generic GPIO support + */ +#define MCFGPIO_PIN_MAX 64 +#define MCFGPIO_IRQ_MAX -1 +#define MCFGPIO_IRQ_VECBASE -1 /****************************************************************************/ @@ -137,9 +151,9 @@ subql #1,%a1 /* get MBAR2 address in a1 */ /* - * Move secondary interrupts to base at 128. + * Move secondary interrupts to their base (128). */ - moveb #0x80,%d0 + moveb #MCFINTC2_VECBASE,%d0 moveb %d0,0x16b(%a1) /* interrupt base register */ /* diff --git a/arch/m68k/include/asm/m5272sim.h b/arch/m68k/include/asm/m5272sim.h index 6217edc2113..df3332c2317 100644 --- a/arch/m68k/include/asm/m5272sim.h +++ b/arch/m68k/include/asm/m5272sim.h @@ -12,7 +12,6 @@ #define m5272sim_h /****************************************************************************/ - /* * Define the 5272 SIM register set addresses. */ @@ -63,16 +62,59 @@ #define MCFSIM_DCMR1 0x5c /* DRAM 1 Mask reg (r/w) */ #define MCFSIM_DCCR1 0x63 /* DRAM 1 Control reg (r/w) */ -#define MCFSIM_PACNT 0x80 /* Port A Control (r/w) */ -#define MCFSIM_PADDR 0x84 /* Port A Direction (r/w) */ -#define MCFSIM_PADAT 0x86 /* Port A Data (r/w) */ -#define MCFSIM_PBCNT 0x88 /* Port B Control (r/w) */ -#define MCFSIM_PBDDR 0x8c /* Port B Direction (r/w) */ -#define MCFSIM_PBDAT 0x8e /* Port B Data (r/w) */ -#define MCFSIM_PCDDR 0x94 /* Port C Direction (r/w) */ -#define MCFSIM_PCDAT 0x96 /* Port C Data (r/w) */ -#define MCFSIM_PDCNT 0x98 /* Port D Control (r/w) */ +#define MCFSIM_PACNT (MCF_MBAR + 0x80) /* Port A Control (r/w) */ +#define MCFSIM_PADDR (MCF_MBAR + 0x84) /* Port A Direction (r/w) */ +#define MCFSIM_PADAT (MCF_MBAR + 0x86) /* Port A Data (r/w) */ +#define MCFSIM_PBCNT (MCF_MBAR + 0x88) /* Port B Control (r/w) */ +#define MCFSIM_PBDDR (MCF_MBAR + 0x8c) /* Port B Direction (r/w) */ +#define MCFSIM_PBDAT (MCF_MBAR + 0x8e) /* Port B Data (r/w) */ +#define MCFSIM_PCDDR (MCF_MBAR + 0x94) /* Port C Direction (r/w) */ +#define MCFSIM_PCDAT (MCF_MBAR + 0x96) /* Port C Data (r/w) */ +#define MCFSIM_PDCNT (MCF_MBAR + 0x98) /* Port D Control (r/w) */ + +/* + * Define system peripheral IRQ usage. + */ +#define MCFINT_VECBASE 64 /* Base of interrupts */ +#define MCF_IRQ_SPURIOUS 64 /* User Spurious */ +#define MCF_IRQ_EINT1 65 /* External Interrupt 1 */ +#define MCF_IRQ_EINT2 66 /* External Interrupt 2 */ +#define MCF_IRQ_EINT3 67 /* External Interrupt 3 */ +#define MCF_IRQ_EINT4 68 /* External Interrupt 4 */ +#define MCF_IRQ_TIMER1 69 /* Timer 1 */ +#define MCF_IRQ_TIMER2 70 /* Timer 2 */ +#define MCF_IRQ_TIMER3 71 /* Timer 3 */ +#define MCF_IRQ_TIMER4 72 /* Timer 4 */ +#define MCF_IRQ_UART1 73 /* UART 1 */ +#define MCF_IRQ_UART2 74 /* UART 2 */ +#define MCF_IRQ_PLIP 75 /* PLIC 2Khz Periodic */ +#define MCF_IRQ_PLIA 76 /* PLIC Asynchronous */ +#define MCF_IRQ_USB0 77 /* USB Endpoint 0 */ +#define MCF_IRQ_USB1 78 /* USB Endpoint 1 */ +#define MCF_IRQ_USB2 79 /* USB Endpoint 2 */ +#define MCF_IRQ_USB3 80 /* USB Endpoint 3 */ +#define MCF_IRQ_USB4 81 /* USB Endpoint 4 */ +#define MCF_IRQ_USB5 82 /* USB Endpoint 5 */ +#define MCF_IRQ_USB6 83 /* USB Endpoint 6 */ +#define MCF_IRQ_USB7 84 /* USB Endpoint 7 */ +#define MCF_IRQ_DMA 85 /* DMA Controller */ +#define MCF_IRQ_ERX 86 /* Ethernet Receiver */ +#define MCF_IRQ_ETX 87 /* Ethernet Transmitter */ +#define MCF_IRQ_ENTC 88 /* Ethernet Non-Time Critical */ +#define MCF_IRQ_QSPI 89 /* Queued Serial Interface */ +#define MCF_IRQ_EINT5 90 /* External Interrupt 5 */ +#define MCF_IRQ_EINT6 91 /* External Interrupt 6 */ +#define MCF_IRQ_SWTO 92 /* Software Watchdog */ +#define MCFINT_VECMAX 95 /* Maxmum interrupt */ +#define MCF_IRQ_TIMER MCF_IRQ_TIMER1 +#define MCF_IRQ_PROFILER MCF_IRQ_TIMER2 +/* + * Generic GPIO support + */ +#define MCFGPIO_PIN_MAX 48 +#define MCFGPIO_IRQ_MAX -1 +#define MCFGPIO_IRQ_VECBASE -1 /****************************************************************************/ #endif /* m5272sim_h */ diff --git a/arch/m68k/include/asm/m527xsim.h b/arch/m68k/include/asm/m527xsim.h index 95f4f8ee8f7..453356d72d8 100644 --- a/arch/m68k/include/asm/m527xsim.h +++ b/arch/m68k/include/asm/m527xsim.h @@ -54,6 +54,175 @@ #define MCFSIM_DMR1 0x5c /* SDRAM address mask 1 */ #endif + +#ifdef CONFIG_M5271 +#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000) +#define MCFGPIO_PODR_DATAH (MCF_IPSBAR + 0x100001) +#define MCFGPIO_PODR_DATAL (MCF_IPSBAR + 0x100002) +#define MCFGPIO_PODR_BUSCTL (MCF_IPSBAR + 0x100003) +#define MCFGPIO_PODR_BS (MCF_IPSBAR + 0x100004) +#define MCFGPIO_PODR_CS (MCF_IPSBAR + 0x100005) +#define MCFGPIO_PODR_SDRAM (MCF_IPSBAR + 0x100006) +#define MCFGPIO_PODR_FECI2C (MCF_IPSBAR + 0x100007) +#define MCFGPIO_PODR_UARTH (MCF_IPSBAR + 0x100008) +#define MCFGPIO_PODR_UARTL (MCF_IPSBAR + 0x100009) +#define MCFGPIO_PODR_QSPI (MCF_IPSBAR + 0x10000A) +#define MCFGPIO_PODR_TIMER (MCF_IPSBAR + 0x10000B) + +#define MCFGPIO_PDDR_ADDR (MCF_IPSBAR + 0x100010) +#define MCFGPIO_PDDR_DATAH (MCF_IPSBAR + 0x100011) +#define MCFGPIO_PDDR_DATAL (MCF_IPSBAR + 0x100012) +#define MCFGPIO_PDDR_BUSCTL (MCF_IPSBAR + 0x100013) +#define MCFGPIO_PDDR_BS (MCF_IPSBAR + 0x100014) +#define MCFGPIO_PDDR_CS (MCF_IPSBAR + 0x100015) +#define MCFGPIO_PDDR_SDRAM (MCF_IPSBAR + 0x100016) +#define MCFGPIO_PDDR_FECI2C (MCF_IPSBAR + 0x100017) +#define MCFGPIO_PDDR_UARTH (MCF_IPSBAR + 0x100018) +#define MCFGPIO_PDDR_UARTL (MCF_IPSBAR + 0x100019) +#define MCFGPIO_PDDR_QSPI (MCF_IPSBAR + 0x10001A) +#define MCFGPIO_PDDR_TIMER (MCF_IPSBAR + 0x10001B) + +#define MCFGPIO_PPDSDR_ADDR (MCF_IPSBAR + 0x100020) +#define MCFGPIO_PPDSDR_DATAH (MCF_IPSBAR + 0x100021) +#define MCFGPIO_PPDSDR_DATAL (MCF_IPSBAR + 0x100022) +#define MCFGPIO_PPDSDR_BUSCTL (MCF_IPSBAR + 0x100023) +#define MCFGPIO_PPDSDR_BS (MCF_IPSBAR + 0x100024) +#define MCFGPIO_PPDSDR_CS (MCF_IPSBAR + 0x100025) +#define MCFGPIO_PPDSDR_SDRAM (MCF_IPSBAR + 0x100026) +#define MCFGPIO_PPDSDR_FECI2C (MCF_IPSBAR + 0x100027) +#define MCFGPIO_PPDSDR_UARTH (MCF_IPSBAR + 0x100028) +#define MCFGPIO_PPDSDR_UARTL (MCF_IPSBAR + 0x100029) +#define MCFGPIO_PPDSDR_QSPI (MCF_IPSBAR + 0x10002A) +#define MCFGPIO_PPDSDR_TIMER (MCF_IPSBAR + 0x10002B) + +#define MCFGPIO_PCLRR_ADDR (MCF_IPSBAR + 0x100030) +#define MCFGPIO_PCLRR_DATAH (MCF_IPSBAR + 0x100031) +#define MCFGPIO_PCLRR_DATAL (MCF_IPSBAR + 0x100032) +#define MCFGPIO_PCLRR_BUSCTL (MCF_IPSBAR + 0x100033) +#define MCFGPIO_PCLRR_BS (MCF_IPSBAR + 0x100034) +#define MCFGPIO_PCLRR_CS (MCF_IPSBAR + 0x100035) +#define MCFGPIO_PCLRR_SDRAM (MCF_IPSBAR + 0x100036) +#define MCFGPIO_PCLRR_FECI2C (MCF_IPSBAR + 0x100037) +#define MCFGPIO_PCLRR_UARTH (MCF_IPSBAR + 0x100038) +#define MCFGPIO_PCLRR_UARTL (MCF_IPSBAR + 0x100039) +#define MCFGPIO_PCLRR_QSPI (MCF_IPSBAR + 0x10003A) +#define MCFGPIO_PCLRR_TIMER (MCF_IPSBAR + 0x10003B) + +/* + * Generic GPIO support + */ +#define MCFGPIO_PODR MCFGPIO_PODR_ADDR +#define MCFGPIO_PDDR MCFGPIO_PDDR_ADDR +#define MCFGPIO_PPDR MCFGPIO_PPDSDR_ADDR +#define MCFGPIO_SETR MCFGPIO_PPDSDR_ADDR +#define MCFGPIO_CLRR MCFGPIO_PCLRR_ADDR + +#define MCFGPIO_PIN_MAX 100 +#define MCFGPIO_IRQ_MAX 8 +#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE +#endif + +#ifdef CONFIG_M5275 +#define MCFGPIO_PODR_BUSCTL (MCF_IPSBAR + 0x100004) +#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100005) +#define MCFGPIO_PODR_CS (MCF_IPSBAR + 0x100008) +#define MCFGPIO_PODR_FEC0H (MCF_IPSBAR + 0x10000A) +#define MCFGPIO_PODR_FEC0L (MCF_IPSBAR + 0x10000B) +#define MCFGPIO_PODR_FECI2C (MCF_IPSBAR + 0x10000C) +#define MCFGPIO_PODR_QSPI (MCF_IPSBAR + 0x10000D) +#define MCFGPIO_PODR_SDRAM (MCF_IPSBAR + 0x10000E) +#define MCFGPIO_PODR_TIMERH (MCF_IPSBAR + 0x10000F) +#define MCFGPIO_PODR_TIMERL (MCF_IPSBAR + 0x100010) +#define MCFGPIO_PODR_UARTL (MCF_IPSBAR + 0x100011) +#define MCFGPIO_PODR_FEC1H (MCF_IPSBAR + 0x100012) +#define MCFGPIO_PODR_FEC1L (MCF_IPSBAR + 0x100013) +#define MCFGPIO_PODR_BS (MCF_IPSBAR + 0x100014) +#define MCFGPIO_PODR_IRQ (MCF_IPSBAR + 0x100015) +#define MCFGPIO_PODR_USBH (MCF_IPSBAR + 0x100016) +#define MCFGPIO_PODR_USBL (MCF_IPSBAR + 0x100017) +#define MCFGPIO_PODR_UARTH (MCF_IPSBAR + 0x100018) + +#define MCFGPIO_PDDR_BUSCTL (MCF_IPSBAR + 0x100020) +#define MCFGPIO_PDDR_ADDR (MCF_IPSBAR + 0x100021) +#define MCFGPIO_PDDR_CS (MCF_IPSBAR + 0x100024) +#define MCFGPIO_PDDR_FEC0H (MCF_IPSBAR + 0x100026) +#define MCFGPIO_PDDR_FEC0L (MCF_IPSBAR + 0x100027) +#define MCFGPIO_PDDR_FECI2C (MCF_IPSBAR + 0x100028) +#define MCFGPIO_PDDR_QSPI (MCF_IPSBAR + 0x100029) +#define MCFGPIO_PDDR_SDRAM (MCF_IPSBAR + 0x10002A) +#define MCFGPIO_PDDR_TIMERH (MCF_IPSBAR + 0x10002B) +#define MCFGPIO_PDDR_TIMERL (MCF_IPSBAR + 0x10002C) +#define MCFGPIO_PDDR_UARTL (MCF_IPSBAR + 0x10002D) +#define MCFGPIO_PDDR_FEC1H (MCF_IPSBAR + 0x10002E) +#define MCFGPIO_PDDR_FEC1L (MCF_IPSBAR + 0x10002F) +#define MCFGPIO_PDDR_BS (MCF_IPSBAR + 0x100030) +#define MCFGPIO_PDDR_IRQ (MCF_IPSBAR + 0x100031) +#define MCFGPIO_PDDR_USBH (MCF_IPSBAR + 0x100032) +#define MCFGPIO_PDDR_USBL (MCF_IPSBAR + 0x100033) +#define MCFGPIO_PDDR_UARTH (MCF_IPSBAR + 0x100034) + +#define MCFGPIO_PPDSDR_BUSCTL (MCF_IPSBAR + 0x10003C) +#define MCFGPIO_PPDSDR_ADDR (MCF_IPSBAR + 0x10003D) +#define MCFGPIO_PPDSDR_CS (MCF_IPSBAR + 0x100040) +#define MCFGPIO_PPDSDR_FEC0H (MCF_IPSBAR + 0x100042) +#define MCFGPIO_PPDSDR_FEC0L (MCF_IPSBAR + 0x100043) +#define MCFGPIO_PPDSDR_FECI2C (MCF_IPSBAR + 0x100044) +#define MCFGPIO_PPDSDR_QSPI (MCF_IPSBAR + 0x100045) +#define MCFGPIO_PPDSDR_SDRAM (MCF_IPSBAR + 0x100046) +#define MCFGPIO_PPDSDR_TIMERH (MCF_IPSBAR + 0x100047) +#define MCFGPIO_PPDSDR_TIMERL (MCF_IPSBAR + 0x100048) +#define MCFGPIO_PPDSDR_UARTL (MCF_IPSBAR + 0x100049) +#define MCFGPIO_PPDSDR_FEC1H (MCF_IPSBAR + 0x10004A) +#define MCFGPIO_PPDSDR_FEC1L (MCF_IPSBAR + 0x10004B) +#define MCFGPIO_PPDSDR_BS (MCF_IPSBAR + 0x10004C) +#define MCFGPIO_PPDSDR_IRQ (MCF_IPSBAR + 0x10004D) +#define MCFGPIO_PPDSDR_USBH (MCF_IPSBAR + 0x10004E) +#define MCFGPIO_PPDSDR_USBL (MCF_IPSBAR + 0x10004F) +#define MCFGPIO_PPDSDR_UARTH (MCF_IPSBAR + 0x100050) + +#define MCFGPIO_PCLRR_BUSCTL (MCF_IPSBAR + 0x100058) +#define MCFGPIO_PCLRR_ADDR (MCF_IPSBAR + 0x100059) +#define MCFGPIO_PCLRR_CS (MCF_IPSBAR + 0x10005C) +#define MCFGPIO_PCLRR_FEC0H (MCF_IPSBAR + 0x10005E) +#define MCFGPIO_PCLRR_FEC0L (MCF_IPSBAR + 0x10005F) +#define MCFGPIO_PCLRR_FECI2C (MCF_IPSBAR + 0x100060) +#define MCFGPIO_PCLRR_QSPI (MCF_IPSBAR + 0x100061) +#define MCFGPIO_PCLRR_SDRAM (MCF_IPSBAR + 0x100062) +#define MCFGPIO_PCLRR_TIMERH (MCF_IPSBAR + 0x100063) +#define MCFGPIO_PCLRR_TIMERL (MCF_IPSBAR + 0x100064) +#define MCFGPIO_PCLRR_UARTL (MCF_IPSBAR + 0x100065) +#define MCFGPIO_PCLRR_FEC1H (MCF_IPSBAR + 0x100066) +#define MCFGPIO_PCLRR_FEC1L (MCF_IPSBAR + 0x100067) +#define MCFGPIO_PCLRR_BS (MCF_IPSBAR + 0x100068) +#define MCFGPIO_PCLRR_IRQ (MCF_IPSBAR + 0x100069) +#define MCFGPIO_PCLRR_USBH (MCF_IPSBAR + 0x10006A) +#define MCFGPIO_PCLRR_USBL (MCF_IPSBAR + 0x10006B) +#define MCFGPIO_PCLRR_UARTH (MCF_IPSBAR + 0x10006C) + + +/* + * Generic GPIO support + */ +#define MCFGPIO_PODR MCFGPIO_PODR_BUSCTL +#define MCFGPIO_PDDR MCFGPIO_PDDR_BUSCTL +#define MCFGPIO_PPDR MCFGPIO_PPDSDR_BUSCTL +#define MCFGPIO_SETR MCFGPIO_PPDSDR_BUSCTL +#define MCFGPIO_CLRR MCFGPIO_PCLRR_BUSCTL + +#define MCFGPIO_PIN_MAX 148 +#define MCFGPIO_IRQ_MAX 8 +#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE +#endif + +/* + * EPort + */ + +#define MCFEPORT_EPDDR (MCF_IPSBAR + 0x130002) +#define MCFEPORT_EPDR (MCF_IPSBAR + 0x130004) +#define MCFEPORT_EPPDR (MCF_IPSBAR + 0x130005) + + /* * GPIO pins setups to enable the UARTs. */ diff --git a/arch/m68k/include/asm/m528xsim.h b/arch/m68k/include/asm/m528xsim.h index d79c49f8134..e2ad1f42b65 100644 --- a/arch/m68k/include/asm/m528xsim.h +++ b/arch/m68k/include/asm/m528xsim.h @@ -41,6 +41,157 @@ #define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */ /* + * GPIO registers + */ +#define MCFGPIO_PORTA (MCF_IPSBAR + 0x00100000) +#define MCFGPIO_PORTB (MCF_IPSBAR + 0x00100001) +#define MCFGPIO_PORTC (MCF_IPSBAR + 0x00100002) +#define MCFGPIO_PORTD (MCF_IPSBAR + 0x00100003) +#define MCFGPIO_PORTE (MCF_IPSBAR + 0x00100004) +#define MCFGPIO_PORTF (MCF_IPSBAR + 0x00100005) +#define MCFGPIO_PORTG (MCF_IPSBAR + 0x00100006) +#define MCFGPIO_PORTH (MCF_IPSBAR + 0x00100007) +#define MCFGPIO_PORTJ (MCF_IPSBAR + 0x00100008) +#define MCFGPIO_PORTDD (MCF_IPSBAR + 0x00100009) +#define MCFGPIO_PORTEH (MCF_IPSBAR + 0x0010000A) +#define MCFGPIO_PORTEL (MCF_IPSBAR + 0x0010000B) +#define MCFGPIO_PORTAS (MCF_IPSBAR + 0x0010000C) +#define MCFGPIO_PORTQS (MCF_IPSBAR + 0x0010000D) +#define MCFGPIO_PORTSD (MCF_IPSBAR + 0x0010000E) +#define MCFGPIO_PORTTC (MCF_IPSBAR + 0x0010000F) +#define MCFGPIO_PORTTD (MCF_IPSBAR + 0x00100010) +#define MCFGPIO_PORTUA (MCF_IPSBAR + 0x00100011) + +#define MCFGPIO_DDRA (MCF_IPSBAR + 0x00100014) +#define MCFGPIO_DDRB (MCF_IPSBAR + 0x00100015) +#define MCFGPIO_DDRC (MCF_IPSBAR + 0x00100016) +#define MCFGPIO_DDRD (MCF_IPSBAR + 0x00100017) +#define MCFGPIO_DDRE (MCF_IPSBAR + 0x00100018) +#define MCFGPIO_DDRF (MCF_IPSBAR + 0x00100019) +#define MCFGPIO_DDRG (MCF_IPSBAR + 0x0010001A) +#define MCFGPIO_DDRH (MCF_IPSBAR + 0x0010001B) +#define MCFGPIO_DDRJ (MCF_IPSBAR + 0x0010001C) +#define MCFGPIO_DDRDD (MCF_IPSBAR + 0x0010001D) +#define MCFGPIO_DDREH (MCF_IPSBAR + 0x0010001E) +#define MCFGPIO_DDREL (MCF_IPSBAR + 0x0010001F) +#define MCFGPIO_DDRAS (MCF_IPSBAR + 0x00100020) +#define MCFGPIO_DDRQS (MCF_IPSBAR + 0x00100021) +#define MCFGPIO_DDRSD (MCF_IPSBAR + 0x00100022) +#define MCFGPIO_DDRTC (MCF_IPSBAR + 0x00100023) +#define MCFGPIO_DDRTD (MCF_IPSBAR + 0x00100024) +#define MCFGPIO_DDRUA (MCF_IPSBAR + 0x00100025) + +#define MCFGPIO_PORTAP (MCF_IPSBAR + 0x00100028) +#define MCFGPIO_PORTBP (MCF_IPSBAR + 0x00100029) +#define MCFGPIO_PORTCP (MCF_IPSBAR + 0x0010002A) +#define MCFGPIO_PORTDP (MCF_IPSBAR + 0x0010002B) +#define MCFGPIO_PORTEP (MCF_IPSBAR + 0x0010002C) +#define MCFGPIO_PORTFP (MCF_IPSBAR + 0x0010002D) +#define MCFGPIO_PORTGP (MCF_IPSBAR + 0x0010002E) +#define MCFGPIO_PORTHP (MCF_IPSBAR + 0x0010002F) +#define MCFGPIO_PORTJP (MCF_IPSBAR + 0x00100030) +#define MCFGPIO_PORTDDP (MCF_IPSBAR + 0x00100031) +#define MCFGPIO_PORTEHP (MCF_IPSBAR + 0x00100032) +#define MCFGPIO_PORTELP (MCF_IPSBAR + 0x00100033) +#define MCFGPIO_PORTASP (MCF_IPSBAR + 0x00100034) +#define MCFGPIO_PORTQSP (MCF_IPSBAR + 0x00100035) +#define MCFGPIO_PORTSDP (MCF_IPSBAR + 0x00100036) +#define MCFGPIO_PORTTCP (MCF_IPSBAR + 0x00100037) +#define MCFGPIO_PORTTDP (MCF_IPSBAR + 0x00100038) +#define MCFGPIO_PORTUAP (MCF_IPSBAR + 0x00100039) + +#define MCFGPIO_SETA (MCF_IPSBAR + 0x00100028) +#define MCFGPIO_SETB (MCF_IPSBAR + 0x00100029) +#define MCFGPIO_SETC (MCF_IPSBAR + 0x0010002A) +#define MCFGPIO_SETD (MCF_IPSBAR + 0x0010002B) +#define MCFGPIO_SETE (MCF_IPSBAR + 0x0010002C) +#define MCFGPIO_SETF (MCF_IPSBAR + 0x0010002D) +#define MCFGPIO_SETG (MCF_IPSBAR + 0x0010002E) +#define MCFGPIO_SETH (MCF_IPSBAR + 0x0010002F) +#define MCFGPIO_SETJ (MCF_IPSBAR + 0x00100030) +#define MCFGPIO_SETDD (MCF_IPSBAR + 0x00100031) +#define MCFGPIO_SETEH (MCF_IPSBAR + 0x00100032) +#define MCFGPIO_SETEL (MCF_IPSBAR + 0x00100033) +#define MCFGPIO_SETAS (MCF_IPSBAR + 0x00100034) +#define MCFGPIO_SETQS (MCF_IPSBAR + 0x00100035) +#define MCFGPIO_SETSD (MCF_IPSBAR + 0x00100036) +#define MCFGPIO_SETTC (MCF_IPSBAR + 0x00100037) +#define MCFGPIO_SETTD (MCF_IPSBAR + 0x00100038) +#define MCFGPIO_SETUA (MCF_IPSBAR + 0x00100039) + +#define MCFGPIO_CLRA (MCF_IPSBAR + 0x0010003C) +#define MCFGPIO_CLRB (MCF_IPSBAR + 0x0010003D) +#define MCFGPIO_CLRC (MCF_IPSBAR + 0x0010003E) +#define MCFGPIO_CLRD (MCF_IPSBAR + 0x0010003F) +#define MCFGPIO_CLRE (MCF_IPSBAR + 0x00100040) +#define MCFGPIO_CLRF (MCF_IPSBAR + 0x00100041) +#define MCFGPIO_CLRG (MCF_IPSBAR + 0x00100042) +#define MCFGPIO_CLRH (MCF_IPSBAR + 0x00100043) +#define MCFGPIO_CLRJ (MCF_IPSBAR + 0x00100044) +#define MCFGPIO_CLRDD (MCF_IPSBAR + 0x00100045) +#define MCFGPIO_CLREH (MCF_IPSBAR + 0x00100046) +#define MCFGPIO_CLREL (MCF_IPSBAR + 0x00100047) +#define MCFGPIO_CLRAS (MCF_IPSBAR + 0x00100048) +#define MCFGPIO_CLRQS (MCF_IPSBAR + 0x00100049) +#define MCFGPIO_CLRSD (MCF_IPSBAR + 0x0010004A) +#define MCFGPIO_CLRTC (MCF_IPSBAR + 0x0010004B) +#define MCFGPIO_CLRTD (MCF_IPSBAR + 0x0010004C) +#define MCFGPIO_CLRUA (MCF_IPSBAR + 0x0010004D) + +#define MCFGPIO_PBCDPAR (MCF_IPSBAR + 0x00100050) +#define MCFGPIO_PFPAR (MCF_IPSBAR + 0x00100051) +#define MCFGPIO_PEPAR (MCF_IPSBAR + 0x00100052) +#define MCFGPIO_PJPAR (MCF_IPSBAR + 0x00100054) +#define MCFGPIO_PSDPAR (MCF_IPSBAR + 0x00100055) +#define MCFGPIO_PASPAR (MCF_IPSBAR + 0x00100056) +#define MCFGPIO_PEHLPAR (MCF_IPSBAR + 0x00100058) +#define MCFGPIO_PQSPAR (MCF_IPSBAR + 0x00100059) +#define MCFGPIO_PTCPAR (MCF_IPSBAR + 0x0010005A) +#define MCFGPIO_PTDPAR (MCF_IPSBAR + 0x0010005B) +#define MCFGPIO_PUAPAR (MCF_IPSBAR + 0x0010005C) + +/* + * Edge Port registers + */ +#define MCFEPORT_EPPAR (MCF_IPSBAR + 0x00130000) +#define MCFEPORT_EPDDR (MCF_IPSBAR + 0x00130002) +#define MCFEPORT_EPIER (MCF_IPSBAR + 0x00130003) +#define MCFEPORT_EPDR (MCF_IPSBAR + 0x00130004) +#define MCFEPORT_EPPDR (MCF_IPSBAR + 0x00130005) +#define MCFEPORT_EPFR (MCF_IPSBAR + 0x00130006) + +/* + * Queued ADC registers + */ +#define MCFQADC_PORTQA (MCF_IPSBAR + 0x00190006) +#define MCFQADC_PORTQB (MCF_IPSBAR + 0x00190007) +#define MCFQADC_DDRQA (MCF_IPSBAR + 0x00190008) +#define MCFQADC_DDRQB (MCF_IPSBAR + 0x00190009) + +/* + * General Purpose Timers registers + */ +#define MCFGPTA_GPTPORT (MCF_IPSBAR + 0x001A001D) +#define MCFGPTA_GPTDDR (MCF_IPSBAR + 0x001A001E) +#define MCFGPTB_GPTPORT (MCF_IPSBAR + 0x001B001D) +#define MCFGPTB_GPTDDR (MCF_IPSBAR + 0x001B001E) +/* + * + * definitions for generic gpio support + * + */ +#define MCFGPIO_PODR MCFGPIO_PORTA /* port output data */ +#define MCFGPIO_PDDR MCFGPIO_DDRA /* port data direction */ +#define MCFGPIO_PPDR MCFGPIO_PORTAP /* port pin data */ +#define MCFGPIO_SETR MCFGPIO_SETA /* set output */ +#define MCFGPIO_CLRR MCFGPIO_CLRA /* clr output */ + +#define MCFGPIO_IRQ_MAX 8 +#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE +#define MCFGPIO_PIN_MAX 180 + + +/* * Derek Cheung - 6 Feb 2005 * add I2C and QSPI register definition using Freescale's MCF5282 */ diff --git a/arch/m68k/include/asm/m5307sim.h b/arch/m68k/include/asm/m5307sim.h index 5886728409c..c6830e5b54c 100644 --- a/arch/m68k/include/asm/m5307sim.h +++ b/arch/m68k/include/asm/m5307sim.h @@ -90,8 +90,15 @@ #define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */ #define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */ -#define MCFSIM_PADDR 0x244 /* Parallel Direction (r/w) */ -#define MCFSIM_PADAT 0x248 /* Parallel Data (r/w) */ +#define MCFSIM_PADDR (MCF_MBAR + 0x244) +#define MCFSIM_PADAT (MCF_MBAR + 0x248) + +/* + * Generic GPIO support + */ +#define MCFGPIO_PIN_MAX 16 +#define MCFGPIO_IRQ_MAX -1 +#define MCFGPIO_IRQ_VECBASE -1 /* Definition offset address for CS2-7 -- old mask 5307 */ @@ -117,22 +124,6 @@ #define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ #define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ -#if defined(CONFIG_M5307) -#define MCFSIM_IMR_MASKALL 0x3fffe /* All SIM intr sources */ -#endif - -/* - * Macro to set IMR register. It is 32 bits on the 5307. - */ -#define mcf_getimr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); - -#define mcf_getipr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) - /* * Some symbol defines for the Parallel Port Pin Assignment Register @@ -149,6 +140,11 @@ #define IRQ3_LEVEL6 0x40 #define IRQ1_LEVEL2 0x20 +/* + * Define system peripheral IRQ usage. + */ +#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */ +#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */ /* * Define the Cache register flags. diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h index eb7fd444894..36bf15aec9a 100644 --- a/arch/m68k/include/asm/m532xsim.h +++ b/arch/m68k/include/asm/m532xsim.h @@ -56,47 +56,21 @@ #define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ -#define MCFSIM_IMR_MASKALL 0xFFFFFFFF /* All SIM intr sources */ - -#define MCFSIM_IMR_SIMR0 0xFC04801C -#define MCFSIM_IMR_SIMR1 0xFC04C01C -#define MCFSIM_IMR_CIMR0 0xFC04801D -#define MCFSIM_IMR_CIMR1 0xFC04C01D +#define MCFINTC0_SIMR 0xFC04801C +#define MCFINTC0_CIMR 0xFC04801D +#define MCFINTC0_ICR0 0xFC048040 +#define MCFINTC1_SIMR 0xFC04C01C +#define MCFINTC1_CIMR 0xFC04C01D +#define MCFINTC1_ICR0 0xFC04C040 #define MCFSIM_ICR_TIMER1 (0xFC048040+32) #define MCFSIM_ICR_TIMER2 (0xFC048040+33) - /* - * Macro to set IMR register. It is 32 bits on the 5307. + * Define system peripheral IRQ usage. */ -#define mcf_getimr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); - -#define mcf_getipr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) - -#define mcf_getiprl() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRL)) - -#define mcf_getiprh() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRH)) - - -#define mcf_enable_irq0(irq) \ - *((volatile unsigned char*) (MCFSIM_IMR_CIMR0)) = (irq); - -#define mcf_enable_irq1(irq) \ - *((volatile unsigned char*) (MCFSIM_IMR_CIMR1)) = (irq); - -#define mcf_disable_irq0(irq) \ - *((volatile unsigned char*) (MCFSIM_IMR_SIMR0)) = (irq); - -#define mcf_disable_irq1(irq) \ - *((volatile unsigned char*) (MCFSIM_IMR_SIMR1)) = (irq); +#define MCF_IRQ_TIMER (64 + 32) /* Timer0 */ +#define MCF_IRQ_PROFILER (64 + 33) /* Timer1 */ /* * Define the Cache register flags. @@ -422,70 +396,70 @@ *********************************************************************/ /* Register read/write macros */ -#define MCF_GPIO_PODR_FECH MCF_REG08(0xFC0A4000) -#define MCF_GPIO_PODR_FECL MCF_REG08(0xFC0A4001) -#define MCF_GPIO_PODR_SSI MCF_REG08(0xFC0A4002) -#define MCF_GPIO_PODR_BUSCTL MCF_REG08(0xFC0A4003) -#define MCF_GPIO_PODR_BE MCF_REG08(0xFC0A4004) -#define MCF_GPIO_PODR_CS MCF_REG08(0xFC0A4005) -#define MCF_GPIO_PODR_PWM MCF_REG08(0xFC0A4006) -#define MCF_GPIO_PODR_FECI2C MCF_REG08(0xFC0A4007) -#define MCF_GPIO_PODR_UART MCF_REG08(0xFC0A4009) -#define MCF_GPIO_PODR_QSPI MCF_REG08(0xFC0A400A) -#define MCF_GPIO_PODR_TIMER MCF_REG08(0xFC0A400B) -#define MCF_GPIO_PODR_LCDDATAH MCF_REG08(0xFC0A400D) -#define MCF_GPIO_PODR_LCDDATAM MCF_REG08(0xFC0A400E) -#define MCF_GPIO_PODR_LCDDATAL MCF_REG08(0xFC0A400F) -#define MCF_GPIO_PODR_LCDCTLH MCF_REG08(0xFC0A4010) -#define MCF_GPIO_PODR_LCDCTLL MCF_REG08(0xFC0A4011) -#define MCF_GPIO_PDDR_FECH MCF_REG08(0xFC0A4014) -#define MCF_GPIO_PDDR_FECL MCF_REG08(0xFC0A4015) -#define MCF_GPIO_PDDR_SSI MCF_REG08(0xFC0A4016) -#define MCF_GPIO_PDDR_BUSCTL MCF_REG08(0xFC0A4017) -#define MCF_GPIO_PDDR_BE MCF_REG08(0xFC0A4018) -#define MCF_GPIO_PDDR_CS MCF_REG08(0xFC0A4019) -#define MCF_GPIO_PDDR_PWM MCF_REG08(0xFC0A401A) -#define MCF_GPIO_PDDR_FECI2C MCF_REG08(0xFC0A401B) -#define MCF_GPIO_PDDR_UART MCF_REG08(0xFC0A401C) -#define MCF_GPIO_PDDR_QSPI MCF_REG08(0xFC0A401E) -#define MCF_GPIO_PDDR_TIMER MCF_REG08(0xFC0A401F) -#define MCF_GPIO_PDDR_LCDDATAH MCF_REG08(0xFC0A4021) -#define MCF_GPIO_PDDR_LCDDATAM MCF_REG08(0xFC0A4022) -#define MCF_GPIO_PDDR_LCDDATAL MCF_REG08(0xFC0A4023) -#define MCF_GPIO_PDDR_LCDCTLH MCF_REG08(0xFC0A4024) -#define MCF_GPIO_PDDR_LCDCTLL MCF_REG08(0xFC0A4025) -#define MCF_GPIO_PPDSDR_FECH MCF_REG08(0xFC0A4028) -#define MCF_GPIO_PPDSDR_FECL MCF_REG08(0xFC0A4029) -#define MCF_GPIO_PPDSDR_SSI MCF_REG08(0xFC0A402A) -#define MCF_GPIO_PPDSDR_BUSCTL MCF_REG08(0xFC0A402B) -#define MCF_GPIO_PPDSDR_BE MCF_REG08(0xFC0A402C) -#define MCF_GPIO_PPDSDR_CS MCF_REG08(0xFC0A402D) -#define MCF_GPIO_PPDSDR_PWM MCF_REG08(0xFC0A402E) -#define MCF_GPIO_PPDSDR_FECI2C MCF_REG08(0xFC0A402F) -#define MCF_GPIO_PPDSDR_UART MCF_REG08(0xFC0A4031) -#define MCF_GPIO_PPDSDR_QSPI MCF_REG08(0xFC0A4032) -#define MCF_GPIO_PPDSDR_TIMER MCF_REG08(0xFC0A4033) -#define MCF_GPIO_PPDSDR_LCDDATAH MCF_REG08(0xFC0A4035) -#define MCF_GPIO_PPDSDR_LCDDATAM MCF_REG08(0xFC0A4036) -#define MCF_GPIO_PPDSDR_LCDDATAL MCF_REG08(0xFC0A4037) -#define MCF_GPIO_PPDSDR_LCDCTLH MCF_REG08(0xFC0A4038) -#define MCF_GPIO_PPDSDR_LCDCTLL MCF_REG08(0xFC0A4039) -#define MCF_GPIO_PCLRR_FECH MCF_REG08(0xFC0A403C) -#define MCF_GPIO_PCLRR_FECL MCF_REG08(0xFC0A403D) -#define MCF_GPIO_PCLRR_SSI MCF_REG08(0xFC0A403E) -#define MCF_GPIO_PCLRR_BUSCTL MCF_REG08(0xFC0A403F) -#define MCF_GPIO_PCLRR_BE MCF_REG08(0xFC0A4040) -#define MCF_GPIO_PCLRR_CS MCF_REG08(0xFC0A4041) -#define MCF_GPIO_PCLRR_PWM MCF_REG08(0xFC0A4042) -#define MCF_GPIO_PCLRR_FECI2C MCF_REG08(0xFC0A4043) -#define MCF_GPIO_PCLRR_UART MCF_REG08(0xFC0A4045) -#define MCF_GPIO_PCLRR_QSPI MCF_REG08(0xFC0A4046) -#define MCF_GPIO_PCLRR_TIMER MCF_REG08(0xFC0A4047) -#define MCF_GPIO_PCLRR_LCDDATAH MCF_REG08(0xFC0A4049) -#define MCF_GPIO_PCLRR_LCDDATAM MCF_REG08(0xFC0A404A) -#define MCF_GPIO_PCLRR_LCDDATAL MCF_REG08(0xFC0A404B) -#define MCF_GPIO_PCLRR_LCDCTLH MCF_REG08(0xFC0A404C) -#define MCF_GPIO_PCLRR_LCDCTLL MCF_REG08(0xFC0A404D) +#define MCFGPIO_PODR_FECH (0xFC0A4000) +#define MCFGPIO_PODR_FECL (0xFC0A4001) +#define MCFGPIO_PODR_SSI (0xFC0A4002) +#define MCFGPIO_PODR_BUSCTL (0xFC0A4003) +#define MCFGPIO_PODR_BE (0xFC0A4004) +#define MCFGPIO_PODR_CS (0xFC0A4005) +#define MCFGPIO_PODR_PWM (0xFC0A4006) +#define MCFGPIO_PODR_FECI2C (0xFC0A4007) +#define MCFGPIO_PODR_UART (0xFC0A4009) +#define MCFGPIO_PODR_QSPI (0xFC0A400A) +#define MCFGPIO_PODR_TIMER (0xFC0A400B) +#define MCFGPIO_PODR_LCDDATAH (0xFC0A400D) +#define MCFGPIO_PODR_LCDDATAM (0xFC0A400E) +#define MCFGPIO_PODR_LCDDATAL (0xFC0A400F) +#define MCFGPIO_PODR_LCDCTLH (0xFC0A4010) +#define MCFGPIO_PODR_LCDCTLL (0xFC0A4011) +#define MCFGPIO_PDDR_FECH (0xFC0A4014) +#define MCFGPIO_PDDR_FECL (0xFC0A4015) +#define MCFGPIO_PDDR_SSI (0xFC0A4016) +#define MCFGPIO_PDDR_BUSCTL (0xFC0A4017) +#define MCFGPIO_PDDR_BE (0xFC0A4018) +#define MCFGPIO_PDDR_CS (0xFC0A4019) +#define MCFGPIO_PDDR_PWM (0xFC0A401A) +#define MCFGPIO_PDDR_FECI2C (0xFC0A401B) +#define MCFGPIO_PDDR_UART (0xFC0A401C) +#define MCFGPIO_PDDR_QSPI (0xFC0A401E) +#define MCFGPIO_PDDR_TIMER (0xFC0A401F) +#define MCFGPIO_PDDR_LCDDATAH (0xFC0A4021) +#define MCFGPIO_PDDR_LCDDATAM (0xFC0A4022) +#define MCFGPIO_PDDR_LCDDATAL (0xFC0A4023) +#define MCFGPIO_PDDR_LCDCTLH (0xFC0A4024) +#define MCFGPIO_PDDR_LCDCTLL (0xFC0A4025) +#define MCFGPIO_PPDSDR_FECH (0xFC0A4028) +#define MCFGPIO_PPDSDR_FECL (0xFC0A4029) +#define MCFGPIO_PPDSDR_SSI (0xFC0A402A) +#define MCFGPIO_PPDSDR_BUSCTL (0xFC0A402B) +#define MCFGPIO_PPDSDR_BE (0xFC0A402C) +#define MCFGPIO_PPDSDR_CS (0xFC0A402D) +#define MCFGPIO_PPDSDR_PWM (0xFC0A402E) +#define MCFGPIO_PPDSDR_FECI2C (0xFC0A402F) +#define MCFGPIO_PPDSDR_UART (0xFC0A4031) +#define MCFGPIO_PPDSDR_QSPI (0xFC0A4032) +#define MCFGPIO_PPDSDR_TIMER (0xFC0A4033) +#define MCFGPIO_PPDSDR_LCDDATAH (0xFC0A4035) +#define MCFGPIO_PPDSDR_LCDDATAM (0xFC0A4036) +#define MCFGPIO_PPDSDR_LCDDATAL (0xFC0A4037) +#define MCFGPIO_PPDSDR_LCDCTLH (0xFC0A4038) +#define MCFGPIO_PPDSDR_LCDCTLL (0xFC0A4039) +#define MCFGPIO_PCLRR_FECH (0xFC0A403C) +#define MCFGPIO_PCLRR_FECL (0xFC0A403D) +#define MCFGPIO_PCLRR_SSI (0xFC0A403E) +#define MCFGPIO_PCLRR_BUSCTL (0xFC0A403F) +#define MCFGPIO_PCLRR_BE (0xFC0A4040) +#define MCFGPIO_PCLRR_CS (0xFC0A4041) +#define MCFGPIO_PCLRR_PWM (0xFC0A4042) +#define MCFGPIO_PCLRR_FECI2C (0xFC0A4043) +#define MCFGPIO_PCLRR_UART (0xFC0A4045) +#define MCFGPIO_PCLRR_QSPI (0xFC0A4046) +#define MCFGPIO_PCLRR_TIMER (0xFC0A4047) +#define MCFGPIO_PCLRR_LCDDATAH (0xFC0A4049) +#define MCFGPIO_PCLRR_LCDDATAM (0xFC0A404A) +#define MCFGPIO_PCLRR_LCDDATAL (0xFC0A404B) +#define MCFGPIO_PCLRR_LCDCTLH (0xFC0A404C) +#define MCFGPIO_PCLRR_LCDCTLL (0xFC0A404D) #define MCF_GPIO_PAR_FEC MCF_REG08(0xFC0A4050) #define MCF_GPIO_PAR_PWM MCF_REG08(0xFC0A4051) #define MCF_GPIO_PAR_BUSCTL MCF_REG08(0xFC0A4052) @@ -1187,6 +1161,20 @@ /* Bit definitions and macros for MCF_GPIO_DSCR_IRQ */ #define MCF_GPIO_DSCR_IRQ_IRQ_DSE(x) (((x)&0x03)<<0) +/* + * Generic GPIO support + */ +#define MCFGPIO_PODR MCFGPIO_PODR_FECH +#define MCFGPIO_PDDR MCFGPIO_PDDR_FECH +#define MCFGPIO_PPDR MCFGPIO_PPDSDR_FECH +#define MCFGPIO_SETR MCFGPIO_PPDSDR_FECH +#define MCFGPIO_CLRR MCFGPIO_PCLRR_FECH + +#define MCFGPIO_PIN_MAX 136 +#define MCFGPIO_IRQ_MAX 8 +#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE + + /********************************************************************* * * Interrupt Controller (INTC) @@ -2154,12 +2142,12 @@ *********************************************************************/ /* Register read/write macros */ -#define MCF_EPORT_EPPAR MCF_REG16(0xFC094000) -#define MCF_EPORT_EPDDR MCF_REG08(0xFC094002) -#define MCF_EPORT_EPIER MCF_REG08(0xFC094003) -#define MCF_EPORT_EPDR MCF_REG08(0xFC094004) -#define MCF_EPORT_EPPDR MCF_REG08(0xFC094005) -#define MCF_EPORT_EPFR MCF_REG08(0xFC094006) +#define MCFEPORT_EPPAR (0xFC094000) +#define MCFEPORT_EPDDR (0xFC094002) +#define MCFEPORT_EPIER (0xFC094003) +#define MCFEPORT_EPDR (0xFC094004) +#define MCFEPORT_EPPDR (0xFC094005) +#define MCFEPORT_EPFR (0xFC094006) /* Bit definitions and macros for MCF_EPORT_EPPAR */ #define MCF_EPORT_EPPAR_EPPA1(x) (((x)&0x0003)<<2) diff --git a/arch/m68k/include/asm/m5407sim.h b/arch/m68k/include/asm/m5407sim.h index cc22c4a5300..c399abbf953 100644 --- a/arch/m68k/include/asm/m5407sim.h +++ b/arch/m68k/include/asm/m5407sim.h @@ -73,9 +73,15 @@ #define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */ #define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */ -#define MCFSIM_PADDR 0x244 /* Parallel Direction (r/w) */ -#define MCFSIM_PADAT 0x248 /* Parallel Data (r/w) */ +#define MCFSIM_PADDR (MCF_MBAR + 0x244) +#define MCFSIM_PADAT (MCF_MBAR + 0x248) +/* + * Generic GPIO support + */ +#define MCFGPIO_PIN_MAX 16 +#define MCFGPIO_IRQ_MAX -1 +#define MCFGPIO_IRQ_VECBASE -1 /* * Some symbol defines for the above... @@ -91,19 +97,6 @@ #define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ /* - * Macro to set IMR register. It is 32 bits on the 5407. - */ -#define mcf_getimr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); - -#define mcf_getipr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) - - -/* * Some symbol defines for the Parallel Port Pin Assignment Register */ #define MCFSIM_PAR_DREQ0 0x40 /* Set to select DREQ0 input */ @@ -118,6 +111,11 @@ #define IRQ3_LEVEL6 0x40 #define IRQ1_LEVEL2 0x20 +/* + * Define system peripheral IRQ usage. + */ +#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */ +#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */ /* * Define the Cache register flags. diff --git a/arch/m68k/include/asm/mcfgpio.h b/arch/m68k/include/asm/mcfgpio.h new file mode 100644 index 00000000000..ee5e4ccce89 --- /dev/null +++ b/arch/m68k/include/asm/mcfgpio.h @@ -0,0 +1,40 @@ +/* + * Coldfire generic GPIO support. + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef mcfgpio_h +#define mcfgpio_h + +#include <linux/io.h> +#include <asm-generic/gpio.h> + +struct mcf_gpio_chip { + struct gpio_chip gpio_chip; + void __iomem *pddr; + void __iomem *podr; + void __iomem *ppdr; + void __iomem *setr; + void __iomem *clrr; + const u8 *gpio_to_pinmux; +}; + +int mcf_gpio_direction_input(struct gpio_chip *, unsigned); +int mcf_gpio_get_value(struct gpio_chip *, unsigned); +int mcf_gpio_direction_output(struct gpio_chip *, unsigned, int); +void mcf_gpio_set_value(struct gpio_chip *, unsigned, int); +void mcf_gpio_set_value_fast(struct gpio_chip *, unsigned, int); +int mcf_gpio_request(struct gpio_chip *, unsigned); +void mcf_gpio_free(struct gpio_chip *, unsigned); + +#endif diff --git a/arch/m68k/include/asm/mcfintc.h b/arch/m68k/include/asm/mcfintc.h new file mode 100644 index 00000000000..4183320a381 --- /dev/null +++ b/arch/m68k/include/asm/mcfintc.h @@ -0,0 +1,89 @@ +/****************************************************************************/ + +/* + * mcfintc.h -- support definitions for the simple ColdFire + * Interrupt Controller + * + * (C) Copyright 2009, Greg Ungerer <gerg@uclinux.org> + */ + +/****************************************************************************/ +#ifndef mcfintc_h +#define mcfintc_h +/****************************************************************************/ + +/* + * Most of the older ColdFire parts use the same simple interrupt + * controller. This is currently used on the 5206, 5206e, 5249, 5307 + * and 5407 parts. + * + * The builtin peripherals are masked through dedicated bits in the + * Interrupt Mask register (IMR) - and this is not indexed (or in any way + * related to) the actual interrupt number they use. So knowing the IRQ + * number doesn't explicitly map to a certain internal device for + * interrupt control purposes. + */ + +/* + * Bit definitions for the ICR family of registers. + */ +#define MCFSIM_ICR_AUTOVEC 0x80 /* Auto-vectored intr */ +#define MCFSIM_ICR_LEVEL0 0x00 /* Level 0 intr */ +#define MCFSIM_ICR_LEVEL1 0x04 /* Level 1 intr */ +#define MCFSIM_ICR_LEVEL2 0x08 /* Level 2 intr */ +#define MCFSIM_ICR_LEVEL3 0x0c /* Level 3 intr */ +#define MCFSIM_ICR_LEVEL4 0x10 /* Level 4 intr */ +#define MCFSIM_ICR_LEVEL5 0x14 /* Level 5 intr */ +#define MCFSIM_ICR_LEVEL6 0x18 /* Level 6 intr */ +#define MCFSIM_ICR_LEVEL7 0x1c /* Level 7 intr */ + +#define MCFSIM_ICR_PRI0 0x00 /* Priority 0 intr */ +#define MCFSIM_ICR_PRI1 0x01 /* Priority 1 intr */ +#define MCFSIM_ICR_PRI2 0x02 /* Priority 2 intr */ +#define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */ + +/* + * IMR bit position definitions. Not all ColdFire parts with this interrupt + * controller actually support all of these interrupt sources. But the bit + * numbers are the same in all cores. + */ +#define MCFINTC_EINT1 1 /* External int #1 */ +#define MCFINTC_EINT2 2 /* External int #2 */ +#define MCFINTC_EINT3 3 /* External int #3 */ +#define MCFINTC_EINT4 4 /* External int #4 */ +#define MCFINTC_EINT5 5 /* External int #5 */ +#define MCFINTC_EINT6 6 /* External int #6 */ +#define MCFINTC_EINT7 7 /* External int #7 */ +#define MCFINTC_SWT 8 /* Software Watchdog */ +#define MCFINTC_TIMER1 9 +#define MCFINTC_TIMER2 10 +#define MCFINTC_I2C 11 /* I2C / MBUS */ +#define MCFINTC_UART0 12 +#define MCFINTC_UART1 13 +#define MCFINTC_DMA0 14 +#define MCFINTC_DMA1 15 +#define MCFINTC_DMA2 16 +#define MCFINTC_DMA3 17 +#define MCFINTC_QSPI 18 + +#ifndef __ASSEMBLER__ + +/* + * There is no one-is-one correspondance between the interrupt number (irq) + * and the bit fields on the mask register. So we create a per-cpu type + * mapping of irq to mask bit. The CPU platform code needs to register + * its supported irq's at init time, using this function. + */ +extern unsigned char mcf_irq2imr[]; +static inline void mcf_mapirq2imr(int irq, int imr) +{ + mcf_irq2imr[irq] = imr; +} + +void mcf_autovector(int irq); +void mcf_setimr(int index); +void mcf_clrimr(int index); +#endif + +/****************************************************************************/ +#endif /* mcfintc_h */ diff --git a/arch/m68k/include/asm/mcfne.h b/arch/m68k/include/asm/mcfne.h index 431f63aadd0..bf638be0958 100644 --- a/arch/m68k/include/asm/mcfne.h +++ b/arch/m68k/include/asm/mcfne.h @@ -239,87 +239,4 @@ void ne2000_outsw(unsigned int addr, const void *vbuf, unsigned long len) #endif /* NE2000_OFFOFFSET */ /****************************************************************************/ - -#ifdef COLDFIRE_NE2000_FUNCS - -/* - * Lastly the interrupt set up code... - * Minor differences between the different board types. - */ - -#if defined(CONFIG_ARN5206) -void ne2000_irqsetup(int irq) -{ - volatile unsigned char *icrp; - - icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4); - *icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2; - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4); -} -#endif - -#if defined(CONFIG_M5206eC3) -void ne2000_irqsetup(int irq) -{ - volatile unsigned char *icrp; - - icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4); - *icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2 | MCFSIM_ICR_AUTOVEC; - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4); -} -#endif - -#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel) -void ne2000_irqsetup(int irq) -{ - mcf_autovector(irq); -} -#endif - -#if defined(CONFIG_M5272) && defined(CONFIG_NETtel) -void ne2000_irqsetup(int irq) -{ - volatile unsigned long *icrp; - volatile unsigned long *pitr; - - /* The NE2000 device uses external IRQ3 */ - icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = (*icrp & 0x77077777) | 0x00d00000; - - pitr = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PITR); - *pitr = *pitr | 0x20000000; -} - -void ne2000_irqack(int irq) -{ - volatile unsigned long *icrp; - - /* The NE2000 device uses external IRQ3 */ - icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = (*icrp & 0x77777777) | 0x00800000; -} -#endif - -#if defined(CONFIG_M5307) || defined(CONFIG_M5407) -#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3) - -void ne2000_irqsetup(int irq) -{ - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3); - mcf_autovector(irq); -} - -#else - -void ne2000_irqsetup(int irq) -{ - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3); -} - -#endif /* ! CONFIG_NETtel || CONFIG_SECUREEDGEMP3 */ -#endif /* CONFIG_M5307 || CONFIG_M5407 */ - -#endif /* COLDFIRE_NE2000_FUNCS */ - -/****************************************************************************/ #endif /* mcfne_h */ diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h index da3f2ceff3a..9c70a67bf85 100644 --- a/arch/m68k/include/asm/mcfsim.h +++ b/arch/m68k/include/asm/mcfsim.h @@ -4,7 +4,7 @@ * mcfsim.h -- ColdFire System Integration Module support. * * (C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com) - * (C) Copyright 2000, Lineo Inc. (www.lineo.com) + * (C) Copyright 2000, Lineo Inc. (www.lineo.com) */ /****************************************************************************/ @@ -12,19 +12,21 @@ #define mcfsim_h /****************************************************************************/ - /* - * Include 5204, 5206/e, 5235, 5249, 5270/5271, 5272, 5280/5282, - * 5307 or 5407 specific addresses. + * Include the appropriate ColdFire CPU specific System Integration Module + * (SIM) definitions. */ #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) #include <asm/m5206sim.h> +#include <asm/mcfintc.h> #elif defined(CONFIG_M520x) #include <asm/m520xsim.h> #elif defined(CONFIG_M523x) #include <asm/m523xsim.h> +#include <asm/mcfintc.h> #elif defined(CONFIG_M5249) #include <asm/m5249sim.h> +#include <asm/mcfintc.h> #elif defined(CONFIG_M527x) #include <asm/m527xsim.h> #elif defined(CONFIG_M5272) @@ -33,94 +35,13 @@ #include <asm/m528xsim.h> #elif defined(CONFIG_M5307) #include <asm/m5307sim.h> +#include <asm/mcfintc.h> #elif defined(CONFIG_M532x) #include <asm/m532xsim.h> #elif defined(CONFIG_M5407) #include <asm/m5407sim.h> +#include <asm/mcfintc.h> #endif - -/* - * Define the base address of the SIM within the MBAR address space. - */ -#define MCFSIM_BASE 0x0 /* Base address of SIM */ - - -/* - * Bit definitions for the ICR family of registers. - */ -#define MCFSIM_ICR_AUTOVEC 0x80 /* Auto-vectored intr */ -#define MCFSIM_ICR_LEVEL0 0x00 /* Level 0 intr */ -#define MCFSIM_ICR_LEVEL1 0x04 /* Level 1 intr */ -#define MCFSIM_ICR_LEVEL2 0x08 /* Level 2 intr */ -#define MCFSIM_ICR_LEVEL3 0x0c /* Level 3 intr */ -#define MCFSIM_ICR_LEVEL4 0x10 /* Level 4 intr */ -#define MCFSIM_ICR_LEVEL5 0x14 /* Level 5 intr */ -#define MCFSIM_ICR_LEVEL6 0x18 /* Level 6 intr */ -#define MCFSIM_ICR_LEVEL7 0x1c /* Level 7 intr */ - -#define MCFSIM_ICR_PRI0 0x00 /* Priority 0 intr */ -#define MCFSIM_ICR_PRI1 0x01 /* Priority 1 intr */ -#define MCFSIM_ICR_PRI2 0x02 /* Priority 2 intr */ -#define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */ - -/* - * Bit definitions for the Interrupt Mask register (IMR). - */ -#define MCFSIM_IMR_EINT1 0x0002 /* External intr # 1 */ -#define MCFSIM_IMR_EINT2 0x0004 /* External intr # 2 */ -#define MCFSIM_IMR_EINT3 0x0008 /* External intr # 3 */ -#define MCFSIM_IMR_EINT4 0x0010 /* External intr # 4 */ -#define MCFSIM_IMR_EINT5 0x0020 /* External intr # 5 */ -#define MCFSIM_IMR_EINT6 0x0040 /* External intr # 6 */ -#define MCFSIM_IMR_EINT7 0x0080 /* External intr # 7 */ - -#define MCFSIM_IMR_SWD 0x0100 /* Software Watchdog intr */ -#define MCFSIM_IMR_TIMER1 0x0200 /* TIMER 1 intr */ -#define MCFSIM_IMR_TIMER2 0x0400 /* TIMER 2 intr */ -#define MCFSIM_IMR_MBUS 0x0800 /* MBUS intr */ -#define MCFSIM_IMR_UART1 0x1000 /* UART 1 intr */ -#define MCFSIM_IMR_UART2 0x2000 /* UART 2 intr */ - -#if defined(CONFIG_M5206e) -#define MCFSIM_IMR_DMA1 0x4000 /* DMA 1 intr */ -#define MCFSIM_IMR_DMA2 0x8000 /* DMA 2 intr */ -#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) -#define MCFSIM_IMR_DMA0 0x4000 /* DMA 0 intr */ -#define MCFSIM_IMR_DMA1 0x8000 /* DMA 1 intr */ -#define MCFSIM_IMR_DMA2 0x10000 /* DMA 2 intr */ -#define MCFSIM_IMR_DMA3 0x20000 /* DMA 3 intr */ -#endif - -/* - * Mask for all of the SIM devices. Some parts have more or less - * SIM devices. This is a catchall for the sandard set. - */ -#ifndef MCFSIM_IMR_MASKALL -#define MCFSIM_IMR_MASKALL 0x3ffe /* All intr sources */ -#endif - - -/* - * PIT interrupt settings, if not found in mXXXXsim.h file. - */ -#ifndef ICR_INTRCONF -#define ICR_INTRCONF 0x2b /* PIT1 level 5, priority 3 */ -#endif -#ifndef MCFPIT_IMR -#define MCFPIT_IMR MCFINTC_IMRH -#endif -#ifndef MCFPIT_IMR_IBIT -#define MCFPIT_IMR_IBIT (1 << (MCFINT_PIT1 - 32)) -#endif - - -#ifndef __ASSEMBLY__ -/* - * Definition for the interrupt auto-vectoring support. - */ -extern void mcf_autovector(unsigned int vec); -#endif /* __ASSEMBLY__ */ - /****************************************************************************/ #endif /* mcfsim_h */ diff --git a/arch/m68k/include/asm/mcfsmc.h b/arch/m68k/include/asm/mcfsmc.h index 2d7a4dbd968..527bea5d678 100644 --- a/arch/m68k/include/asm/mcfsmc.h +++ b/arch/m68k/include/asm/mcfsmc.h @@ -167,15 +167,15 @@ void smc_remap(unsigned int ioaddr) static int once = 0; extern unsigned short ppdata; if (once++ == 0) { - *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADDR)) = 0x00ec; + *((volatile unsigned short *)MCFSIM_PADDR) = 0x00ec; ppdata |= 0x0080; - *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata; + *((volatile unsigned short *)MCFSIM_PADAT) = ppdata; outw(0x0001, ioaddr + BANK_SELECT); outw(0x0001, ioaddr + BANK_SELECT); outw(0x0067, ioaddr + BASE); ppdata &= ~0x0080; - *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata; + *((volatile unsigned short *)MCFSIM_PADAT) = ppdata; } *((volatile unsigned short *)(MCF_MBAR+MCFSIM_CSCR3)) = 0x1180; diff --git a/arch/m68k/include/asm/nettel.h b/arch/m68k/include/asm/nettel.h index 0299f6a2dee..4dec2d9fb99 100644 --- a/arch/m68k/include/asm/nettel.h +++ b/arch/m68k/include/asm/nettel.h @@ -48,14 +48,14 @@ extern volatile unsigned short ppdata; static __inline__ unsigned int mcf_getppdata(void) { volatile unsigned short *pp; - pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT); + pp = (volatile unsigned short *) MCFSIM_PADAT; return((unsigned int) *pp); } static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits) { volatile unsigned short *pp; - pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT); + pp = (volatile unsigned short *) MCFSIM_PADAT; ppdata = (ppdata & ~mask) | bits; *pp = ppdata; } diff --git a/arch/m68k/include/asm/page_no.h b/arch/m68k/include/asm/page_no.h index 9aa3f90f485..1f31b060cc8 100644 --- a/arch/m68k/include/asm/page_no.h +++ b/arch/m68k/include/asm/page_no.h @@ -1,10 +1,12 @@ #ifndef _M68KNOMMU_PAGE_H #define _M68KNOMMU_PAGE_H +#include <linux/const.h> + /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT (12) -#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) #include <asm/setup.h> diff --git a/arch/m68k/include/asm/pinmux.h b/arch/m68k/include/asm/pinmux.h new file mode 100644 index 00000000000..119ee686dbd --- /dev/null +++ b/arch/m68k/include/asm/pinmux.h @@ -0,0 +1,30 @@ +/* + * Coldfire generic GPIO pinmux support. + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef pinmux_h +#define pinmux_h + +#define MCFPINMUX_NONE -1 + +extern int mcf_pinmux_request(unsigned, unsigned); +extern void mcf_pinmux_release(unsigned, unsigned); + +static inline int mcf_pinmux_is_valid(unsigned pinmux) +{ + return pinmux != MCFPINMUX_NONE; +} + +#endif + diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h index fc3f2c22f2b..74fd674b15a 100644 --- a/arch/m68k/include/asm/processor.h +++ b/arch/m68k/include/asm/processor.h @@ -1,5 +1,170 @@ -#ifdef __uClinux__ -#include "processor_no.h" +/* + * include/asm-m68k/processor.h + * + * Copyright (C) 1995 Hamish Macdonald + */ + +#ifndef __ASM_M68K_PROCESSOR_H +#define __ASM_M68K_PROCESSOR_H + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ __label__ _l; _l: &&_l;}) + +#include <linux/thread_info.h> +#include <asm/segment.h> +#include <asm/fpu.h> +#include <asm/ptrace.h> + +static inline unsigned long rdusp(void) +{ +#ifdef CONFIG_COLDFIRE + extern unsigned int sw_usp; + return sw_usp; #else -#include "processor_mm.h" + unsigned long usp; + __asm__ __volatile__("move %/usp,%0" : "=a" (usp)); + return usp; +#endif +} + +static inline void wrusp(unsigned long usp) +{ +#ifdef CONFIG_COLDFIRE + extern unsigned int sw_usp; + sw_usp = usp; +#else + __asm__ __volatile__("move %0,%/usp" : : "a" (usp)); +#endif +} + +/* + * User space process size: 3.75GB. This is hardcoded into a few places, + * so don't change it unless you know what you are doing. + */ +#ifndef CONFIG_SUN3 +#define TASK_SIZE (0xF0000000UL) +#else +#define TASK_SIZE (0x0E000000UL) +#endif + +#ifdef __KERNEL__ +#define STACK_TOP TASK_SIZE +#define STACK_TOP_MAX STACK_TOP +#endif + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#ifdef CONFIG_MMU +#ifndef CONFIG_SUN3 +#define TASK_UNMAPPED_BASE 0xC0000000UL +#else +#define TASK_UNMAPPED_BASE 0x0A000000UL +#endif +#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr) +#else +#define TASK_UNMAPPED_BASE 0 +#endif + +struct thread_struct { + unsigned long ksp; /* kernel stack pointer */ + unsigned long usp; /* user stack pointer */ + unsigned short sr; /* saved status register */ + unsigned short fs; /* saved fs (sfc, dfc) */ + unsigned long crp[2]; /* cpu root pointer */ + unsigned long esp0; /* points to SR of stack frame */ + unsigned long faddr; /* info about last fault */ + int signo, code; + unsigned long fp[8*3]; + unsigned long fpcntl[3]; /* fp control regs */ + unsigned char fpstate[FPSTATESIZE]; /* floating point state */ + struct thread_info info; +}; + +#define INIT_THREAD { \ + .ksp = sizeof(init_stack) + (unsigned long) init_stack, \ + .sr = PS_S, \ + .fs = __KERNEL_DS, \ + .info = INIT_THREAD_INFO(init_task), \ +} + +#ifdef CONFIG_MMU +/* + * Do necessary setup to start up a newly executed thread. + */ +static inline void start_thread(struct pt_regs * regs, unsigned long pc, + unsigned long usp) +{ + /* reads from user space */ + set_fs(USER_DS); + + regs->pc = pc; + regs->sr &= ~0x2000; + wrusp(usp); +} + +#else + +/* + * Coldfire stacks need to be re-aligned on trap exit, conventional + * 68k can handle this case cleanly. + */ +#ifdef CONFIG_COLDFIRE +#define reformat(_regs) do { (_regs)->format = 0x4; } while(0) +#else +#define reformat(_regs) do { } while (0) +#endif + +#define start_thread(_regs, _pc, _usp) \ +do { \ + set_fs(USER_DS); /* reads from user space */ \ + (_regs)->pc = (_pc); \ + ((struct switch_stack *)(_regs))[-1].a6 = 0; \ + reformat(_regs); \ + if (current->mm) \ + (_regs)->d5 = current->mm->start_data; \ + (_regs)->sr &= ~0x2000; \ + wrusp(_usp); \ +} while(0) + +#endif + +/* Forward declaration, a strange C thing */ +struct task_struct; + +/* Free all resources held by a thread. */ +static inline void release_thread(struct task_struct *dead_task) +{ +} + +/* Prepare to copy thread state - unlazy all lazy status */ +#define prepare_to_copy(tsk) do { } while (0) + +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + +/* + * Free current thread data structures etc.. + */ +static inline void exit_thread(void) +{ +} + +extern unsigned long thread_saved_pc(struct task_struct *tsk); + +unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) \ + ({ \ + unsigned long eip = 0; \ + if ((tsk)->thread.esp0 > PAGE_SIZE && \ + (virt_addr_valid((tsk)->thread.esp0))) \ + eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ + eip; }) +#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) + +#define cpu_relax() barrier() + #endif diff --git a/arch/m68k/include/asm/processor_mm.h b/arch/m68k/include/asm/processor_mm.h deleted file mode 100644 index 1f61ef53f0e..00000000000 --- a/arch/m68k/include/asm/processor_mm.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * include/asm-m68k/processor.h - * - * Copyright (C) 1995 Hamish Macdonald - */ - -#ifndef __ASM_M68K_PROCESSOR_H -#define __ASM_M68K_PROCESSOR_H - -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). - */ -#define current_text_addr() ({ __label__ _l; _l: &&_l;}) - -#include <linux/thread_info.h> -#include <asm/segment.h> -#include <asm/fpu.h> -#include <asm/ptrace.h> - -static inline unsigned long rdusp(void) -{ - unsigned long usp; - - __asm__ __volatile__("move %/usp,%0" : "=a" (usp)); - return usp; -} - -static inline void wrusp(unsigned long usp) -{ - __asm__ __volatile__("move %0,%/usp" : : "a" (usp)); -} - -/* - * User space process size: 3.75GB. This is hardcoded into a few places, - * so don't change it unless you know what you are doing. - */ -#ifndef CONFIG_SUN3 -#define TASK_SIZE (0xF0000000UL) -#else -#define TASK_SIZE (0x0E000000UL) -#endif - -#ifdef __KERNEL__ -#define STACK_TOP TASK_SIZE -#define STACK_TOP_MAX STACK_TOP -#endif - -/* This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -#ifndef CONFIG_SUN3 -#define TASK_UNMAPPED_BASE 0xC0000000UL -#else -#define TASK_UNMAPPED_BASE 0x0A000000UL -#endif -#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr) - -struct thread_struct { - unsigned long ksp; /* kernel stack pointer */ - unsigned long usp; /* user stack pointer */ - unsigned short sr; /* saved status register */ - unsigned short fs; /* saved fs (sfc, dfc) */ - unsigned long crp[2]; /* cpu root pointer */ - unsigned long esp0; /* points to SR of stack frame */ - unsigned long faddr; /* info about last fault */ - int signo, code; - unsigned long fp[8*3]; - unsigned long fpcntl[3]; /* fp control regs */ - unsigned char fpstate[FPSTATESIZE]; /* floating point state */ - struct thread_info info; -}; - -#define INIT_THREAD { \ - .ksp = sizeof(init_stack) + (unsigned long) init_stack, \ - .sr = PS_S, \ - .fs = __KERNEL_DS, \ - .info = INIT_THREAD_INFO(init_task), \ -} - -/* - * Do necessary setup to start up a newly executed thread. - */ -static inline void start_thread(struct pt_regs * regs, unsigned long pc, - unsigned long usp) -{ - /* reads from user space */ - set_fs(USER_DS); - - regs->pc = pc; - regs->sr &= ~0x2000; - wrusp(usp); -} - -/* Forward declaration, a strange C thing */ -struct task_struct; - -/* Free all resources held by a thread. */ -static inline void release_thread(struct task_struct *dead_task) -{ -} - -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy(tsk) do { } while (0) - -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); - -/* - * Free current thread data structures etc.. - */ -static inline void exit_thread(void) -{ -} - -extern unsigned long thread_saved_pc(struct task_struct *tsk); - -unsigned long get_wchan(struct task_struct *p); - -#define KSTK_EIP(tsk) \ - ({ \ - unsigned long eip = 0; \ - if ((tsk)->thread.esp0 > PAGE_SIZE && \ - (virt_addr_valid((tsk)->thread.esp0))) \ - eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ - eip; }) -#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) - -#define cpu_relax() barrier() - -#endif diff --git a/arch/m68k/include/asm/processor_no.h b/arch/m68k/include/asm/processor_no.h deleted file mode 100644 index 7a1e0ba35f5..00000000000 --- a/arch/m68k/include/asm/processor_no.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * include/asm-m68knommu/processor.h - * - * Copyright (C) 1995 Hamish Macdonald - */ - -#ifndef __ASM_M68K_PROCESSOR_H -#define __ASM_M68K_PROCESSOR_H - -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). - */ -#define current_text_addr() ({ __label__ _l; _l: &&_l;}) - -#include <linux/compiler.h> -#include <linux/threads.h> -#include <asm/types.h> -#include <asm/segment.h> -#include <asm/fpu.h> -#include <asm/ptrace.h> -#include <asm/current.h> - -static inline unsigned long rdusp(void) -{ -#ifdef CONFIG_COLDFIRE - extern unsigned int sw_usp; - return(sw_usp); -#else - unsigned long usp; - __asm__ __volatile__("move %/usp,%0" : "=a" (usp)); - return usp; -#endif -} - -static inline void wrusp(unsigned long usp) -{ -#ifdef CONFIG_COLDFIRE - extern unsigned int sw_usp; - sw_usp = usp; -#else - __asm__ __volatile__("move %0,%/usp" : : "a" (usp)); -#endif -} - -/* - * User space process size: 3.75GB. This is hardcoded into a few places, - * so don't change it unless you know what you are doing. - */ -#define TASK_SIZE (0xF0000000UL) - -/* - * This decides where the kernel will search for a free chunk of vm - * space during mmap's. We won't be using it - */ -#define TASK_UNMAPPED_BASE 0 - -/* - * if you change this structure, you must change the code and offsets - * in m68k/machasm.S - */ - -struct thread_struct { - unsigned long ksp; /* kernel stack pointer */ - unsigned long usp; /* user stack pointer */ - unsigned short sr; /* saved status register */ - unsigned short fs; /* saved fs (sfc, dfc) */ - unsigned long crp[2]; /* cpu root pointer */ - unsigned long esp0; /* points to SR of stack frame */ - unsigned long fp[8*3]; - unsigned long fpcntl[3]; /* fp control regs */ - unsigned char fpstate[FPSTATESIZE]; /* floating point state */ -}; - -#define INIT_THREAD { \ - .ksp = sizeof(init_stack) + (unsigned long) init_stack, \ - .sr = PS_S, \ - .fs = __KERNEL_DS, \ -} - -/* - * Coldfire stacks need to be re-aligned on trap exit, conventional - * 68k can handle this case cleanly. - */ -#if defined(CONFIG_COLDFIRE) -#define reformat(_regs) do { (_regs)->format = 0x4; } while(0) -#else -#define reformat(_regs) do { } while (0) -#endif - -/* - * Do necessary setup to start up a newly executed thread. - * - * pass the data segment into user programs if it exists, - * it can't hurt anything as far as I can tell - */ -#define start_thread(_regs, _pc, _usp) \ -do { \ - set_fs(USER_DS); /* reads from user space */ \ - (_regs)->pc = (_pc); \ - ((struct switch_stack *)(_regs))[-1].a6 = 0; \ - reformat(_regs); \ - if (current->mm) \ - (_regs)->d5 = current->mm->start_data; \ - (_regs)->sr &= ~0x2000; \ - wrusp(_usp); \ -} while(0) - -/* Forward declaration, a strange C thing */ -struct task_struct; - -/* Free all resources held by a thread. */ -static inline void release_thread(struct task_struct *dead_task) -{ -} - -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy(tsk) do { } while (0) - -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); - -/* - * Free current thread data structures etc.. - */ -static inline void exit_thread(void) -{ -} - -unsigned long thread_saved_pc(struct task_struct *tsk); -unsigned long get_wchan(struct task_struct *p); - -#define KSTK_EIP(tsk) \ - ({ \ - unsigned long eip = 0; \ - if ((tsk)->thread.esp0 > PAGE_SIZE && \ - (virt_addr_valid((tsk)->thread.esp0))) \ - eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ - eip; }) -#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) - -#define cpu_relax() barrier() - -#endif diff --git a/arch/m68k/include/asm/timex.h b/arch/m68k/include/asm/timex.h index b87f2f278f6..6759dad954f 100644 --- a/arch/m68k/include/asm/timex.h +++ b/arch/m68k/include/asm/timex.h @@ -3,10 +3,23 @@ * * m68k architecture timex specifications */ -#ifndef _ASMm68k_TIMEX_H -#define _ASMm68k_TIMEX_H +#ifndef _ASMm68K_TIMEX_H +#define _ASMm68K_TIMEX_H +#ifdef CONFIG_COLDFIRE +/* + * CLOCK_TICK_RATE should give the underlying frequency of the tick timer + * to make ntp work best. For Coldfires, that's the main clock. + */ +#include <asm/coldfire.h> +#define CLOCK_TICK_RATE MCF_CLK +#else +/* + * This default CLOCK_TICK_RATE is probably wrong for many 68k boards + * Users of those boards will need to check and modify accordingly + */ #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ +#endif typedef unsigned long cycles_t; diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig index 534376299a9..e2201b90aa2 100644 --- a/arch/m68knommu/Kconfig +++ b/arch/m68knommu/Kconfig @@ -47,6 +47,10 @@ config GENERIC_FIND_NEXT_BIT bool default y +config GENERIC_GPIO + bool + default n + config GENERIC_HWEIGHT bool default y @@ -182,6 +186,8 @@ config M527x config COLDFIRE bool depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407) + select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB default y config CLOCK_SET diff --git a/arch/m68knommu/kernel/irq.c b/arch/m68knommu/kernel/irq.c index 56e0f4c55a6..c9cac36d442 100644 --- a/arch/m68knommu/kernel/irq.c +++ b/arch/m68knommu/kernel/irq.c @@ -29,32 +29,6 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs) set_irq_regs(oldregs); } -void ack_bad_irq(unsigned int irq) -{ - printk(KERN_ERR "IRQ: unexpected irq=%d\n", irq); -} - -static struct irq_chip m_irq_chip = { - .name = "M68K-INTC", - .enable = enable_vector, - .disable = disable_vector, - .ack = ack_vector, -}; - -void __init init_IRQ(void) -{ - int irq; - - init_vectors(); - - for (irq = 0; (irq < NR_IRQS); irq++) { - irq_desc[irq].status = IRQ_DISABLED; - irq_desc[irq].action = NULL; - irq_desc[irq].depth = 1; - irq_desc[irq].chip = &m_irq_chip; - } -} - int show_interrupts(struct seq_file *p, void *v) { struct irqaction *ap; diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c index d182b2f7221..c2aa717de08 100644 --- a/arch/m68knommu/kernel/time.c +++ b/arch/m68knommu/kernel/time.c @@ -69,7 +69,7 @@ static unsigned long read_rtc_mmss(void) if ((year += 1900) < 1970) year += 100; - return mktime(year, mon, day, hour, min, sec);; + return mktime(year, mon, day, hour, min, sec); } unsigned long read_persistent_clock(void) diff --git a/arch/m68knommu/lib/checksum.c b/arch/m68knommu/lib/checksum.c index 269d83bfbbe..eccf25d3d73 100644 --- a/arch/m68knommu/lib/checksum.c +++ b/arch/m68knommu/lib/checksum.c @@ -92,6 +92,7 @@ out: return result; } +#ifdef CONFIG_COLDFIRE /* * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. @@ -100,6 +101,7 @@ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) { return (__force __sum16)~do_csum(iph,ihl*4); } +#endif /* * computes the checksum of a memory block at buff, length len, @@ -127,15 +129,6 @@ __wsum csum_partial(const void *buff, int len, __wsum sum) EXPORT_SYMBOL(csum_partial); /* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ -__sum16 ip_compute_csum(const void *buff, int len) -{ - return (__force __sum16)~do_csum(buff,len); -} - -/* * copy from fs while checksumming, otherwise like csum_partial */ diff --git a/arch/m68knommu/platform/5206/Makefile b/arch/m68knommu/platform/5206/Makefile index a439d9ab3f2..113c3339006 100644 --- a/arch/m68knommu/platform/5206/Makefile +++ b/arch/m68knommu/platform/5206/Makefile @@ -14,5 +14,5 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y := config.o +obj-y := config.o gpio.o diff --git a/arch/m68knommu/platform/5206/config.c b/arch/m68knommu/platform/5206/config.c index f6f79874e9a..9c335465e66 100644 --- a/arch/m68knommu/platform/5206/config.c +++ b/arch/m68knommu/platform/5206/config.c @@ -49,11 +49,11 @@ static void __init m5206_uart_init_line(int line, int irq) if (line == 0) { writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); writeb(irq, MCFUART_BASE1 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); + mcf_mapirq2imr(irq, MCFINTC_UART0); } else if (line == 1) { writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); writeb(irq, MCFUART_BASE2 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); + mcf_mapirq2imr(irq, MCFINTC_UART1); } } @@ -68,38 +68,19 @@ static void __init m5206_uarts_init(void) /***************************************************************************/ -void mcf_autovector(unsigned int vec) +static void __init m5206_timers_init(void) { - volatile unsigned char *mbar; - unsigned char icr; - - if ((vec >= 25) && (vec <= 31)) { - vec -= 25; - mbar = (volatile unsigned char *) MCF_MBAR; - icr = MCFSIM_ICR_AUTOVEC | (vec << 3); - *(mbar + MCFSIM_ICR1 + vec) = icr; - vec = 0x1 << (vec + 1); - mcf_setimr(mcf_getimr() & ~vec); - } -} - -/***************************************************************************/ - -void mcf_settimericr(unsigned int timer, unsigned int level) -{ - volatile unsigned char *icrp; - unsigned int icr, imr; - - if (timer <= 2) { - switch (timer) { - case 2: icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break; - default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break; - } - - icrp = (volatile unsigned char *) (MCF_MBAR + icr); - *icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3; - mcf_setimr(mcf_getimr() & ~imr); - } + /* Timer1 is always used as system timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER1ICR); + mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1); + +#ifdef CONFIG_HIGHPROFILE + /* Timer2 is to be used as a high speed profile timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER2ICR); + mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2); +#endif } /***************************************************************************/ @@ -117,15 +98,20 @@ void m5206_cpu_reset(void) void __init config_BSP(char *commandp, int size) { - mcf_setimr(MCFSIM_IMR_MASKALL); mach_reset = m5206_cpu_reset; + m5206_timers_init(); + m5206_uarts_init(); + + /* Only support the external interrupts on their primary level */ + mcf_mapirq2imr(25, MCFINTC_EINT1); + mcf_mapirq2imr(28, MCFINTC_EINT4); + mcf_mapirq2imr(31, MCFINTC_EINT7); } /***************************************************************************/ static int __init init_BSP(void) { - m5206_uarts_init(); platform_add_devices(m5206_devices, ARRAY_SIZE(m5206_devices)); return 0; } diff --git a/arch/m68knommu/platform/5206/gpio.c b/arch/m68knommu/platform/5206/gpio.c new file mode 100644 index 00000000000..60f779ce165 --- /dev/null +++ b/arch/m68knommu/platform/5206/gpio.c @@ -0,0 +1,49 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfgpio.h> + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PP", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 8, + }, + .pddr = MCFSIM_PADDR, + .podr = MCFSIM_PADAT, + .ppdr = MCFSIM_PADAT, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/arch/m68knommu/platform/5206e/Makefile b/arch/m68knommu/platform/5206e/Makefile index a439d9ab3f2..113c3339006 100644 --- a/arch/m68knommu/platform/5206e/Makefile +++ b/arch/m68knommu/platform/5206e/Makefile @@ -14,5 +14,5 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y := config.o +obj-y := config.o gpio.o diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c index 65887799db8..0f41ba82a3b 100644 --- a/arch/m68knommu/platform/5206e/config.c +++ b/arch/m68knommu/platform/5206e/config.c @@ -15,6 +15,7 @@ #include <asm/machdep.h> #include <asm/coldfire.h> #include <asm/mcfsim.h> +#include <asm/mcfuart.h> #include <asm/mcfdma.h> #include <asm/mcfuart.h> @@ -49,11 +50,11 @@ static void __init m5206e_uart_init_line(int line, int irq) if (line == 0) { writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); writeb(irq, MCFUART_BASE1 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); + mcf_mapirq2imr(irq, MCFINTC_UART0); } else if (line == 1) { writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); writeb(irq, MCFUART_BASE2 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); + mcf_mapirq2imr(irq, MCFINTC_UART1); } } @@ -68,38 +69,19 @@ static void __init m5206e_uarts_init(void) /***************************************************************************/ -void mcf_autovector(unsigned int vec) -{ - volatile unsigned char *mbar; - unsigned char icr; - - if ((vec >= 25) && (vec <= 31)) { - vec -= 25; - mbar = (volatile unsigned char *) MCF_MBAR; - icr = MCFSIM_ICR_AUTOVEC | (vec << 3); - *(mbar + MCFSIM_ICR1 + vec) = icr; - vec = 0x1 << (vec + 1); - mcf_setimr(mcf_getimr() & ~vec); - } -} - -/***************************************************************************/ - -void mcf_settimericr(unsigned int timer, unsigned int level) +static void __init m5206e_timers_init(void) { - volatile unsigned char *icrp; - unsigned int icr, imr; - - if (timer <= 2) { - switch (timer) { - case 2: icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break; - default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break; - } - - icrp = (volatile unsigned char *) (MCF_MBAR + icr); - *icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3; - mcf_setimr(mcf_getimr() & ~imr); - } + /* Timer1 is always used as system timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER1ICR); + mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1); + +#ifdef CONFIG_HIGHPROFILE + /* Timer2 is to be used as a high speed profile timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER2ICR); + mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2); +#endif } /***************************************************************************/ @@ -117,8 +99,6 @@ void m5206e_cpu_reset(void) void __init config_BSP(char *commandp, int size) { - mcf_setimr(MCFSIM_IMR_MASKALL); - #if defined(CONFIG_NETtel) /* Copy command line from FLASH to local buffer... */ memcpy(commandp, (char *) 0xf0004000, size); @@ -126,13 +106,19 @@ void __init config_BSP(char *commandp, int size) #endif /* CONFIG_NETtel */ mach_reset = m5206e_cpu_reset; + m5206e_timers_init(); + m5206e_uarts_init(); + + /* Only support the external interrupts on their primary level */ + mcf_mapirq2imr(25, MCFINTC_EINT1); + mcf_mapirq2imr(28, MCFINTC_EINT4); + mcf_mapirq2imr(31, MCFINTC_EINT7); } /***************************************************************************/ static int __init init_BSP(void) { - m5206e_uarts_init(); platform_add_devices(m5206e_devices, ARRAY_SIZE(m5206e_devices)); return 0; } diff --git a/arch/m68knommu/platform/5206e/gpio.c b/arch/m68knommu/platform/5206e/gpio.c new file mode 100644 index 00000000000..60f779ce165 --- /dev/null +++ b/arch/m68knommu/platform/5206e/gpio.c @@ -0,0 +1,49 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfgpio.h> + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PP", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 8, + }, + .pddr = MCFSIM_PADDR, + .podr = MCFSIM_PADAT, + .ppdr = MCFSIM_PADAT, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/arch/m68knommu/platform/520x/Makefile b/arch/m68knommu/platform/520x/Makefile index a50e76acc8f..435ab3483dc 100644 --- a/arch/m68knommu/platform/520x/Makefile +++ b/arch/m68knommu/platform/520x/Makefile @@ -14,4 +14,4 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y := config.o +obj-y := config.o gpio.o diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68knommu/platform/520x/config.c index 1c43a8aec69..92614de42cd 100644 --- a/arch/m68knommu/platform/520x/config.c +++ b/arch/m68knommu/platform/520x/config.c @@ -81,20 +81,11 @@ static struct platform_device *m520x_devices[] __initdata = { /***************************************************************************/ -#define INTC0 (MCF_MBAR + MCFICM_INTC0) - static void __init m520x_uart_init_line(int line, int irq) { - u32 imr; u16 par; u8 par2; - writeb(0x03, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line); - - imr = readl(INTC0 + MCFINTC_IMRL); - imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1); - writel(imr, INTC0 + MCFINTC_IMRL); - switch (line) { case 0: par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART); @@ -131,18 +122,8 @@ static void __init m520x_uarts_init(void) static void __init m520x_fec_init(void) { - u32 imr; u8 v; - /* Unmask FEC interrupts at ColdFire interrupt controller */ - writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 36); - writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 40); - writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 42); - - imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH); - imr &= ~0x0001FFF0; - writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH); - /* Set multi-function pins to ethernet mode */ v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FEC); writeb(v | 0xf0, MCF_IPSBAR + MCF_GPIO_PAR_FEC); @@ -153,17 +134,6 @@ static void __init m520x_fec_init(void) /***************************************************************************/ -/* - * Program the vector to be an auto-vectored. - */ - -void mcf_autovector(unsigned int vec) -{ - /* Everything is auto-vectored on the 520x devices */ -} - -/***************************************************************************/ - static void m520x_cpu_reset(void) { local_irq_disable(); diff --git a/arch/m68knommu/platform/520x/gpio.c b/arch/m68knommu/platform/520x/gpio.c new file mode 100644 index 00000000000..15b5bb62a69 --- /dev/null +++ b/arch/m68knommu/platform/520x/gpio.c @@ -0,0 +1,211 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfgpio.h> + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PIRQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 8, + }, + .pddr = MCFEPORT_EPDDR, + .podr = MCFEPORT_EPDR, + .ppdr = MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 8, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_BUSCTL, + .podr = MCFGPIO_PODR_BUSCTL, + .ppdr = MCFGPIO_PPDSDR_BUSCTL, + .setr = MCFGPIO_PPDSDR_BUSCTL, + .clrr = MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "BE", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 16, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_BE, + .podr = MCFGPIO_PODR_BE, + .ppdr = MCFGPIO_PPDSDR_BE, + .setr = MCFGPIO_PPDSDR_BE, + .clrr = MCFGPIO_PCLRR_BE, + }, + { + .gpio_chip = { + .label = "CS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 25, + .ngpio = 3, + }, + .pddr = MCFGPIO_PDDR_CS, + .podr = MCFGPIO_PODR_CS, + .ppdr = MCFGPIO_PPDSDR_CS, + .setr = MCFGPIO_PPDSDR_CS, + .clrr = MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "FECI2C", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 32, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_FECI2C, + .podr = MCFGPIO_PODR_FECI2C, + .ppdr = MCFGPIO_PPDSDR_FECI2C, + .setr = MCFGPIO_PPDSDR_FECI2C, + .clrr = MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "QSPI", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 40, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_QSPI, + .podr = MCFGPIO_PODR_QSPI, + .ppdr = MCFGPIO_PPDSDR_QSPI, + .setr = MCFGPIO_PPDSDR_QSPI, + .clrr = MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "TIMER", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 48, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_TIMER, + .podr = MCFGPIO_PODR_TIMER, + .ppdr = MCFGPIO_PPDSDR_TIMER, + .setr = MCFGPIO_PPDSDR_TIMER, + .clrr = MCFGPIO_PCLRR_TIMER, + }, + { + .gpio_chip = { + .label = "UART", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 56, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_UART, + .podr = MCFGPIO_PODR_UART, + .ppdr = MCFGPIO_PPDSDR_UART, + .setr = MCFGPIO_PPDSDR_UART, + .clrr = MCFGPIO_PCLRR_UART, + }, + { + .gpio_chip = { + .label = "FECH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 64, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FECH, + .podr = MCFGPIO_PODR_FECH, + .ppdr = MCFGPIO_PPDSDR_FECH, + .setr = MCFGPIO_PPDSDR_FECH, + .clrr = MCFGPIO_PCLRR_FECH, + }, + { + .gpio_chip = { + .label = "FECL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 72, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FECL, + .podr = MCFGPIO_PODR_FECL, + .ppdr = MCFGPIO_PPDSDR_FECL, + .setr = MCFGPIO_PPDSDR_FECL, + .clrr = MCFGPIO_PCLRR_FECL, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/arch/m68knommu/platform/523x/Makefile b/arch/m68knommu/platform/523x/Makefile index 5694d593f02..b8f9b45440c 100644 --- a/arch/m68knommu/platform/523x/Makefile +++ b/arch/m68knommu/platform/523x/Makefile @@ -14,4 +14,4 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y := config.o +obj-y := config.o gpio.o diff --git a/arch/m68knommu/platform/523x/config.c b/arch/m68knommu/platform/523x/config.c index 961fefebca1..6ba84f2aa39 100644 --- a/arch/m68knommu/platform/523x/config.c +++ b/arch/m68knommu/platform/523x/config.c @@ -82,66 +82,20 @@ static struct platform_device *m523x_devices[] __initdata = { /***************************************************************************/ -#define INTC0 (MCF_MBAR + MCFICM_INTC0) - -static void __init m523x_uart_init_line(int line, int irq) -{ - u32 imr; - - if ((line < 0) || (line > 2)) - return; - - writeb(0x30+line, (INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line)); - - imr = readl(INTC0 + MCFINTC_IMRL); - imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1); - writel(imr, INTC0 + MCFINTC_IMRL); -} - -static void __init m523x_uarts_init(void) -{ - const int nrlines = ARRAY_SIZE(m523x_uart_platform); - int line; - - for (line = 0; (line < nrlines); line++) - m523x_uart_init_line(line, m523x_uart_platform[line].irq); -} - -/***************************************************************************/ - static void __init m523x_fec_init(void) { - u32 imr; - - /* Unmask FEC interrupts at ColdFire interrupt controller */ - writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23); - writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27); - writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29); - - imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH); - imr &= ~0xf; - writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH); - imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL); - imr &= ~0xff800001; - writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL); -} - -/***************************************************************************/ - -void mcf_disableall(void) -{ - *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff; - *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff; + u16 par; + u8 v; + + /* Set multi-function pins to ethernet use */ + par = readw(MCF_IPSBAR + 0x100082); + writew(par | 0xf00, MCF_IPSBAR + 0x100082); + v = readb(MCF_IPSBAR + 0x100078); + writeb(v | 0xc0, MCF_IPSBAR + 0x100078); } /***************************************************************************/ -void mcf_autovector(unsigned int vec) -{ - /* Everything is auto-vectored on the 523x */ -} -/***************************************************************************/ - static void m523x_cpu_reset(void) { local_irq_disable(); @@ -152,16 +106,14 @@ static void m523x_cpu_reset(void) void __init config_BSP(char *commandp, int size) { - mcf_disableall(); mach_reset = m523x_cpu_reset; - m523x_uarts_init(); - m523x_fec_init(); } /***************************************************************************/ static int __init init_BSP(void) { + m523x_fec_init(); platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices)); return 0; } diff --git a/arch/m68knommu/platform/523x/gpio.c b/arch/m68knommu/platform/523x/gpio.c new file mode 100644 index 00000000000..f02840d54d3 --- /dev/null +++ b/arch/m68knommu/platform/523x/gpio.c @@ -0,0 +1,283 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfgpio.h> + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PIRQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 8, + }, + .pddr = MCFEPORT_EPDDR, + .podr = MCFEPORT_EPDR, + .ppdr = MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "ADDR", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 13, + .ngpio = 3, + }, + .pddr = MCFGPIO_PDDR_ADDR, + .podr = MCFGPIO_PODR_ADDR, + .ppdr = MCFGPIO_PPDSDR_ADDR, + .setr = MCFGPIO_PPDSDR_ADDR, + .clrr = MCFGPIO_PCLRR_ADDR, + }, + { + .gpio_chip = { + .label = "DATAH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 16, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_DATAH, + .podr = MCFGPIO_PODR_DATAH, + .ppdr = MCFGPIO_PPDSDR_DATAH, + .setr = MCFGPIO_PPDSDR_DATAH, + .clrr = MCFGPIO_PCLRR_DATAH, + }, + { + .gpio_chip = { + .label = "DATAL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 24, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_DATAL, + .podr = MCFGPIO_PODR_DATAL, + .ppdr = MCFGPIO_PPDSDR_DATAL, + .setr = MCFGPIO_PPDSDR_DATAL, + .clrr = MCFGPIO_PCLRR_DATAL, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 32, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_BUSCTL, + .podr = MCFGPIO_PODR_BUSCTL, + .ppdr = MCFGPIO_PPDSDR_BUSCTL, + .setr = MCFGPIO_PPDSDR_BUSCTL, + .clrr = MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "BS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 40, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_BS, + .podr = MCFGPIO_PODR_BS, + .ppdr = MCFGPIO_PPDSDR_BS, + .setr = MCFGPIO_PPDSDR_BS, + .clrr = MCFGPIO_PCLRR_BS, + }, + { + .gpio_chip = { + .label = "CS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 49, + .ngpio = 7, + }, + .pddr = MCFGPIO_PDDR_CS, + .podr = MCFGPIO_PODR_CS, + .ppdr = MCFGPIO_PPDSDR_CS, + .setr = MCFGPIO_PPDSDR_CS, + .clrr = MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "SDRAM", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 56, + .ngpio = 6, + }, + .pddr = MCFGPIO_PDDR_SDRAM, + .podr = MCFGPIO_PODR_SDRAM, + .ppdr = MCFGPIO_PPDSDR_SDRAM, + .setr = MCFGPIO_PPDSDR_SDRAM, + .clrr = MCFGPIO_PCLRR_SDRAM, + }, + { + .gpio_chip = { + .label = "FECI2C", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 64, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_FECI2C, + .podr = MCFGPIO_PODR_FECI2C, + .ppdr = MCFGPIO_PPDSDR_FECI2C, + .setr = MCFGPIO_PPDSDR_FECI2C, + .clrr = MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "UARTH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 72, + .ngpio = 2, + }, + .pddr = MCFGPIO_PDDR_UARTH, + .podr = MCFGPIO_PODR_UARTH, + .ppdr = MCFGPIO_PPDSDR_UARTH, + .setr = MCFGPIO_PPDSDR_UARTH, + .clrr = MCFGPIO_PCLRR_UARTH, + }, + { + .gpio_chip = { + .label = "UARTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 80, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_UARTL, + .podr = MCFGPIO_PODR_UARTL, + .ppdr = MCFGPIO_PPDSDR_UARTL, + .setr = MCFGPIO_PPDSDR_UARTL, + .clrr = MCFGPIO_PCLRR_UARTL, + }, + { + .gpio_chip = { + .label = "QSPI", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 88, + .ngpio = 5, + }, + .pddr = MCFGPIO_PDDR_QSPI, + .podr = MCFGPIO_PODR_QSPI, + .ppdr = MCFGPIO_PPDSDR_QSPI, + .setr = MCFGPIO_PPDSDR_QSPI, + .clrr = MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "TIMER", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 96, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_TIMER, + .podr = MCFGPIO_PODR_TIMER, + .ppdr = MCFGPIO_PPDSDR_TIMER, + .setr = MCFGPIO_PPDSDR_TIMER, + .clrr = MCFGPIO_PCLRR_TIMER, + }, + { + .gpio_chip = { + .label = "ETPU", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 104, + .ngpio = 3, + }, + .pddr = MCFGPIO_PDDR_ETPU, + .podr = MCFGPIO_PODR_ETPU, + .ppdr = MCFGPIO_PPDSDR_ETPU, + .setr = MCFGPIO_PPDSDR_ETPU, + .clrr = MCFGPIO_PCLRR_ETPU, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/arch/m68knommu/platform/5249/Makefile b/arch/m68knommu/platform/5249/Makefile index a439d9ab3f2..f56225d1582 100644 --- a/arch/m68knommu/platform/5249/Makefile +++ b/arch/m68knommu/platform/5249/Makefile @@ -14,5 +14,5 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y := config.o +obj-y := config.o gpio.o intc2.o diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c index 93d99882592..646f5ba462f 100644 --- a/arch/m68knommu/platform/5249/config.c +++ b/arch/m68knommu/platform/5249/config.c @@ -48,11 +48,11 @@ static void __init m5249_uart_init_line(int line, int irq) if (line == 0) { writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); + mcf_mapirq2imr(irq, MCFINTC_UART0); } else if (line == 1) { writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); + mcf_mapirq2imr(irq, MCFINTC_UART1); } } @@ -65,38 +65,21 @@ static void __init m5249_uarts_init(void) m5249_uart_init_line(line, m5249_uart_platform[line].irq); } - /***************************************************************************/ -void mcf_autovector(unsigned int vec) +static void __init m5249_timers_init(void) { - volatile unsigned char *mbar; - - if ((vec >= 25) && (vec <= 31)) { - mbar = (volatile unsigned char *) MCF_MBAR; - vec = 0x1 << (vec - 24); - *(mbar + MCFSIM_AVR) |= vec; - mcf_setimr(mcf_getimr() & ~vec); - } -} - -/***************************************************************************/ - -void mcf_settimericr(unsigned int timer, unsigned int level) -{ - volatile unsigned char *icrp; - unsigned int icr, imr; - - if (timer <= 2) { - switch (timer) { - case 2: icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break; - default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break; - } - - icrp = (volatile unsigned char *) (MCF_MBAR + icr); - *icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3; - mcf_setimr(mcf_getimr() & ~imr); - } + /* Timer1 is always used as system timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER1ICR); + mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1); + +#ifdef CONFIG_HIGHPROFILE + /* Timer2 is to be used as a high speed profile timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER2ICR); + mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2); +#endif } /***************************************************************************/ @@ -114,15 +97,15 @@ void m5249_cpu_reset(void) void __init config_BSP(char *commandp, int size) { - mcf_setimr(MCFSIM_IMR_MASKALL); mach_reset = m5249_cpu_reset; + m5249_timers_init(); + m5249_uarts_init(); } /***************************************************************************/ static int __init init_BSP(void) { - m5249_uarts_init(); platform_add_devices(m5249_devices, ARRAY_SIZE(m5249_devices)); return 0; } diff --git a/arch/m68knommu/platform/5249/gpio.c b/arch/m68knommu/platform/5249/gpio.c new file mode 100644 index 00000000000..c611eab8b3b --- /dev/null +++ b/arch/m68knommu/platform/5249/gpio.c @@ -0,0 +1,65 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfgpio.h> + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "GPIO0", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 32, + }, + .pddr = MCFSIM2_GPIOENABLE, + .podr = MCFSIM2_GPIOWRITE, + .ppdr = MCFSIM2_GPIOREAD, + }, + { + .gpio_chip = { + .label = "GPIO1", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .base = 32, + .ngpio = 32, + }, + .pddr = MCFSIM2_GPIO1ENABLE, + .podr = MCFSIM2_GPIO1WRITE, + .ppdr = MCFSIM2_GPIO1READ, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/arch/m68knommu/platform/5249/intc2.c b/arch/m68knommu/platform/5249/intc2.c new file mode 100644 index 00000000000..d09d9da0453 --- /dev/null +++ b/arch/m68knommu/platform/5249/intc2.c @@ -0,0 +1,59 @@ +/* + * intc2.c -- support for the 2nd INTC controller of the 5249 + * + * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com> + * + * 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. + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <asm/coldfire.h> +#include <asm/mcfsim.h> + +static void intc2_irq_gpio_mask(unsigned int irq) +{ + u32 imr; + imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE); + imr &= ~(0x1 << (irq - MCFINTC2_GPIOIRQ0)); + writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE); +} + +static void intc2_irq_gpio_unmask(unsigned int irq) +{ + u32 imr; + imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE); + imr |= (0x1 << (irq - MCFINTC2_GPIOIRQ0)); + writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE); +} + +static void intc2_irq_gpio_ack(unsigned int irq) +{ + writel(0x1 << (irq - MCFINTC2_GPIOIRQ0), MCF_MBAR2 + MCFSIM2_GPIOINTCLEAR); +} + +static struct irq_chip intc2_irq_gpio_chip = { + .name = "CF-INTC2", + .mask = intc2_irq_gpio_mask, + .unmask = intc2_irq_gpio_unmask, + .ack = intc2_irq_gpio_ack, +}; + +static int __init mcf_intc2_init(void) +{ + int irq; + + /* GPIO interrupt sources */ + for (irq = MCFINTC2_GPIOIRQ0; (irq <= MCFINTC2_GPIOIRQ7); irq++) + irq_desc[irq].chip = &intc2_irq_gpio_chip; + + return 0; +} + +arch_initcall(mcf_intc2_init); diff --git a/arch/m68knommu/platform/5272/Makefile b/arch/m68knommu/platform/5272/Makefile index 26135d92b34..93673ef8e2c 100644 --- a/arch/m68knommu/platform/5272/Makefile +++ b/arch/m68knommu/platform/5272/Makefile @@ -14,5 +14,5 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y := config.o +obj-y := config.o gpio.o intc.o diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c index 5f95fcde05f..59278c0887d 100644 --- a/arch/m68knommu/platform/5272/config.c +++ b/arch/m68knommu/platform/5272/config.c @@ -20,12 +20,6 @@ /***************************************************************************/ -extern unsigned int mcf_timervector; -extern unsigned int mcf_profilevector; -extern unsigned int mcf_timerlevel; - -/***************************************************************************/ - /* * Some platforms need software versions of the GPIO data registers. */ @@ -37,11 +31,11 @@ unsigned char ledbank = 0xff; static struct mcf_platform_uart m5272_uart_platform[] = { { .mapbase = MCF_MBAR + MCFUART_BASE1, - .irq = 73, + .irq = MCF_IRQ_UART1, }, { .mapbase = MCF_MBAR + MCFUART_BASE2, - .irq = 74, + .irq = MCF_IRQ_UART2, }, { }, }; @@ -59,18 +53,18 @@ static struct resource m5272_fec_resources[] = { .flags = IORESOURCE_MEM, }, { - .start = 86, - .end = 86, + .start = MCF_IRQ_ERX, + .end = MCF_IRQ_ERX, .flags = IORESOURCE_IRQ, }, { - .start = 87, - .end = 87, + .start = MCF_IRQ_ETX, + .end = MCF_IRQ_ETX, .flags = IORESOURCE_IRQ, }, { - .start = 88, - .end = 88, + .start = MCF_IRQ_ENTC, + .end = MCF_IRQ_ENTC, .flags = IORESOURCE_IRQ, }, }; @@ -94,9 +88,6 @@ static void __init m5272_uart_init_line(int line, int irq) u32 v; if ((line >= 0) && (line < 2)) { - v = (line) ? 0x0e000000 : 0xe0000000; - writel(v, MCF_MBAR + MCFSIM_ICR2); - /* Enable the output lines for the serial ports */ v = readl(MCF_MBAR + MCFSIM_PBCNT); v = (v & ~0x000000ff) | 0x00000055; @@ -119,54 +110,6 @@ static void __init m5272_uarts_init(void) /***************************************************************************/ -static void __init m5272_fec_init(void) -{ - u32 imr; - - /* Unmask FEC interrupts at ColdFire interrupt controller */ - imr = readl(MCF_MBAR + MCFSIM_ICR3); - imr = (imr & ~0x00000fff) | 0x00000ddd; - writel(imr, MCF_MBAR + MCFSIM_ICR3); - - imr = readl(MCF_MBAR + MCFSIM_ICR1); - imr = (imr & ~0x0f000000) | 0x0d000000; - writel(imr, MCF_MBAR + MCFSIM_ICR1); -} - -/***************************************************************************/ - -void mcf_disableall(void) -{ - volatile unsigned long *icrp; - - icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - icrp[0] = 0x88888888; - icrp[1] = 0x88888888; - icrp[2] = 0x88888888; - icrp[3] = 0x88888888; -} - -/***************************************************************************/ - -void mcf_autovector(unsigned int vec) -{ - /* Everything is auto-vectored on the 5272 */ -} - -/***************************************************************************/ - -void mcf_settimericr(int timer, int level) -{ - volatile unsigned long *icrp; - - if ((timer >= 1 ) && (timer <= 4)) { - icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = (0x8 | level) << ((4 - timer) * 4); - } -} - -/***************************************************************************/ - static void m5272_cpu_reset(void) { local_irq_disable(); @@ -190,8 +133,6 @@ void __init config_BSP(char *commandp, int size) *pivrp = 0x40; #endif - mcf_disableall(); - #if defined(CONFIG_NETtel) || defined(CONFIG_SCALES) /* Copy command line from FLASH to local buffer... */ memcpy(commandp, (char *) 0xf0004000, size); @@ -202,8 +143,6 @@ void __init config_BSP(char *commandp, int size) commandp[size-1] = 0; #endif - mcf_timervector = 69; - mcf_profilevector = 70; mach_reset = m5272_cpu_reset; } @@ -212,7 +151,6 @@ void __init config_BSP(char *commandp, int size) static int __init init_BSP(void) { m5272_uarts_init(); - m5272_fec_init(); platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices)); return 0; } diff --git a/arch/m68knommu/platform/5272/gpio.c b/arch/m68knommu/platform/5272/gpio.c new file mode 100644 index 00000000000..459db89a89c --- /dev/null +++ b/arch/m68knommu/platform/5272/gpio.c @@ -0,0 +1,81 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfgpio.h> + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PA", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 16, + }, + .pddr = MCFSIM_PADDR, + .podr = MCFSIM_PADAT, + .ppdr = MCFSIM_PADAT, + }, + { + .gpio_chip = { + .label = "PB", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .base = 16, + .ngpio = 16, + }, + .pddr = MCFSIM_PBDDR, + .podr = MCFSIM_PBDAT, + .ppdr = MCFSIM_PBDAT, + }, + { + .gpio_chip = { + .label = "PC", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .base = 32, + .ngpio = 16, + }, + .pddr = MCFSIM_PCDDR, + .podr = MCFSIM_PCDAT, + .ppdr = MCFSIM_PCDAT, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/arch/m68knommu/platform/5272/intc.c b/arch/m68knommu/platform/5272/intc.c new file mode 100644 index 00000000000..7081e0a9720 --- /dev/null +++ b/arch/m68knommu/platform/5272/intc.c @@ -0,0 +1,138 @@ +/* + * intc.c -- interrupt controller or ColdFire 5272 SoC + * + * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com> + * + * 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. + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/traps.h> + +/* + * The 5272 ColdFire interrupt controller is nothing like any other + * ColdFire interrupt controller - it truly is completely different. + * Given its age it is unlikely to be used on any other ColdFire CPU. + */ + +/* + * The masking and priproty setting of interrupts on the 5272 is done + * via a set of 4 "Interrupt Controller Registers" (ICR). There is a + * loose mapping of vector number to register and internal bits, but + * a table is the easiest and quickest way to map them. + */ +struct irqmap { + unsigned char icr; + unsigned char index; + unsigned char ack; +}; + +static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = { + /*MCF_IRQ_SPURIOUS*/ { .icr = 0, .index = 0, .ack = 0, }, + /*MCF_IRQ_EINT1*/ { .icr = MCFSIM_ICR1, .index = 28, .ack = 1, }, + /*MCF_IRQ_EINT2*/ { .icr = MCFSIM_ICR1, .index = 24, .ack = 1, }, + /*MCF_IRQ_EINT3*/ { .icr = MCFSIM_ICR1, .index = 20, .ack = 1, }, + /*MCF_IRQ_EINT4*/ { .icr = MCFSIM_ICR1, .index = 16, .ack = 1, }, + /*MCF_IRQ_TIMER1*/ { .icr = MCFSIM_ICR1, .index = 12, .ack = 0, }, + /*MCF_IRQ_TIMER2*/ { .icr = MCFSIM_ICR1, .index = 8, .ack = 0, }, + /*MCF_IRQ_TIMER3*/ { .icr = MCFSIM_ICR1, .index = 4, .ack = 0, }, + /*MCF_IRQ_TIMER4*/ { .icr = MCFSIM_ICR1, .index = 0, .ack = 0, }, + /*MCF_IRQ_UART1*/ { .icr = MCFSIM_ICR2, .index = 28, .ack = 0, }, + /*MCF_IRQ_UART2*/ { .icr = MCFSIM_ICR2, .index = 24, .ack = 0, }, + /*MCF_IRQ_PLIP*/ { .icr = MCFSIM_ICR2, .index = 20, .ack = 0, }, + /*MCF_IRQ_PLIA*/ { .icr = MCFSIM_ICR2, .index = 16, .ack = 0, }, + /*MCF_IRQ_USB0*/ { .icr = MCFSIM_ICR2, .index = 12, .ack = 0, }, + /*MCF_IRQ_USB1*/ { .icr = MCFSIM_ICR2, .index = 8, .ack = 0, }, + /*MCF_IRQ_USB2*/ { .icr = MCFSIM_ICR2, .index = 4, .ack = 0, }, + /*MCF_IRQ_USB3*/ { .icr = MCFSIM_ICR2, .index = 0, .ack = 0, }, + /*MCF_IRQ_USB4*/ { .icr = MCFSIM_ICR3, .index = 28, .ack = 0, }, + /*MCF_IRQ_USB5*/ { .icr = MCFSIM_ICR3, .index = 24, .ack = 0, }, + /*MCF_IRQ_USB6*/ { .icr = MCFSIM_ICR3, .index = 20, .ack = 0, }, + /*MCF_IRQ_USB7*/ { .icr = MCFSIM_ICR3, .index = 16, .ack = 0, }, + /*MCF_IRQ_DMA*/ { .icr = MCFSIM_ICR3, .index = 12, .ack = 0, }, + /*MCF_IRQ_ERX*/ { .icr = MCFSIM_ICR3, .index = 8, .ack = 0, }, + /*MCF_IRQ_ETX*/ { .icr = MCFSIM_ICR3, .index = 4, .ack = 0, }, + /*MCF_IRQ_ENTC*/ { .icr = MCFSIM_ICR3, .index = 0, .ack = 0, }, + /*MCF_IRQ_QSPI*/ { .icr = MCFSIM_ICR4, .index = 28, .ack = 0, }, + /*MCF_IRQ_EINT5*/ { .icr = MCFSIM_ICR4, .index = 24, .ack = 1, }, + /*MCF_IRQ_EINT6*/ { .icr = MCFSIM_ICR4, .index = 20, .ack = 1, }, + /*MCF_IRQ_SWTO*/ { .icr = MCFSIM_ICR4, .index = 16, .ack = 0, }, +}; + +static void intc_irq_mask(unsigned int irq) +{ + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { + u32 v; + irq -= MCFINT_VECBASE; + v = 0x8 << intc_irqmap[irq].index; + writel(v, MCF_MBAR + intc_irqmap[irq].icr); + } +} + +static void intc_irq_unmask(unsigned int irq) +{ + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { + u32 v; + irq -= MCFINT_VECBASE; + v = 0xd << intc_irqmap[irq].index; + writel(v, MCF_MBAR + intc_irqmap[irq].icr); + } +} + +static void intc_irq_ack(unsigned int irq) +{ + /* Only external interrupts are acked */ + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { + irq -= MCFINT_VECBASE; + if (intc_irqmap[irq].ack) { + u32 v; + v = 0xd << intc_irqmap[irq].index; + writel(v, MCF_MBAR + intc_irqmap[irq].icr); + } + } +} + +static int intc_irq_set_type(unsigned int irq, unsigned int type) +{ + /* We can set the edge type here for external interrupts */ + return 0; +} + +static struct irq_chip intc_irq_chip = { + .name = "CF-INTC", + .mask = intc_irq_mask, + .unmask = intc_irq_unmask, + .ack = intc_irq_ack, + .set_type = intc_irq_set_type, +}; + +void __init init_IRQ(void) +{ + int irq; + + init_vectors(); + + /* Mask all interrupt sources */ + writel(0x88888888, MCF_MBAR + MCFSIM_ICR1); + writel(0x88888888, MCF_MBAR + MCFSIM_ICR2); + writel(0x88888888, MCF_MBAR + MCFSIM_ICR3); + writel(0x88888888, MCF_MBAR + MCFSIM_ICR4); + + for (irq = 0; (irq < NR_IRQS); irq++) { + irq_desc[irq].status = IRQ_DISABLED; + irq_desc[irq].action = NULL; + irq_desc[irq].depth = 1; + irq_desc[irq].chip = &intc_irq_chip; + intc_irq_set_type(irq, 0); + } +} + diff --git a/arch/m68knommu/platform/527x/Makefile b/arch/m68knommu/platform/527x/Makefile index 26135d92b34..3d90e6d9245 100644 --- a/arch/m68knommu/platform/527x/Makefile +++ b/arch/m68knommu/platform/527x/Makefile @@ -14,5 +14,5 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y := config.o +obj-y := config.o gpio.o diff --git a/arch/m68knommu/platform/527x/config.c b/arch/m68knommu/platform/527x/config.c index f746439cfd3..fa51be17283 100644 --- a/arch/m68knommu/platform/527x/config.c +++ b/arch/m68knommu/platform/527x/config.c @@ -116,23 +116,13 @@ static struct platform_device *m527x_devices[] __initdata = { /***************************************************************************/ -#define INTC0 (MCF_MBAR + MCFICM_INTC0) - static void __init m527x_uart_init_line(int line, int irq) { u16 sepmask; - u32 imr; if ((line < 0) || (line > 2)) return; - /* level 6, line based priority */ - writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line); - - imr = readl(INTC0 + MCFINTC_IMRL); - imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1); - writel(imr, INTC0 + MCFINTC_IMRL); - /* * External Pin Mask Setting & Enable External Pin for Interface */ @@ -157,32 +147,11 @@ static void __init m527x_uarts_init(void) /***************************************************************************/ -static void __init m527x_fec_irq_init(int nr) -{ - unsigned long base; - u32 imr; - - base = MCF_IPSBAR + (nr ? MCFICM_INTC1 : MCFICM_INTC0); - - writeb(0x28, base + MCFINTC_ICR0 + 23); - writeb(0x27, base + MCFINTC_ICR0 + 27); - writeb(0x26, base + MCFINTC_ICR0 + 29); - - imr = readl(base + MCFINTC_IMRH); - imr &= ~0xf; - writel(imr, base + MCFINTC_IMRH); - imr = readl(base + MCFINTC_IMRL); - imr &= ~0xff800001; - writel(imr, base + MCFINTC_IMRL); -} - static void __init m527x_fec_init(void) { u16 par; u8 v; - m527x_fec_irq_init(0); - /* Set multi-function pins to ethernet mode for fec0 */ #if defined(CONFIG_M5271) v = readb(MCF_IPSBAR + 0x100047); @@ -195,8 +164,6 @@ static void __init m527x_fec_init(void) #endif #ifdef CONFIG_FEC2 - m527x_fec_irq_init(1); - /* Set multi-function pins to ethernet mode for fec1 */ par = readw(MCF_IPSBAR + 0x100082); writew(par | 0xa0, MCF_IPSBAR + 0x100082); @@ -207,21 +174,6 @@ static void __init m527x_fec_init(void) /***************************************************************************/ -void mcf_disableall(void) -{ - *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff; - *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff; -} - -/***************************************************************************/ - -void mcf_autovector(unsigned int vec) -{ - /* Everything is auto-vectored on the 5272 */ -} - -/***************************************************************************/ - static void m527x_cpu_reset(void) { local_irq_disable(); @@ -232,7 +184,6 @@ static void m527x_cpu_reset(void) void __init config_BSP(char *commandp, int size) { - mcf_disableall(); mach_reset = m527x_cpu_reset; m527x_uarts_init(); m527x_fec_init(); diff --git a/arch/m68knommu/platform/527x/gpio.c b/arch/m68knommu/platform/527x/gpio.c new file mode 100644 index 00000000000..1028142851a --- /dev/null +++ b/arch/m68knommu/platform/527x/gpio.c @@ -0,0 +1,607 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfgpio.h> + +static struct mcf_gpio_chip mcf_gpio_chips[] = { +#if defined(CONFIG_M5271) + { + .gpio_chip = { + .label = "PIRQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 8, + }, + .pddr = MCFEPORT_EPDDR, + .podr = MCFEPORT_EPDR, + .ppdr = MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "ADDR", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 13, + .ngpio = 3, + }, + .pddr = MCFGPIO_PDDR_ADDR, + .podr = MCFGPIO_PODR_ADDR, + .ppdr = MCFGPIO_PPDSDR_ADDR, + .setr = MCFGPIO_PPDSDR_ADDR, + .clrr = MCFGPIO_PCLRR_ADDR, + }, + { + .gpio_chip = { + .label = "DATAH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 16, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_DATAH, + .podr = MCFGPIO_PODR_DATAH, + .ppdr = MCFGPIO_PPDSDR_DATAH, + .setr = MCFGPIO_PPDSDR_DATAH, + .clrr = MCFGPIO_PCLRR_DATAH, + }, + { + .gpio_chip = { + .label = "DATAL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 24, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_DATAL, + .podr = MCFGPIO_PODR_DATAL, + .ppdr = MCFGPIO_PPDSDR_DATAL, + .setr = MCFGPIO_PPDSDR_DATAL, + .clrr = MCFGPIO_PCLRR_DATAL, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 32, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_BUSCTL, + .podr = MCFGPIO_PODR_BUSCTL, + .ppdr = MCFGPIO_PPDSDR_BUSCTL, + .setr = MCFGPIO_PPDSDR_BUSCTL, + .clrr = MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "BS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 40, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_BS, + .podr = MCFGPIO_PODR_BS, + .ppdr = MCFGPIO_PPDSDR_BS, + .setr = MCFGPIO_PPDSDR_BS, + .clrr = MCFGPIO_PCLRR_BS, + }, + { + .gpio_chip = { + .label = "CS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 49, + .ngpio = 7, + }, + .pddr = MCFGPIO_PDDR_CS, + .podr = MCFGPIO_PODR_CS, + .ppdr = MCFGPIO_PPDSDR_CS, + .setr = MCFGPIO_PPDSDR_CS, + .clrr = MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "SDRAM", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 56, + .ngpio = 6, + }, + .pddr = MCFGPIO_PDDR_SDRAM, + .podr = MCFGPIO_PODR_SDRAM, + .ppdr = MCFGPIO_PPDSDR_SDRAM, + .setr = MCFGPIO_PPDSDR_SDRAM, + .clrr = MCFGPIO_PCLRR_SDRAM, + }, + { + .gpio_chip = { + .label = "FECI2C", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 64, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_FECI2C, + .podr = MCFGPIO_PODR_FECI2C, + .ppdr = MCFGPIO_PPDSDR_FECI2C, + .setr = MCFGPIO_PPDSDR_FECI2C, + .clrr = MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "UARTH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 72, + .ngpio = 2, + }, + .pddr = MCFGPIO_PDDR_UARTH, + .podr = MCFGPIO_PODR_UARTH, + .ppdr = MCFGPIO_PPDSDR_UARTH, + .setr = MCFGPIO_PPDSDR_UARTH, + .clrr = MCFGPIO_PCLRR_UARTH, + }, + { + .gpio_chip = { + .label = "UARTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 80, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_UARTL, + .podr = MCFGPIO_PODR_UARTL, + .ppdr = MCFGPIO_PPDSDR_UARTL, + .setr = MCFGPIO_PPDSDR_UARTL, + .clrr = MCFGPIO_PCLRR_UARTL, + }, + { + .gpio_chip = { + .label = "QSPI", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 88, + .ngpio = 5, + }, + .pddr = MCFGPIO_PDDR_QSPI, + .podr = MCFGPIO_PODR_QSPI, + .ppdr = MCFGPIO_PPDSDR_QSPI, + .setr = MCFGPIO_PPDSDR_QSPI, + .clrr = MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "TIMER", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 96, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_TIMER, + .podr = MCFGPIO_PODR_TIMER, + .ppdr = MCFGPIO_PPDSDR_TIMER, + .setr = MCFGPIO_PPDSDR_TIMER, + .clrr = MCFGPIO_PCLRR_TIMER, + }, +#elif defined(CONFIG_M5275) + { + .gpio_chip = { + .label = "PIRQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 8, + }, + .pddr = MCFEPORT_EPDDR, + .podr = MCFEPORT_EPDR, + .ppdr = MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 8, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_BUSCTL, + .podr = MCFGPIO_PODR_BUSCTL, + .ppdr = MCFGPIO_PPDSDR_BUSCTL, + .setr = MCFGPIO_PPDSDR_BUSCTL, + .clrr = MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "ADDR", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 21, + .ngpio = 3, + }, + .pddr = MCFGPIO_PDDR_ADDR, + .podr = MCFGPIO_PODR_ADDR, + .ppdr = MCFGPIO_PPDSDR_ADDR, + .setr = MCFGPIO_PPDSDR_ADDR, + .clrr = MCFGPIO_PCLRR_ADDR, + }, + { + .gpio_chip = { + .label = "CS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 25, + .ngpio = 7, + }, + .pddr = MCFGPIO_PDDR_CS, + .podr = MCFGPIO_PODR_CS, + .ppdr = MCFGPIO_PPDSDR_CS, + .setr = MCFGPIO_PPDSDR_CS, + .clrr = MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "FEC0H", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 32, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FEC0H, + .podr = MCFGPIO_PODR_FEC0H, + .ppdr = MCFGPIO_PPDSDR_FEC0H, + .setr = MCFGPIO_PPDSDR_FEC0H, + .clrr = MCFGPIO_PCLRR_FEC0H, + }, + { + .gpio_chip = { + .label = "FEC0L", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 40, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FEC0L, + .podr = MCFGPIO_PODR_FEC0L, + .ppdr = MCFGPIO_PPDSDR_FEC0L, + .setr = MCFGPIO_PPDSDR_FEC0L, + .clrr = MCFGPIO_PCLRR_FEC0L, + }, + { + .gpio_chip = { + .label = "FECI2C", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 48, + .ngpio = 6, + }, + .pddr = MCFGPIO_PDDR_FECI2C, + .podr = MCFGPIO_PODR_FECI2C, + .ppdr = MCFGPIO_PPDSDR_FECI2C, + .setr = MCFGPIO_PPDSDR_FECI2C, + .clrr = MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "QSPI", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 56, + .ngpio = 7, + }, + .pddr = MCFGPIO_PDDR_QSPI, + .podr = MCFGPIO_PODR_QSPI, + .ppdr = MCFGPIO_PPDSDR_QSPI, + .setr = MCFGPIO_PPDSDR_QSPI, + .clrr = MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "SDRAM", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 64, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_SDRAM, + .podr = MCFGPIO_PODR_SDRAM, + .ppdr = MCFGPIO_PPDSDR_SDRAM, + .setr = MCFGPIO_PPDSDR_SDRAM, + .clrr = MCFGPIO_PCLRR_SDRAM, + }, + { + .gpio_chip = { + .label = "TIMERH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 72, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_TIMERH, + .podr = MCFGPIO_PODR_TIMERH, + .ppdr = MCFGPIO_PPDSDR_TIMERH, + .setr = MCFGPIO_PPDSDR_TIMERH, + .clrr = MCFGPIO_PCLRR_TIMERH, + }, + { + .gpio_chip = { + .label = "TIMERL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 80, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_TIMERL, + .podr = MCFGPIO_PODR_TIMERL, + .ppdr = MCFGPIO_PPDSDR_TIMERL, + .setr = MCFGPIO_PPDSDR_TIMERL, + .clrr = MCFGPIO_PCLRR_TIMERL, + }, + { + .gpio_chip = { + .label = "UARTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 88, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_UARTL, + .podr = MCFGPIO_PODR_UARTL, + .ppdr = MCFGPIO_PPDSDR_UARTL, + .setr = MCFGPIO_PPDSDR_UARTL, + .clrr = MCFGPIO_PCLRR_UARTL, + }, + { + .gpio_chip = { + .label = "FEC1H", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 96, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FEC1H, + .podr = MCFGPIO_PODR_FEC1H, + .ppdr = MCFGPIO_PPDSDR_FEC1H, + .setr = MCFGPIO_PPDSDR_FEC1H, + .clrr = MCFGPIO_PCLRR_FEC1H, + }, + { + .gpio_chip = { + .label = "FEC1L", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 104, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FEC1L, + .podr = MCFGPIO_PODR_FEC1L, + .ppdr = MCFGPIO_PPDSDR_FEC1L, + .setr = MCFGPIO_PPDSDR_FEC1L, + .clrr = MCFGPIO_PCLRR_FEC1L, + }, + { + .gpio_chip = { + .label = "BS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 114, + .ngpio = 2, + }, + .pddr = MCFGPIO_PDDR_BS, + .podr = MCFGPIO_PODR_BS, + .ppdr = MCFGPIO_PPDSDR_BS, + .setr = MCFGPIO_PPDSDR_BS, + .clrr = MCFGPIO_PCLRR_BS, + }, + { + .gpio_chip = { + .label = "IRQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 121, + .ngpio = 7, + }, + .pddr = MCFGPIO_PDDR_IRQ, + .podr = MCFGPIO_PODR_IRQ, + .ppdr = MCFGPIO_PPDSDR_IRQ, + .setr = MCFGPIO_PPDSDR_IRQ, + .clrr = MCFGPIO_PCLRR_IRQ, + }, + { + .gpio_chip = { + .label = "USBH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 128, + .ngpio = 1, + }, + .pddr = MCFGPIO_PDDR_USBH, + .podr = MCFGPIO_PODR_USBH, + .ppdr = MCFGPIO_PPDSDR_USBH, + .setr = MCFGPIO_PPDSDR_USBH, + .clrr = MCFGPIO_PCLRR_USBH, + }, + { + .gpio_chip = { + .label = "USBL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 136, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_USBL, + .podr = MCFGPIO_PODR_USBL, + .ppdr = MCFGPIO_PPDSDR_USBL, + .setr = MCFGPIO_PPDSDR_USBL, + .clrr = MCFGPIO_PCLRR_USBL, + }, + { + .gpio_chip = { + .label = "UARTH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 144, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_UARTH, + .podr = MCFGPIO_PODR_UARTH, + .ppdr = MCFGPIO_PPDSDR_UARTH, + .setr = MCFGPIO_PPDSDR_UARTH, + .clrr = MCFGPIO_PCLRR_UARTH, + }, +#endif +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/arch/m68knommu/platform/528x/Makefile b/arch/m68knommu/platform/528x/Makefile index 26135d92b34..3d90e6d9245 100644 --- a/arch/m68knommu/platform/528x/Makefile +++ b/arch/m68knommu/platform/528x/Makefile @@ -14,5 +14,5 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y := config.o +obj-y := config.o gpio.o diff --git a/arch/m68knommu/platform/528x/config.c b/arch/m68knommu/platform/528x/config.c index a1d1a61c4fe..6e608d1836f 100644 --- a/arch/m68knommu/platform/528x/config.c +++ b/arch/m68knommu/platform/528x/config.c @@ -3,8 +3,8 @@ /* * linux/arch/m68knommu/platform/528x/config.c * - * Sub-architcture dependant initialization code for the Motorola - * 5280 and 5282 CPUs. + * Sub-architcture dependant initialization code for the Freescale + * 5280, 5281 and 5282 CPUs. * * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com) * Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com) @@ -15,20 +15,13 @@ #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> -#include <linux/interrupt.h> #include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/spi/flash.h> #include <linux/io.h> #include <asm/machdep.h> #include <asm/coldfire.h> #include <asm/mcfsim.h> #include <asm/mcfuart.h> -#ifdef CONFIG_MTD_PARTITIONS -#include <linux/mtd/partitions.h> -#endif - /***************************************************************************/ static struct mcf_platform_uart m528x_uart_platform[] = { @@ -91,23 +84,13 @@ static struct platform_device *m528x_devices[] __initdata = { /***************************************************************************/ -#define INTC0 (MCF_MBAR + MCFICM_INTC0) - static void __init m528x_uart_init_line(int line, int irq) { u8 port; - u32 imr; if ((line < 0) || (line > 2)) return; - /* level 6, line based priority */ - writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line); - - imr = readl(INTC0 + MCFINTC_IMRL); - imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1); - writel(imr, INTC0 + MCFINTC_IMRL); - /* make sure PUAPAR is set for UART0 and UART1 */ if (line < 2) { port = readb(MCF_MBAR + MCF5282_GPIO_PUAPAR); @@ -129,21 +112,8 @@ static void __init m528x_uarts_init(void) static void __init m528x_fec_init(void) { - u32 imr; u16 v16; - /* Unmask FEC interrupts at ColdFire interrupt controller */ - writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23); - writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27); - writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29); - - imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH); - imr &= ~0xf; - writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH); - imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL); - imr &= ~0xff800001; - writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL); - /* Set multi-function pins to ethernet mode for fec0 */ v16 = readw(MCF_IPSBAR + 0x100056); writew(v16 | 0xf00, MCF_IPSBAR + 0x100056); @@ -152,21 +122,6 @@ static void __init m528x_fec_init(void) /***************************************************************************/ -void mcf_disableall(void) -{ - *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff; - *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff; -} - -/***************************************************************************/ - -void mcf_autovector(unsigned int vec) -{ - /* Everything is auto-vectored on the 5272 */ -} - -/***************************************************************************/ - static void m528x_cpu_reset(void) { local_irq_disable(); @@ -204,8 +159,6 @@ void wildfiremod_halt(void) void __init config_BSP(char *commandp, int size) { - mcf_disableall(); - #ifdef CONFIG_WILDFIRE mach_halt = wildfire_halt; #endif diff --git a/arch/m68knommu/platform/528x/gpio.c b/arch/m68knommu/platform/528x/gpio.c new file mode 100644 index 00000000000..ec593950696 --- /dev/null +++ b/arch/m68knommu/platform/528x/gpio.c @@ -0,0 +1,438 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfgpio.h> + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "NQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .base = 1, + .ngpio = 8, + }, + .pddr = MCFEPORT_EPDDR, + .podr = MCFEPORT_EPDR, + .ppdr = MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "TA", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 8, + .ngpio = 4, + }, + .pddr = MCFGPTA_GPTDDR, + .podr = MCFGPTA_GPTPORT, + .ppdr = MCFGPTB_GPTPORT, + }, + { + .gpio_chip = { + .label = "TB", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 16, + .ngpio = 4, + }, + .pddr = MCFGPTB_GPTDDR, + .podr = MCFGPTB_GPTPORT, + .ppdr = MCFGPTB_GPTPORT, + }, + { + .gpio_chip = { + .label = "QA", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 24, + .ngpio = 4, + }, + .pddr = MCFQADC_DDRQA, + .podr = MCFQADC_PORTQA, + .ppdr = MCFQADC_PORTQA, + }, + { + .gpio_chip = { + .label = "QB", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 32, + .ngpio = 4, + }, + .pddr = MCFQADC_DDRQB, + .podr = MCFQADC_PORTQB, + .ppdr = MCFQADC_PORTQB, + }, + { + .gpio_chip = { + .label = "A", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 40, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRA, + .podr = MCFGPIO_PORTA, + .ppdr = MCFGPIO_PORTAP, + .setr = MCFGPIO_SETA, + .clrr = MCFGPIO_CLRA, + }, + { + .gpio_chip = { + .label = "B", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 48, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRB, + .podr = MCFGPIO_PORTB, + .ppdr = MCFGPIO_PORTBP, + .setr = MCFGPIO_SETB, + .clrr = MCFGPIO_CLRB, + }, + { + .gpio_chip = { + .label = "C", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 56, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRC, + .podr = MCFGPIO_PORTC, + .ppdr = MCFGPIO_PORTCP, + .setr = MCFGPIO_SETC, + .clrr = MCFGPIO_CLRC, + }, + { + .gpio_chip = { + .label = "D", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 64, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRD, + .podr = MCFGPIO_PORTD, + .ppdr = MCFGPIO_PORTDP, + .setr = MCFGPIO_SETD, + .clrr = MCFGPIO_CLRD, + }, + { + .gpio_chip = { + .label = "E", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 72, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRE, + .podr = MCFGPIO_PORTE, + .ppdr = MCFGPIO_PORTEP, + .setr = MCFGPIO_SETE, + .clrr = MCFGPIO_CLRE, + }, + { + .gpio_chip = { + .label = "F", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 80, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRF, + .podr = MCFGPIO_PORTF, + .ppdr = MCFGPIO_PORTFP, + .setr = MCFGPIO_SETF, + .clrr = MCFGPIO_CLRF, + }, + { + .gpio_chip = { + .label = "G", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 88, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRG, + .podr = MCFGPIO_PORTG, + .ppdr = MCFGPIO_PORTGP, + .setr = MCFGPIO_SETG, + .clrr = MCFGPIO_CLRG, + }, + { + .gpio_chip = { + .label = "H", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 96, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRH, + .podr = MCFGPIO_PORTH, + .ppdr = MCFGPIO_PORTHP, + .setr = MCFGPIO_SETH, + .clrr = MCFGPIO_CLRH, + }, + { + .gpio_chip = { + .label = "J", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 104, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRJ, + .podr = MCFGPIO_PORTJ, + .ppdr = MCFGPIO_PORTJP, + .setr = MCFGPIO_SETJ, + .clrr = MCFGPIO_CLRJ, + }, + { + .gpio_chip = { + .label = "DD", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 112, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRDD, + .podr = MCFGPIO_PORTDD, + .ppdr = MCFGPIO_PORTDDP, + .setr = MCFGPIO_SETDD, + .clrr = MCFGPIO_CLRDD, + }, + { + .gpio_chip = { + .label = "EH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 120, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDREH, + .podr = MCFGPIO_PORTEH, + .ppdr = MCFGPIO_PORTEHP, + .setr = MCFGPIO_SETEH, + .clrr = MCFGPIO_CLREH, + }, + { + .gpio_chip = { + .label = "EL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 128, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDREL, + .podr = MCFGPIO_PORTEL, + .ppdr = MCFGPIO_PORTELP, + .setr = MCFGPIO_SETEL, + .clrr = MCFGPIO_CLREL, + }, + { + .gpio_chip = { + .label = "AS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 136, + .ngpio = 6, + }, + .pddr = MCFGPIO_DDRAS, + .podr = MCFGPIO_PORTAS, + .ppdr = MCFGPIO_PORTASP, + .setr = MCFGPIO_SETAS, + .clrr = MCFGPIO_CLRAS, + }, + { + .gpio_chip = { + .label = "QS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 144, + .ngpio = 7, + }, + .pddr = MCFGPIO_DDRQS, + .podr = MCFGPIO_PORTQS, + .ppdr = MCFGPIO_PORTQSP, + .setr = MCFGPIO_SETQS, + .clrr = MCFGPIO_CLRQS, + }, + { + .gpio_chip = { + .label = "SD", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 152, + .ngpio = 6, + }, + .pddr = MCFGPIO_DDRSD, + .podr = MCFGPIO_PORTSD, + .ppdr = MCFGPIO_PORTSDP, + .setr = MCFGPIO_SETSD, + .clrr = MCFGPIO_CLRSD, + }, + { + .gpio_chip = { + .label = "TC", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 160, + .ngpio = 4, + }, + .pddr = MCFGPIO_DDRTC, + .podr = MCFGPIO_PORTTC, + .ppdr = MCFGPIO_PORTTCP, + .setr = MCFGPIO_SETTC, + .clrr = MCFGPIO_CLRTC, + }, + { + .gpio_chip = { + .label = "TD", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 168, + .ngpio = 4, + }, + .pddr = MCFGPIO_DDRTD, + .podr = MCFGPIO_PORTTD, + .ppdr = MCFGPIO_PORTTDP, + .setr = MCFGPIO_SETTD, + .clrr = MCFGPIO_CLRTD, + }, + { + .gpio_chip = { + .label = "UA", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 176, + .ngpio = 4, + }, + .pddr = MCFGPIO_DDRUA, + .podr = MCFGPIO_PORTUA, + .ppdr = MCFGPIO_PORTUAP, + .setr = MCFGPIO_SETUA, + .clrr = MCFGPIO_CLRUA, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile index cfd586860fd..667db659845 100644 --- a/arch/m68knommu/platform/5307/Makefile +++ b/arch/m68knommu/platform/5307/Makefile @@ -14,5 +14,5 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y += config.o +obj-y += config.o gpio.o diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c index 39da9e9ff67..00900ac06a9 100644 --- a/arch/m68knommu/platform/5307/config.c +++ b/arch/m68knommu/platform/5307/config.c @@ -21,12 +21,6 @@ /***************************************************************************/ -extern unsigned int mcf_timervector; -extern unsigned int mcf_profilevector; -extern unsigned int mcf_timerlevel; - -/***************************************************************************/ - /* * Some platforms need software versions of the GPIO data registers. */ @@ -64,11 +58,11 @@ static void __init m5307_uart_init_line(int line, int irq) if (line == 0) { writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); + mcf_mapirq2imr(irq, MCFINTC_UART0); } else if (line == 1) { writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); + mcf_mapirq2imr(irq, MCFINTC_UART1); } } @@ -83,35 +77,19 @@ static void __init m5307_uarts_init(void) /***************************************************************************/ -void mcf_autovector(unsigned int vec) -{ - volatile unsigned char *mbar; - - if ((vec >= 25) && (vec <= 31)) { - mbar = (volatile unsigned char *) MCF_MBAR; - vec = 0x1 << (vec - 24); - *(mbar + MCFSIM_AVR) |= vec; - mcf_setimr(mcf_getimr() & ~vec); - } -} - -/***************************************************************************/ - -void mcf_settimericr(unsigned int timer, unsigned int level) +static void __init m5307_timers_init(void) { - volatile unsigned char *icrp; - unsigned int icr, imr; - - if (timer <= 2) { - switch (timer) { - case 2: icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break; - default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break; - } - - icrp = (volatile unsigned char *) (MCF_MBAR + icr); - *icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3; - mcf_setimr(mcf_getimr() & ~imr); - } + /* Timer1 is always used as system timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER1ICR); + mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1); + +#ifdef CONFIG_HIGHPROFILE + /* Timer2 is to be used as a high speed profile timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER2ICR); + mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2); +#endif } /***************************************************************************/ @@ -129,20 +107,22 @@ void m5307_cpu_reset(void) void __init config_BSP(char *commandp, int size) { - mcf_setimr(MCFSIM_IMR_MASKALL); - #if defined(CONFIG_NETtel) || \ defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA) /* Copy command line from FLASH to local buffer... */ memcpy(commandp, (char *) 0xf0004000, size); commandp[size-1] = 0; - /* Different timer setup - to prevent device clash */ - mcf_timervector = 30; - mcf_profilevector = 31; - mcf_timerlevel = 6; #endif mach_reset = m5307_cpu_reset; + m5307_timers_init(); + m5307_uarts_init(); + + /* Only support the external interrupts on their primary level */ + mcf_mapirq2imr(25, MCFINTC_EINT1); + mcf_mapirq2imr(27, MCFINTC_EINT3); + mcf_mapirq2imr(29, MCFINTC_EINT5); + mcf_mapirq2imr(31, MCFINTC_EINT7); #ifdef CONFIG_BDM_DISABLE /* @@ -158,7 +138,6 @@ void __init config_BSP(char *commandp, int size) static int __init init_BSP(void) { - m5307_uarts_init(); platform_add_devices(m5307_devices, ARRAY_SIZE(m5307_devices)); return 0; } diff --git a/arch/m68knommu/platform/5307/gpio.c b/arch/m68knommu/platform/5307/gpio.c new file mode 100644 index 00000000000..8da5880e406 --- /dev/null +++ b/arch/m68knommu/platform/5307/gpio.c @@ -0,0 +1,49 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfgpio.h> + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PP", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 16, + }, + .pddr = MCFSIM_PADDR, + .podr = MCFSIM_PADAT, + .ppdr = MCFSIM_PADAT, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/arch/m68knommu/platform/532x/Makefile b/arch/m68knommu/platform/532x/Makefile index e431912f562..4cc23245bcd 100644 --- a/arch/m68knommu/platform/532x/Makefile +++ b/arch/m68knommu/platform/532x/Makefile @@ -15,4 +15,4 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 #obj-y := config.o usb-mcf532x.o spi-mcf532x.o -obj-y := config.o +obj-y := config.o gpio.o diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68knommu/platform/532x/config.c index cdb761971f7..d632948e64e 100644 --- a/arch/m68knommu/platform/532x/config.c +++ b/arch/m68knommu/platform/532x/config.c @@ -20,7 +20,6 @@ #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> -#include <linux/interrupt.h> #include <linux/io.h> #include <asm/machdep.h> #include <asm/coldfire.h> @@ -31,12 +30,6 @@ /***************************************************************************/ -extern unsigned int mcf_timervector; -extern unsigned int mcf_profilevector; -extern unsigned int mcf_timerlevel; - -/***************************************************************************/ - static struct mcf_platform_uart m532x_uart_platform[] = { { .mapbase = MCFUART_BASE1, @@ -88,6 +81,7 @@ static struct platform_device m532x_fec = { .num_resources = ARRAY_SIZE(m532x_fec_resources), .resource = m532x_fec_resources, }; + static struct platform_device *m532x_devices[] __initdata = { &m532x_uart, &m532x_fec, @@ -98,18 +92,11 @@ static struct platform_device *m532x_devices[] __initdata = { static void __init m532x_uart_init_line(int line, int irq) { if (line == 0) { - MCF_INTC0_ICR26 = 0x3; - MCF_INTC0_CIMR = 26; /* GPIO initialization */ MCF_GPIO_PAR_UART |= 0x000F; } else if (line == 1) { - MCF_INTC0_ICR27 = 0x3; - MCF_INTC0_CIMR = 27; /* GPIO initialization */ MCF_GPIO_PAR_UART |= 0x0FF0; - } else if (line == 2) { - MCF_INTC0_ICR28 = 0x3; - MCF_INTC0_CIMR = 28; } } @@ -125,14 +112,6 @@ static void __init m532x_uarts_init(void) static void __init m532x_fec_init(void) { - /* Unmask FEC interrupts at ColdFire interrupt controller */ - MCF_INTC0_ICR36 = 0x2; - MCF_INTC0_ICR40 = 0x2; - MCF_INTC0_ICR42 = 0x2; - - MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK36 | - MCF_INTC_IMRH_INT_MASK40 | MCF_INTC_IMRH_INT_MASK42); - /* Set multi-function pins to ethernet mode for fec0 */ MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC | MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO); @@ -142,26 +121,6 @@ static void __init m532x_fec_init(void) /***************************************************************************/ -void mcf_settimericr(unsigned int timer, unsigned int level) -{ - volatile unsigned char *icrp; - unsigned int icr; - unsigned char irq; - - if (timer <= 2) { - switch (timer) { - case 2: irq = 33; icr = MCFSIM_ICR_TIMER2; break; - default: irq = 32; icr = MCFSIM_ICR_TIMER1; break; - } - - icrp = (volatile unsigned char *) (icr); - *icrp = level; - mcf_enable_irq0(irq); - } -} - -/***************************************************************************/ - static void m532x_cpu_reset(void) { local_irq_disable(); @@ -172,8 +131,6 @@ static void m532x_cpu_reset(void) void __init config_BSP(char *commandp, int size) { - mcf_setimr(MCFSIM_IMR_MASKALL); - #if !defined(CONFIG_BOOTPARAM) /* Copy command line from FLASH to local buffer... */ memcpy(commandp, (char *) 0x4000, 4); @@ -185,10 +142,6 @@ void __init config_BSP(char *commandp, int size) } #endif - mcf_timervector = 64+32; - mcf_profilevector = 64+33; - mach_reset = m532x_cpu_reset; - #ifdef CONFIG_BDM_DISABLE /* * Disable the BDM clocking. This also turns off most of the rest of @@ -438,8 +391,8 @@ void gpio_init(void) /* Initialize TIN3 as a GPIO output to enable the write half of the latch */ MCF_GPIO_PAR_TIMER = 0x00; - MCF_GPIO_PDDR_TIMER = 0x08; - MCF_GPIO_PCLRR_TIMER = 0x0; + __raw_writeb(0x08, MCFGPIO_PDDR_TIMER); + __raw_writeb(0x00, MCFGPIO_PCLRR_TIMER); } diff --git a/arch/m68knommu/platform/532x/gpio.c b/arch/m68knommu/platform/532x/gpio.c new file mode 100644 index 00000000000..184b77382c3 --- /dev/null +++ b/arch/m68knommu/platform/532x/gpio.c @@ -0,0 +1,337 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfgpio.h> + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PIRQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 8, + }, + .pddr = MCFEPORT_EPDDR, + .podr = MCFEPORT_EPDR, + .ppdr = MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "FECH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 8, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FECH, + .podr = MCFGPIO_PODR_FECH, + .ppdr = MCFGPIO_PPDSDR_FECH, + .setr = MCFGPIO_PPDSDR_FECH, + .clrr = MCFGPIO_PCLRR_FECH, + }, + { + .gpio_chip = { + .label = "FECL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 16, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FECL, + .podr = MCFGPIO_PODR_FECL, + .ppdr = MCFGPIO_PPDSDR_FECL, + .setr = MCFGPIO_PPDSDR_FECL, + .clrr = MCFGPIO_PCLRR_FECL, + }, + { + .gpio_chip = { + .label = "SSI", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 24, + .ngpio = 5, + }, + .pddr = MCFGPIO_PDDR_SSI, + .podr = MCFGPIO_PODR_SSI, + .ppdr = MCFGPIO_PPDSDR_SSI, + .setr = MCFGPIO_PPDSDR_SSI, + .clrr = MCFGPIO_PCLRR_SSI, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 32, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_BUSCTL, + .podr = MCFGPIO_PODR_BUSCTL, + .ppdr = MCFGPIO_PPDSDR_BUSCTL, + .setr = MCFGPIO_PPDSDR_BUSCTL, + .clrr = MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "BE", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 40, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_BE, + .podr = MCFGPIO_PODR_BE, + .ppdr = MCFGPIO_PPDSDR_BE, + .setr = MCFGPIO_PPDSDR_BE, + .clrr = MCFGPIO_PCLRR_BE, + }, + { + .gpio_chip = { + .label = "CS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 49, + .ngpio = 5, + }, + .pddr = MCFGPIO_PDDR_CS, + .podr = MCFGPIO_PODR_CS, + .ppdr = MCFGPIO_PPDSDR_CS, + .setr = MCFGPIO_PPDSDR_CS, + .clrr = MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "PWM", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 58, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_PWM, + .podr = MCFGPIO_PODR_PWM, + .ppdr = MCFGPIO_PPDSDR_PWM, + .setr = MCFGPIO_PPDSDR_PWM, + .clrr = MCFGPIO_PCLRR_PWM, + }, + { + .gpio_chip = { + .label = "FECI2C", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 64, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_FECI2C, + .podr = MCFGPIO_PODR_FECI2C, + .ppdr = MCFGPIO_PPDSDR_FECI2C, + .setr = MCFGPIO_PPDSDR_FECI2C, + .clrr = MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "UART", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 72, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_UART, + .podr = MCFGPIO_PODR_UART, + .ppdr = MCFGPIO_PPDSDR_UART, + .setr = MCFGPIO_PPDSDR_UART, + .clrr = MCFGPIO_PCLRR_UART, + }, + { + .gpio_chip = { + .label = "QSPI", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 80, + .ngpio = 6, + }, + .pddr = MCFGPIO_PDDR_QSPI, + .podr = MCFGPIO_PODR_QSPI, + .ppdr = MCFGPIO_PPDSDR_QSPI, + .setr = MCFGPIO_PPDSDR_QSPI, + .clrr = MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "TIMER", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 88, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_TIMER, + .podr = MCFGPIO_PODR_TIMER, + .ppdr = MCFGPIO_PPDSDR_TIMER, + .setr = MCFGPIO_PPDSDR_TIMER, + .clrr = MCFGPIO_PCLRR_TIMER, + }, + { + .gpio_chip = { + .label = "LCDDATAH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 96, + .ngpio = 2, + }, + .pddr = MCFGPIO_PDDR_LCDDATAH, + .podr = MCFGPIO_PODR_LCDDATAH, + .ppdr = MCFGPIO_PPDSDR_LCDDATAH, + .setr = MCFGPIO_PPDSDR_LCDDATAH, + .clrr = MCFGPIO_PCLRR_LCDDATAH, + }, + { + .gpio_chip = { + .label = "LCDDATAM", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 104, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_LCDDATAM, + .podr = MCFGPIO_PODR_LCDDATAM, + .ppdr = MCFGPIO_PPDSDR_LCDDATAM, + .setr = MCFGPIO_PPDSDR_LCDDATAM, + .clrr = MCFGPIO_PCLRR_LCDDATAM, + }, + { + .gpio_chip = { + .label = "LCDDATAL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 112, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_LCDDATAL, + .podr = MCFGPIO_PODR_LCDDATAL, + .ppdr = MCFGPIO_PPDSDR_LCDDATAL, + .setr = MCFGPIO_PPDSDR_LCDDATAL, + .clrr = MCFGPIO_PCLRR_LCDDATAL, + }, + { + .gpio_chip = { + .label = "LCDCTLH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 120, + .ngpio = 1, + }, + .pddr = MCFGPIO_PDDR_LCDCTLH, + .podr = MCFGPIO_PODR_LCDCTLH, + .ppdr = MCFGPIO_PPDSDR_LCDCTLH, + .setr = MCFGPIO_PPDSDR_LCDCTLH, + .clrr = MCFGPIO_PCLRR_LCDCTLH, + }, + { + .gpio_chip = { + .label = "LCDCTLL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 128, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_LCDCTLL, + .podr = MCFGPIO_PODR_LCDCTLL, + .ppdr = MCFGPIO_PPDSDR_LCDCTLL, + .setr = MCFGPIO_PPDSDR_LCDCTLL, + .clrr = MCFGPIO_PCLRR_LCDCTLL, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/arch/m68knommu/platform/5407/Makefile b/arch/m68knommu/platform/5407/Makefile index e6035e7a2d3..dee62c5dbaa 100644 --- a/arch/m68knommu/platform/5407/Makefile +++ b/arch/m68knommu/platform/5407/Makefile @@ -14,5 +14,5 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y := config.o +obj-y := config.o gpio.o diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c index b41d942bf8d..70ea789a400 100644 --- a/arch/m68knommu/platform/5407/config.c +++ b/arch/m68knommu/platform/5407/config.c @@ -20,12 +20,6 @@ /***************************************************************************/ -extern unsigned int mcf_timervector; -extern unsigned int mcf_profilevector; -extern unsigned int mcf_timerlevel; - -/***************************************************************************/ - static struct mcf_platform_uart m5407_uart_platform[] = { { .mapbase = MCF_MBAR + MCFUART_BASE1, @@ -55,11 +49,11 @@ static void __init m5407_uart_init_line(int line, int irq) if (line == 0) { writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); + mcf_mapirq2imr(irq, MCFINTC_UART0); } else if (line == 1) { writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); + mcf_mapirq2imr(irq, MCFINTC_UART1); } } @@ -74,35 +68,19 @@ static void __init m5407_uarts_init(void) /***************************************************************************/ -void mcf_autovector(unsigned int vec) -{ - volatile unsigned char *mbar; - - if ((vec >= 25) && (vec <= 31)) { - mbar = (volatile unsigned char *) MCF_MBAR; - vec = 0x1 << (vec - 24); - *(mbar + MCFSIM_AVR) |= vec; - mcf_setimr(mcf_getimr() & ~vec); - } -} - -/***************************************************************************/ - -void mcf_settimericr(unsigned int timer, unsigned int level) +static void __init m5407_timers_init(void) { - volatile unsigned char *icrp; - unsigned int icr, imr; - - if (timer <= 2) { - switch (timer) { - case 2: icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break; - default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break; - } - - icrp = (volatile unsigned char *) (MCF_MBAR + icr); - *icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3; - mcf_setimr(mcf_getimr() & ~imr); - } + /* Timer1 is always used as system timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER1ICR); + mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1); + +#ifdef CONFIG_HIGHPROFILE + /* Timer2 is to be used as a high speed profile timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER2ICR); + mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2); +#endif } /***************************************************************************/ @@ -120,23 +98,21 @@ void m5407_cpu_reset(void) void __init config_BSP(char *commandp, int size) { - mcf_setimr(MCFSIM_IMR_MASKALL); - -#if defined(CONFIG_CLEOPATRA) - /* Different timer setup - to prevent device clash */ - mcf_timervector = 30; - mcf_profilevector = 31; - mcf_timerlevel = 6; -#endif - mach_reset = m5407_cpu_reset; + m5407_timers_init(); + m5407_uarts_init(); + + /* Only support the external interrupts on their primary level */ + mcf_mapirq2imr(25, MCFINTC_EINT1); + mcf_mapirq2imr(27, MCFINTC_EINT3); + mcf_mapirq2imr(29, MCFINTC_EINT5); + mcf_mapirq2imr(31, MCFINTC_EINT7); } /***************************************************************************/ static int __init init_BSP(void) { - m5407_uarts_init(); platform_add_devices(m5407_devices, ARRAY_SIZE(m5407_devices)); return 0; } diff --git a/arch/m68knommu/platform/5407/gpio.c b/arch/m68knommu/platform/5407/gpio.c new file mode 100644 index 00000000000..8da5880e406 --- /dev/null +++ b/arch/m68knommu/platform/5407/gpio.c @@ -0,0 +1,49 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfgpio.h> + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PP", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 16, + }, + .pddr = MCFSIM_PADDR, + .podr = MCFSIM_PADAT, + .ppdr = MCFSIM_PADAT, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/arch/m68knommu/platform/68328/ints.c b/arch/m68knommu/platform/68328/ints.c index 72e56d554f4..b91ee85d4b5 100644 --- a/arch/m68knommu/platform/68328/ints.c +++ b/arch/m68knommu/platform/68328/ints.c @@ -73,34 +73,6 @@ extern e_vector *_ramvec; /* The number of spurious interrupts */ volatile unsigned int num_spurious; -/* - * This function should be called during kernel startup to initialize - * the machine vector table. - */ -void __init init_vectors(void) -{ - int i; - - /* set up the vectors */ - for (i = 72; i < 256; ++i) - _ramvec[i] = (e_vector) bad_interrupt; - - _ramvec[32] = system_call; - - _ramvec[65] = (e_vector) inthandler1; - _ramvec[66] = (e_vector) inthandler2; - _ramvec[67] = (e_vector) inthandler3; - _ramvec[68] = (e_vector) inthandler4; - _ramvec[69] = (e_vector) inthandler5; - _ramvec[70] = (e_vector) inthandler6; - _ramvec[71] = (e_vector) inthandler7; - - IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */ - - /* turn off all interrupts */ - IMR = ~0; -} - /* The 68k family did not have a good way to determine the source * of interrupts until later in the family. The EC000 core does * not provide the vector number on the stack, we vector everything @@ -163,18 +135,54 @@ void process_int(int vec, struct pt_regs *fp) } } -void enable_vector(unsigned int irq) +static void intc_irq_unmask(unsigned int irq) { IMR &= ~(1<<irq); } -void disable_vector(unsigned int irq) +static void intc_irq_mask(unsigned int irq) { IMR |= (1<<irq); } -void ack_vector(unsigned int irq) +static struct irq_chip intc_irq_chip = { + .name = "M68K-INTC", + .mask = intc_irq_mask, + .unmask = intc_irq_unmask, +}; + +/* + * This function should be called during kernel startup to initialize + * the machine vector table. + */ +void __init init_IRQ(void) { - /* Nothing needed */ + int i; + + /* set up the vectors */ + for (i = 72; i < 256; ++i) + _ramvec[i] = (e_vector) bad_interrupt; + + _ramvec[32] = system_call; + + _ramvec[65] = (e_vector) inthandler1; + _ramvec[66] = (e_vector) inthandler2; + _ramvec[67] = (e_vector) inthandler3; + _ramvec[68] = (e_vector) inthandler4; + _ramvec[69] = (e_vector) inthandler5; + _ramvec[70] = (e_vector) inthandler6; + _ramvec[71] = (e_vector) inthandler7; + + IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */ + + /* turn off all interrupts */ + IMR = ~0; + + for (i = 0; (i < NR_IRQS); i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].chip = &intc_irq_chip; + } } diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c index c36781157e0..1143f77caca 100644 --- a/arch/m68knommu/platform/68360/ints.c +++ b/arch/m68knommu/platform/68360/ints.c @@ -37,11 +37,33 @@ extern void *_ramvec[]; /* The number of spurious interrupts */ volatile unsigned int num_spurious; +static void intc_irq_unmask(unsigned int irq) +{ + pquicc->intr_cimr |= (1 << irq); +} + +static void intc_irq_mask(unsigned int irq) +{ + pquicc->intr_cimr &= ~(1 << irq); +} + +static void intc_irq_ack(unsigned int irq) +{ + pquicc->intr_cisr = (1 << irq); +} + +static struct irq_chip intc_irq_chip = { + .name = "M68K-INTC", + .mask = intc_irq_mask, + .unmask = intc_irq_unmask, + .ack = intc_irq_ack, +}; + /* * This function should be called during kernel startup to initialize * the vector table. */ -void init_vectors(void) +void init_IRQ(void) { int i; int vba = (CPM_VECTOR_BASE<<4); @@ -109,20 +131,12 @@ void init_vectors(void) /* turn off all CPM interrupts */ pquicc->intr_cimr = 0x00000000; -} - -void enable_vector(unsigned int irq) -{ - pquicc->intr_cimr |= (1 << irq); -} -void disable_vector(unsigned int irq) -{ - pquicc->intr_cimr &= ~(1 << irq); -} - -void ack_vector(unsigned int irq) -{ - pquicc->intr_cisr = (1 << irq); + for (i = 0; (i < NR_IRQS); i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].chip = &intc_irq_chip; + } } diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile index 1bcb9372353..f72a0e5d999 100644 --- a/arch/m68knommu/platform/coldfire/Makefile +++ b/arch/m68knommu/platform/coldfire/Makefile @@ -15,16 +15,17 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 obj-$(CONFIG_COLDFIRE) += clk.o dma.o entry.o vectors.o -obj-$(CONFIG_M5206) += timers.o -obj-$(CONFIG_M5206e) += timers.o -obj-$(CONFIG_M520x) += pit.o -obj-$(CONFIG_M523x) += pit.o dma_timer.o -obj-$(CONFIG_M5249) += timers.o -obj-$(CONFIG_M527x) += pit.o +obj-$(CONFIG_M5206) += timers.o intc.o +obj-$(CONFIG_M5206e) += timers.o intc.o +obj-$(CONFIG_M520x) += pit.o intc-simr.o +obj-$(CONFIG_M523x) += pit.o dma_timer.o intc-2.o +obj-$(CONFIG_M5249) += timers.o intc.o +obj-$(CONFIG_M527x) += pit.o intc-2.o obj-$(CONFIG_M5272) += timers.o -obj-$(CONFIG_M528x) += pit.o -obj-$(CONFIG_M5307) += timers.o -obj-$(CONFIG_M532x) += timers.o -obj-$(CONFIG_M5407) += timers.o +obj-$(CONFIG_M528x) += pit.o intc-2.o +obj-$(CONFIG_M5307) += timers.o intc.o +obj-$(CONFIG_M532x) += timers.o intc-simr.o +obj-$(CONFIG_M5407) += timers.o intc.o +obj-y += pinmux.o gpio.o extra-y := head.o diff --git a/arch/m68knommu/platform/coldfire/gpio.c b/arch/m68knommu/platform/coldfire/gpio.c new file mode 100644 index 00000000000..ff004579345 --- /dev/null +++ b/arch/m68knommu/platform/coldfire/gpio.c @@ -0,0 +1,127 @@ +/* + * Coldfire generic GPIO support. + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/sysdev.h> + +#include <asm/gpio.h> +#include <asm/pinmux.h> +#include <asm/mcfgpio.h> + +#define MCF_CHIP(chip) container_of(chip, struct mcf_gpio_chip, gpio_chip) + +int mcf_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +{ + unsigned long flags; + MCFGPIO_PORTTYPE dir; + struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); + + local_irq_save(flags); + dir = mcfgpio_read(mcf_chip->pddr); + dir &= ~mcfgpio_bit(chip->base + offset); + mcfgpio_write(dir, mcf_chip->pddr); + local_irq_restore(flags); + + return 0; +} + +int mcf_gpio_get_value(struct gpio_chip *chip, unsigned offset) +{ + struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); + + return mcfgpio_read(mcf_chip->ppdr) & mcfgpio_bit(chip->base + offset); +} + +int mcf_gpio_direction_output(struct gpio_chip *chip, unsigned offset, + int value) +{ + unsigned long flags; + MCFGPIO_PORTTYPE data; + struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); + + local_irq_save(flags); + /* write the value to the output latch */ + data = mcfgpio_read(mcf_chip->podr); + if (value) + data |= mcfgpio_bit(chip->base + offset); + else + data &= ~mcfgpio_bit(chip->base + offset); + mcfgpio_write(data, mcf_chip->podr); + + /* now set the direction to output */ + data = mcfgpio_read(mcf_chip->pddr); + data |= mcfgpio_bit(chip->base + offset); + mcfgpio_write(data, mcf_chip->pddr); + local_irq_restore(flags); + + return 0; +} + +void mcf_gpio_set_value(struct gpio_chip *chip, unsigned offset, int value) +{ + struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); + + unsigned long flags; + MCFGPIO_PORTTYPE data; + + local_irq_save(flags); + data = mcfgpio_read(mcf_chip->podr); + if (value) + data |= mcfgpio_bit(chip->base + offset); + else + data &= ~mcfgpio_bit(chip->base + offset); + mcfgpio_write(data, mcf_chip->podr); + local_irq_restore(flags); +} + +void mcf_gpio_set_value_fast(struct gpio_chip *chip, unsigned offset, int value) +{ + struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); + + if (value) + mcfgpio_write(mcfgpio_bit(chip->base + offset), mcf_chip->setr); + else + mcfgpio_write(~mcfgpio_bit(chip->base + offset), mcf_chip->clrr); +} + +int mcf_gpio_request(struct gpio_chip *chip, unsigned offset) +{ + struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); + + return mcf_chip->gpio_to_pinmux ? + mcf_pinmux_request(mcf_chip->gpio_to_pinmux[offset], 0) : 0; +} + +void mcf_gpio_free(struct gpio_chip *chip, unsigned offset) +{ + struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); + + mcf_gpio_direction_input(chip, offset); + + if (mcf_chip->gpio_to_pinmux) + mcf_pinmux_release(mcf_chip->gpio_to_pinmux[offset], 0); +} + +struct sysdev_class mcf_gpio_sysclass = { + .name = "gpio", +}; + +static int __init mcf_gpio_sysinit(void) +{ + return sysdev_class_register(&mcf_gpio_sysclass); +} + +core_initcall(mcf_gpio_sysinit); diff --git a/arch/m68knommu/platform/coldfire/intc-2.c b/arch/m68knommu/platform/coldfire/intc-2.c new file mode 100644 index 00000000000..5598c8b8661 --- /dev/null +++ b/arch/m68knommu/platform/coldfire/intc-2.c @@ -0,0 +1,93 @@ +/* + * intc-1.c + * + * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com> + * + * 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. + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/traps.h> + +/* + * Each vector needs a unique priority and level asscoiated with it. + * We don't really care so much what they are, we don't rely on the + * tranditional priority interrupt scheme of the m68k/ColdFire. + */ +static u8 intc_intpri = 0x36; + +static void intc_irq_mask(unsigned int irq) +{ + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) { + unsigned long imraddr; + u32 val, imrbit; + + irq -= MCFINT_VECBASE; + imraddr = MCF_IPSBAR; + imraddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0; + imraddr += (irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL; + imrbit = 0x1 << (irq & 0x1f); + + val = __raw_readl(imraddr); + __raw_writel(val | imrbit, imraddr); + } +} + +static void intc_irq_unmask(unsigned int irq) +{ + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) { + unsigned long intaddr, imraddr, icraddr; + u32 val, imrbit; + + irq -= MCFINT_VECBASE; + intaddr = MCF_IPSBAR; + intaddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0; + imraddr = intaddr + ((irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL); + icraddr = intaddr + MCFINTC_ICR0 + (irq & 0x3f); + imrbit = 0x1 << (irq & 0x1f); + + /* Don't set the "maskall" bit! */ + if ((irq & 0x20) == 0) + imrbit |= 0x1; + + if (__raw_readb(icraddr) == 0) + __raw_writeb(intc_intpri--, icraddr); + + val = __raw_readl(imraddr); + __raw_writel(val & ~imrbit, imraddr); + } +} + +static struct irq_chip intc_irq_chip = { + .name = "CF-INTC", + .mask = intc_irq_mask, + .unmask = intc_irq_unmask, +}; + +void __init init_IRQ(void) +{ + int irq; + + init_vectors(); + + /* Mask all interrupt sources */ + __raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL); + __raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC1 + MCFINTC_IMRL); + + for (irq = 0; (irq < NR_IRQS); irq++) { + irq_desc[irq].status = IRQ_DISABLED; + irq_desc[irq].action = NULL; + irq_desc[irq].depth = 1; + irq_desc[irq].chip = &intc_irq_chip; + } +} + diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68knommu/platform/coldfire/intc-simr.c new file mode 100644 index 00000000000..1b01e79c2f6 --- /dev/null +++ b/arch/m68knommu/platform/coldfire/intc-simr.c @@ -0,0 +1,78 @@ +/* + * intc-simr.c + * + * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com> + * + * 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. + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/traps.h> + +static void intc_irq_mask(unsigned int irq) +{ + if (irq >= MCFINT_VECBASE) { + if (irq < MCFINT_VECBASE + 64) + __raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_SIMR); + else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_SIMR) + __raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_SIMR); + } +} + +static void intc_irq_unmask(unsigned int irq) +{ + if (irq >= MCFINT_VECBASE) { + if (irq < MCFINT_VECBASE + 64) + __raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_CIMR); + else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_CIMR) + __raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_CIMR); + } +} + +static int intc_irq_set_type(unsigned int irq, unsigned int type) +{ + if (irq >= MCFINT_VECBASE) { + if (irq < MCFINT_VECBASE + 64) + __raw_writeb(5, MCFINTC0_ICR0 + irq - MCFINT_VECBASE); + else if ((irq < MCFINT_VECBASE) && MCFINTC1_ICR0) + __raw_writeb(5, MCFINTC1_ICR0 + irq - MCFINT_VECBASE - 64); + } + return 0; +} + +static struct irq_chip intc_irq_chip = { + .name = "CF-INTC", + .mask = intc_irq_mask, + .unmask = intc_irq_unmask, + .set_type = intc_irq_set_type, +}; + +void __init init_IRQ(void) +{ + int irq; + + init_vectors(); + + /* Mask all interrupt sources */ + __raw_writeb(0xff, MCFINTC0_SIMR); + if (MCFINTC1_SIMR) + __raw_writeb(0xff, MCFINTC1_SIMR); + + for (irq = 0; (irq < NR_IRQS); irq++) { + irq_desc[irq].status = IRQ_DISABLED; + irq_desc[irq].action = NULL; + irq_desc[irq].depth = 1; + irq_desc[irq].chip = &intc_irq_chip; + intc_irq_set_type(irq, 0); + } +} + diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c new file mode 100644 index 00000000000..a4560c86db7 --- /dev/null +++ b/arch/m68knommu/platform/coldfire/intc.c @@ -0,0 +1,153 @@ +/* + * intc.c -- support for the old ColdFire interrupt controller + * + * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com> + * + * 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. + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <asm/traps.h> +#include <asm/coldfire.h> +#include <asm/mcfsim.h> + +/* + * The mapping of irq number to a mask register bit is not one-to-one. + * The irq numbers are either based on "level" of interrupt or fixed + * for an autovector-able interrupt. So we keep a local data structure + * that maps from irq to mask register. Not all interrupts will have + * an IMR bit. + */ +unsigned char mcf_irq2imr[NR_IRQS]; + +/* + * Define the miniumun and maximum external interrupt numbers. + * This is also used as the "level" interrupt numbers. + */ +#define EIRQ1 25 +#define EIRQ7 31 + +/* + * In the early version 2 core ColdFire parts the IMR register was 16 bits + * in size. Version 3 (and later version 2) core parts have a 32 bit + * sized IMR register. Provide some size independant methods to access the + * IMR register. + */ +#ifdef MCFSIM_IMR_IS_16BITS + +void mcf_setimr(int index) +{ + u16 imr; + imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); + __raw_writew(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR); +} + +void mcf_clrimr(int index) +{ + u16 imr; + imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); + __raw_writew(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR); +} + +void mcf_maskimr(unsigned int mask) +{ + u16 imr; + imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); + imr |= mask; + __raw_writew(imr, MCF_MBAR + MCFSIM_IMR); +} + +#else + +void mcf_setimr(int index) +{ + u32 imr; + imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); + __raw_writel(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR); +} + +void mcf_clrimr(int index) +{ + u32 imr; + imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); + __raw_writel(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR); +} + +void mcf_maskimr(unsigned int mask) +{ + u32 imr; + imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); + imr |= mask; + __raw_writel(imr, MCF_MBAR + MCFSIM_IMR); +} + +#endif + +/* + * Interrupts can be "vectored" on the ColdFire cores that support this old + * interrupt controller. That is, the device raising the interrupt can also + * supply the vector number to interrupt through. The AVR register of the + * interrupt controller enables or disables this for each external interrupt, + * so provide generic support for this. Setting this up is out-of-band for + * the interrupt system API's, and needs to be done by the driver that + * supports this device. Very few devices actually use this. + */ +void mcf_autovector(int irq) +{ +#ifdef MCFSIM_AVR + if ((irq >= EIRQ1) && (irq <= EIRQ7)) { + u8 avec; + avec = __raw_readb(MCF_MBAR + MCFSIM_AVR); + avec |= (0x1 << (irq - EIRQ1 + 1)); + __raw_writeb(avec, MCF_MBAR + MCFSIM_AVR); + } +#endif +} + +static void intc_irq_mask(unsigned int irq) +{ + if (mcf_irq2imr[irq]) + mcf_setimr(mcf_irq2imr[irq]); +} + +static void intc_irq_unmask(unsigned int irq) +{ + if (mcf_irq2imr[irq]) + mcf_clrimr(mcf_irq2imr[irq]); +} + +static int intc_irq_set_type(unsigned int irq, unsigned int type) +{ + return 0; +} + +static struct irq_chip intc_irq_chip = { + .name = "CF-INTC", + .mask = intc_irq_mask, + .unmask = intc_irq_unmask, + .set_type = intc_irq_set_type, +}; + +void __init init_IRQ(void) +{ + int irq; + + init_vectors(); + mcf_maskimr(0xffffffff); + + for (irq = 0; (irq < NR_IRQS); irq++) { + irq_desc[irq].status = IRQ_DISABLED; + irq_desc[irq].action = NULL; + irq_desc[irq].depth = 1; + irq_desc[irq].chip = &intc_irq_chip; + intc_irq_set_type(irq, 0); + } +} + diff --git a/arch/m68knommu/platform/coldfire/pinmux.c b/arch/m68knommu/platform/coldfire/pinmux.c new file mode 100644 index 00000000000..8c62b825939 --- /dev/null +++ b/arch/m68knommu/platform/coldfire/pinmux.c @@ -0,0 +1,28 @@ +/* + * Coldfire generic GPIO pinmux support. + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * 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; version 2 of the License. + * + * 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. + * + */ + +#include <linux/kernel.h> + +#include <asm/pinmux.h> + +int mcf_pinmux_request(unsigned pinmux, unsigned func) +{ + return 0; +} + +void mcf_pinmux_release(unsigned pinmux, unsigned func) +{ +} diff --git a/arch/m68knommu/platform/coldfire/pit.c b/arch/m68knommu/platform/coldfire/pit.c index 61b96211f8f..d8720ee3451 100644 --- a/arch/m68knommu/platform/coldfire/pit.c +++ b/arch/m68knommu/platform/coldfire/pit.c @@ -32,7 +32,6 @@ */ #define FREQ ((MCF_CLK / 2) / 64) #define TA(a) (MCF_IPSBAR + MCFPIT_BASE1 + (a)) -#define INTC0 (MCF_IPSBAR + MCFICM_INTC0) #define PIT_CYCLES_PER_JIFFY (FREQ / HZ) static u32 pit_cnt; @@ -154,8 +153,6 @@ static struct clocksource pit_clk = { void hw_timer_init(void) { - u32 imr; - cf_pit_clockevent.cpumask = cpumask_of(smp_processor_id()); cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32); cf_pit_clockevent.max_delta_ns = @@ -166,11 +163,6 @@ void hw_timer_init(void) setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &pit_irq); - __raw_writeb(ICR_INTRCONF, INTC0 + MCFINTC_ICR0 + MCFINT_PIT1); - imr = __raw_readl(INTC0 + MCFPIT_IMR); - imr &= ~MCFPIT_IMR_IBIT; - __raw_writel(imr, INTC0 + MCFPIT_IMR); - pit_clk.mult = clocksource_hz2mult(FREQ, pit_clk.shift); clocksource_register(&pit_clk); } diff --git a/arch/m68knommu/platform/coldfire/timers.c b/arch/m68knommu/platform/coldfire/timers.c index 1ba8a373165..2304d736c70 100644 --- a/arch/m68knommu/platform/coldfire/timers.c +++ b/arch/m68knommu/platform/coldfire/timers.c @@ -31,19 +31,9 @@ #define TA(a) (MCF_MBAR + MCFTIMER_BASE1 + (a)) /* - * Default the timer and vector to use for ColdFire. Some ColdFire - * CPU's and some boards may want different. Their sub-architecture - * startup code (in config.c) can change these if they want. - */ -unsigned int mcf_timervector = 29; -unsigned int mcf_profilevector = 31; -unsigned int mcf_timerlevel = 5; - -/* * These provide the underlying interrupt vector support. * Unfortunately it is a little different on each ColdFire. */ -extern void mcf_settimericr(int timer, int level); void coldfire_profile_init(void); #if defined(CONFIG_M532x) @@ -107,8 +97,6 @@ static struct clocksource mcftmr_clk = { void hw_timer_init(void) { - setup_irq(mcf_timervector, &mcftmr_timer_irq); - __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); mcftmr_cycles_per_jiffy = FREQ / HZ; /* @@ -124,7 +112,7 @@ void hw_timer_init(void) mcftmr_clk.mult = clocksource_hz2mult(FREQ, mcftmr_clk.shift); clocksource_register(&mcftmr_clk); - mcf_settimericr(1, mcf_timerlevel); + setup_irq(MCF_IRQ_TIMER, &mcftmr_timer_irq); #ifdef CONFIG_HIGHPROFILE coldfire_profile_init(); @@ -171,8 +159,6 @@ void coldfire_profile_init(void) printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ); - setup_irq(mcf_profilevector, &coldfire_profile_irq); - /* Set up TIMER 2 as high speed profile clock */ __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR)); @@ -180,7 +166,7 @@ void coldfire_profile_init(void) __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR)); - mcf_settimericr(2, 7); + setup_irq(MCF_IRQ_PROFILER, &coldfire_profile_irq); } /***************************************************************************/ diff --git a/arch/m68knommu/platform/coldfire/vectors.c b/arch/m68knommu/platform/coldfire/vectors.c index bdca0297fa9..a21d3f870b7 100644 --- a/arch/m68knommu/platform/coldfire/vectors.c +++ b/arch/m68knommu/platform/coldfire/vectors.c @@ -1,7 +1,7 @@ /***************************************************************************/ /* - * linux/arch/m68knommu/platform/5307/vectors.c + * linux/arch/m68knommu/platform/coldfire/vectors.c * * Copyright (C) 1999-2007, Greg Ungerer <gerg@snapgear.com> */ @@ -15,7 +15,6 @@ #include <asm/machdep.h> #include <asm/coldfire.h> #include <asm/mcfsim.h> -#include <asm/mcfdma.h> #include <asm/mcfwdebug.h> /***************************************************************************/ @@ -79,20 +78,3 @@ void __init init_vectors(void) } /***************************************************************************/ - -void enable_vector(unsigned int irq) -{ - /* Currently no action on ColdFire */ -} - -void disable_vector(unsigned int irq) -{ - /* Currently no action on ColdFire */ -} - -void ack_vector(unsigned int irq) -{ - /* Currently no action on ColdFire */ -} - -/***************************************************************************/ diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3ca0fe1a912..705a7a9170f 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -6,7 +6,7 @@ config MIPS select HAVE_ARCH_KGDB # Horrible source of confusion. Die, die, die ... select EMBEDDED - select RTC_LIB + select RTC_LIB if !LEMOTE_FULOONG2E mainmenu "Linux/MIPS Kernel Configuration" @@ -80,6 +80,21 @@ config BCM47XX help Support for BCM47XX based boards +config BCM63XX + bool "Broadcom BCM63XX based boards" + select CEVT_R4K + select CSRC_R4K + select DMA_NONCOHERENT + select IRQ_CPU + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_HAS_EARLY_PRINTK + select SWAP_IO_SPACE + select ARCH_REQUIRE_GPIOLIB + help + Support for BCM63XX based boards + config MIPS_COBALT bool "Cobalt Server" select CEVT_R4K @@ -174,30 +189,15 @@ config LASAT select SYS_SUPPORTS_64BIT_KERNEL if BROKEN select SYS_SUPPORTS_LITTLE_ENDIAN -config LEMOTE_FULONG - bool "Lemote Fulong mini-PC" - select ARCH_SPARSEMEM_ENABLE - select CEVT_R4K - select CSRC_R4K - select SYS_HAS_CPU_LOONGSON2 - select DMA_NONCOHERENT - select BOOT_ELF32 - select BOARD_SCACHE - select HAVE_STD_PC_SERIAL_PORT - select HW_HAS_PCI - select I8259 - select ISA - select IRQ_CPU - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_HIGHMEM - select SYS_HAS_EARLY_PRINTK - select GENERIC_ISA_DMA_SUPPORT_BROKEN - select CPU_HAS_WB +config MACH_LOONGSON + bool "Loongson family of machines" help - Lemote Fulong mini-PC board based on the Chinese Loongson-2E CPU and - an FPGA northbridge + This enables the support of Loongson family of machines. + + Loongson is a family of general-purpose MIPS-compatible CPUs. + developed at Institute of Computing Technology (ICT), + Chinese Academy of Sciences (CAS) in the People's Republic + of China. The chief architect is Professor Weiwu Hu. config MIPS_MALTA bool "MIPS Malta board" @@ -660,6 +660,7 @@ endchoice source "arch/mips/alchemy/Kconfig" source "arch/mips/basler/excite/Kconfig" +source "arch/mips/bcm63xx/Kconfig" source "arch/mips/jazz/Kconfig" source "arch/mips/lasat/Kconfig" source "arch/mips/pmc-sierra/Kconfig" @@ -668,6 +669,7 @@ source "arch/mips/sibyte/Kconfig" source "arch/mips/txx9/Kconfig" source "arch/mips/vr41xx/Kconfig" source "arch/mips/cavium-octeon/Kconfig" +source "arch/mips/loongson/Kconfig" endmenu @@ -1044,12 +1046,10 @@ choice prompt "CPU type" default CPU_R4X00 -config CPU_LOONGSON2 - bool "Loongson 2" - depends on SYS_HAS_CPU_LOONGSON2 - select CPU_SUPPORTS_32BIT_KERNEL - select CPU_SUPPORTS_64BIT_KERNEL - select CPU_SUPPORTS_HIGHMEM +config CPU_LOONGSON2E + bool "Loongson 2E" + depends on SYS_HAS_CPU_LOONGSON2E + select CPU_LOONGSON2 help The Loongson 2E processor implements the MIPS III instruction set with many extensions. @@ -1057,7 +1057,6 @@ config CPU_LOONGSON2 config CPU_MIPS32_R1 bool "MIPS32 Release 1" depends on SYS_HAS_CPU_MIPS32_R1 - select CPU_HAS_LLSC select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_HIGHMEM @@ -1075,7 +1074,6 @@ config CPU_MIPS32_R1 config CPU_MIPS32_R2 bool "MIPS32 Release 2" depends on SYS_HAS_CPU_MIPS32_R2 - select CPU_HAS_LLSC select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_HIGHMEM @@ -1089,7 +1087,6 @@ config CPU_MIPS32_R2 config CPU_MIPS64_R1 bool "MIPS64 Release 1" depends on SYS_HAS_CPU_MIPS64_R1 - select CPU_HAS_LLSC select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL @@ -1109,7 +1106,6 @@ config CPU_MIPS64_R1 config CPU_MIPS64_R2 bool "MIPS64 Release 2" depends on SYS_HAS_CPU_MIPS64_R2 - select CPU_HAS_LLSC select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL @@ -1155,7 +1151,6 @@ config CPU_VR41XX config CPU_R4300 bool "R4300" depends on SYS_HAS_CPU_R4300 - select CPU_HAS_LLSC select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL help @@ -1164,7 +1159,6 @@ config CPU_R4300 config CPU_R4X00 bool "R4x00" depends on SYS_HAS_CPU_R4X00 - select CPU_HAS_LLSC select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL help @@ -1174,7 +1168,6 @@ config CPU_R4X00 config CPU_TX49XX bool "R49XX" depends on SYS_HAS_CPU_TX49XX - select CPU_HAS_LLSC select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL @@ -1182,7 +1175,6 @@ config CPU_TX49XX config CPU_R5000 bool "R5000" depends on SYS_HAS_CPU_R5000 - select CPU_HAS_LLSC select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL help @@ -1191,14 +1183,12 @@ config CPU_R5000 config CPU_R5432 bool "R5432" depends on SYS_HAS_CPU_R5432 - select CPU_HAS_LLSC select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL config CPU_R5500 bool "R5500" depends on SYS_HAS_CPU_R5500 - select CPU_HAS_LLSC select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HUGEPAGES @@ -1209,7 +1199,6 @@ config CPU_R5500 config CPU_R6000 bool "R6000" depends on EXPERIMENTAL - select CPU_HAS_LLSC depends on SYS_HAS_CPU_R6000 select CPU_SUPPORTS_32BIT_KERNEL help @@ -1219,7 +1208,6 @@ config CPU_R6000 config CPU_NEVADA bool "RM52xx" depends on SYS_HAS_CPU_NEVADA - select CPU_HAS_LLSC select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL help @@ -1229,7 +1217,6 @@ config CPU_R8000 bool "R8000" depends on EXPERIMENTAL depends on SYS_HAS_CPU_R8000 - select CPU_HAS_LLSC select CPU_HAS_PREFETCH select CPU_SUPPORTS_64BIT_KERNEL help @@ -1239,7 +1226,6 @@ config CPU_R8000 config CPU_R10000 bool "R10000" depends on SYS_HAS_CPU_R10000 - select CPU_HAS_LLSC select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL @@ -1250,7 +1236,6 @@ config CPU_R10000 config CPU_RM7000 bool "RM7000" depends on SYS_HAS_CPU_RM7000 - select CPU_HAS_LLSC select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL @@ -1259,7 +1244,6 @@ config CPU_RM7000 config CPU_RM9000 bool "RM9000" depends on SYS_HAS_CPU_RM9000 - select CPU_HAS_LLSC select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL @@ -1269,7 +1253,6 @@ config CPU_RM9000 config CPU_SB1 bool "SB1" depends on SYS_HAS_CPU_SB1 - select CPU_HAS_LLSC select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM @@ -1296,7 +1279,13 @@ config CPU_CAVIUM_OCTEON endchoice -config SYS_HAS_CPU_LOONGSON2 +config CPU_LOONGSON2 + bool + select CPU_SUPPORTS_32BIT_KERNEL + select CPU_SUPPORTS_64BIT_KERNEL + select CPU_SUPPORTS_HIGHMEM + +config SYS_HAS_CPU_LOONGSON2E bool config SYS_HAS_CPU_MIPS32_R1 @@ -1683,9 +1672,6 @@ config SB1_PASS_2_1_WORKAROUNDS config 64BIT_PHYS_ADDR bool -config CPU_HAS_LLSC - bool - config CPU_HAS_SMARTMIPS depends on SYS_SUPPORTS_SMARTMIPS bool "Support for the SmartMIPS ASE" diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 861da514a46..c825b14b4ed 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -120,7 +120,11 @@ cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap -cflags-$(CONFIG_CPU_LOONGSON2) += -march=r4600 -Wa,--trap +# only gcc >= 4.4 have the loongson-specific support +cflags-$(CONFIG_CPU_LOONGSON2) += -Wa,--trap +cflags-$(CONFIG_CPU_LOONGSON2E) += \ + $(call cc-option,-march=loongson2e,-march=r4600) + cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ -Wa,-mips32 -Wa,--trap cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ @@ -314,11 +318,12 @@ cflags-$(CONFIG_WR_PPMC) += -I$(srctree)/arch/mips/include/asm/mach-wrppmc load-$(CONFIG_WR_PPMC) += 0xffffffff80100000 # -# lemote fulong mini-PC board +# Loongson family # -core-$(CONFIG_LEMOTE_FULONG) +=arch/mips/lemote/lm2e/ -load-$(CONFIG_LEMOTE_FULONG) +=0xffffffff80100000 -cflags-$(CONFIG_LEMOTE_FULONG) += -I$(srctree)/arch/mips/include/asm/mach-lemote +core-$(CONFIG_MACH_LOONGSON) +=arch/mips/loongson/ +cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson \ + -mno-branch-likely +load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000 # # MIPS Malta board @@ -560,6 +565,13 @@ cflags-$(CONFIG_BCM47XX) += -I$(srctree)/arch/mips/include/asm/mach-bcm47xx load-$(CONFIG_BCM47XX) := 0xffffffff80001000 # +# Broadcom BCM63XX boards +# +core-$(CONFIG_BCM63XX) += arch/mips/bcm63xx/ +cflags-$(CONFIG_BCM63XX) += -I$(srctree)/arch/mips/include/asm/mach-bcm63xx/ +load-$(CONFIG_BCM63XX) := 0xffffffff80010000 + +# # SNI RM # core-$(CONFIG_SNI_RM) += arch/mips/sni/ diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index 3f036b3d400..6184baa5678 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c @@ -27,6 +27,7 @@ #include <linux/init.h> #include <linux/ioport.h> +#include <linux/jiffies.h> #include <linux/module.h> #include <linux/pm.h> @@ -53,6 +54,9 @@ void __init plat_mem_setup(void) printk(KERN_INFO "(PRId %08x) @ %lu.%02lu MHz\n", read_c0_prid(), est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000); + /* this is faster than wasting cycles trying to approximate it */ + preset_lpj = (est_freq >> 1) / HZ; + _machine_restart = au1000_restart; _machine_halt = au1000_halt; pm_power_off = au1000_power_off; diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c index 33fbae79af5..f34ff860194 100644 --- a/arch/mips/alchemy/common/time.c +++ b/arch/mips/alchemy/common/time.c @@ -36,14 +36,13 @@ #include <linux/interrupt.h> #include <linux/spinlock.h> +#include <asm/processor.h> #include <asm/time.h> #include <asm/mach-au1x00/au1000.h> /* 32kHz clock enabled and detected */ #define CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S) -extern int allow_au1k_wait; /* default off for CP0 Counter */ - static cycle_t au1x_counter1_read(struct clocksource *cs) { return au_readl(SYS_RTCREAD); @@ -153,13 +152,17 @@ void __init plat_time_init(void) printk(KERN_INFO "Alchemy clocksource installed\n"); - /* can now use 'wait' */ - allow_au1k_wait = 1; return; cntr_err: - /* counters unusable, use C0 counter */ + /* + * MIPS kernel assigns 'au1k_wait' to 'cpu_wait' before this + * function is called. Because the Alchemy counters are unusable + * the C0 timekeeping code is installed and use of the 'wait' + * instruction must be prohibited, which is done most easily by + * assigning NULL to cpu_wait. + */ + cpu_wait = NULL; r4k_clockevent_init(); init_r4k_clocksource(); - allow_au1k_wait = 0; } diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index cf50fa29b19..e2278c04459 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c @@ -417,6 +417,20 @@ static struct platform_device ar7_udc = { .num_resources = ARRAY_SIZE(usb_res), }; +static struct resource ar7_wdt_res = { + .name = "regs", + .start = -1, /* Filled at runtime */ + .end = -1, /* Filled at runtime */ + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ar7_wdt = { + .id = -1, + .name = "ar7_wdt", + .resource = &ar7_wdt_res, + .num_resources = 1, +}; + static inline unsigned char char2hex(char h) { switch (h) { @@ -487,6 +501,7 @@ static void __init detect_leds(void) static int __init ar7_register_devices(void) { + u16 chip_id; int res; #ifdef CONFIG_SERIAL_8250 static struct uart_port uart_port[2]; @@ -565,6 +580,23 @@ static int __init ar7_register_devices(void) res = platform_device_register(&ar7_udc); + chip_id = ar7_chip_id(); + switch (chip_id) { + case AR7_CHIP_7100: + case AR7_CHIP_7200: + ar7_wdt_res.start = AR7_REGS_WDT; + break; + case AR7_CHIP_7300: + ar7_wdt_res.start = UR8_REGS_WDT; + break; + default: + break; + } + + ar7_wdt_res.end = ar7_wdt_res.start + 0x20; + + res = platform_device_register(&ar7_wdt); + return res; } arch_initcall(ar7_register_devices); diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig new file mode 100644 index 00000000000..fb177d6df06 --- /dev/null +++ b/arch/mips/bcm63xx/Kconfig @@ -0,0 +1,25 @@ +menu "CPU support" + depends on BCM63XX + +config BCM63XX_CPU_6338 + bool "support 6338 CPU" + select HW_HAS_PCI + select USB_ARCH_HAS_OHCI + select USB_OHCI_BIG_ENDIAN_DESC + select USB_OHCI_BIG_ENDIAN_MMIO + +config BCM63XX_CPU_6345 + bool "support 6345 CPU" + select USB_OHCI_BIG_ENDIAN_DESC + select USB_OHCI_BIG_ENDIAN_MMIO + +config BCM63XX_CPU_6348 + bool "support 6348 CPU" + select HW_HAS_PCI + +config BCM63XX_CPU_6358 + bool "support 6358 CPU" + select HW_HAS_PCI +endmenu + +source "arch/mips/bcm63xx/boards/Kconfig" diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile new file mode 100644 index 00000000000..aaa585cf26e --- /dev/null +++ b/arch/mips/bcm63xx/Makefile @@ -0,0 +1,7 @@ +obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ + dev-dsp.o dev-enet.o +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + +obj-y += boards/ + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/bcm63xx/boards/Kconfig b/arch/mips/bcm63xx/boards/Kconfig new file mode 100644 index 00000000000..c6aed33d893 --- /dev/null +++ b/arch/mips/bcm63xx/boards/Kconfig @@ -0,0 +1,11 @@ +choice + prompt "Board support" + depends on BCM63XX + default BOARD_BCM963XX + +config BOARD_BCM963XX + bool "Generic Broadcom 963xx boards" + select SSB + help + +endchoice diff --git a/arch/mips/bcm63xx/boards/Makefile b/arch/mips/bcm63xx/boards/Makefile new file mode 100644 index 00000000000..e5cc86dc1da --- /dev/null +++ b/arch/mips/bcm63xx/boards/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c new file mode 100644 index 00000000000..fd77f548207 --- /dev/null +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -0,0 +1,837 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/ssb/ssb.h> +#include <asm/addrspace.h> +#include <bcm63xx_board.h> +#include <bcm63xx_cpu.h> +#include <bcm63xx_regs.h> +#include <bcm63xx_io.h> +#include <bcm63xx_board.h> +#include <bcm63xx_dev_pci.h> +#include <bcm63xx_dev_enet.h> +#include <bcm63xx_dev_dsp.h> +#include <board_bcm963xx.h> + +#define PFX "board_bcm963xx: " + +static struct bcm963xx_nvram nvram; +static unsigned int mac_addr_used; +static struct board_info board; + +/* + * known 6338 boards + */ +#ifdef CONFIG_BCM63XX_CPU_6338 +static struct board_info __initdata board_96338gw = { + .name = "96338GW", + .expected_cpu_id = 0x6338, + + .has_enet0 = 1, + .enet0 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + .has_ohci0 = 1, + + .leds = { + { + .name = "adsl", + .gpio = 3, + .active_low = 1, + }, + { + .name = "ses", + .gpio = 5, + .active_low = 1, + }, + { + .name = "ppp-fail", + .gpio = 4, + .active_low = 1, + }, + { + .name = "power", + .gpio = 0, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "stop", + .gpio = 1, + .active_low = 1, + } + }, +}; + +static struct board_info __initdata board_96338w = { + .name = "96338W", + .expected_cpu_id = 0x6338, + + .has_enet0 = 1, + .enet0 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + .leds = { + { + .name = "adsl", + .gpio = 3, + .active_low = 1, + }, + { + .name = "ses", + .gpio = 5, + .active_low = 1, + }, + { + .name = "ppp-fail", + .gpio = 4, + .active_low = 1, + }, + { + .name = "power", + .gpio = 0, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "stop", + .gpio = 1, + .active_low = 1, + }, + }, +}; +#endif + +/* + * known 6345 boards + */ +#ifdef CONFIG_BCM63XX_CPU_6345 +static struct board_info __initdata board_96345gw2 = { + .name = "96345GW2", + .expected_cpu_id = 0x6345, +}; +#endif + +/* + * known 6348 boards + */ +#ifdef CONFIG_BCM63XX_CPU_6348 +static struct board_info __initdata board_96348r = { + .name = "96348R", + .expected_cpu_id = 0x6348, + + .has_enet0 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .leds = { + { + .name = "adsl-fail", + .gpio = 2, + .active_low = 1, + }, + { + .name = "ppp", + .gpio = 3, + .active_low = 1, + }, + { + .name = "ppp-fail", + .gpio = 4, + .active_low = 1, + }, + { + .name = "power", + .gpio = 0, + .active_low = 1, + .default_trigger = "default-on", + + }, + { + .name = "stop", + .gpio = 1, + .active_low = 1, + }, + }, +}; + +static struct board_info __initdata board_96348gw_10 = { + .name = "96348GW-10", + .expected_cpu_id = 0x6348, + + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + .has_ohci0 = 1, + .has_pccard = 1, + .has_ehci0 = 1, + + .has_dsp = 1, + .dsp = { + .gpio_rst = 6, + .gpio_int = 34, + .cs = 2, + .ext_irq = 2, + }, + + .leds = { + { + .name = "adsl-fail", + .gpio = 2, + .active_low = 1, + }, + { + .name = "ppp", + .gpio = 3, + .active_low = 1, + }, + { + .name = "ppp-fail", + .gpio = 4, + .active_low = 1, + }, + { + .name = "power", + .gpio = 0, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "stop", + .gpio = 1, + .active_low = 1, + }, + }, +}; + +static struct board_info __initdata board_96348gw_11 = { + .name = "96348GW-11", + .expected_cpu_id = 0x6348, + + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + + .has_ohci0 = 1, + .has_pccard = 1, + .has_ehci0 = 1, + + .leds = { + { + .name = "adsl-fail", + .gpio = 2, + .active_low = 1, + }, + { + .name = "ppp", + .gpio = 3, + .active_low = 1, + }, + { + .name = "ppp-fail", + .gpio = 4, + .active_low = 1, + }, + { + .name = "power", + .gpio = 0, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "stop", + .gpio = 1, + .active_low = 1, + }, + }, +}; + +static struct board_info __initdata board_96348gw = { + .name = "96348GW", + .expected_cpu_id = 0x6348, + + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + .has_ohci0 = 1, + + .has_dsp = 1, + .dsp = { + .gpio_rst = 6, + .gpio_int = 34, + .ext_irq = 2, + .cs = 2, + }, + + .leds = { + { + .name = "adsl-fail", + .gpio = 2, + .active_low = 1, + }, + { + .name = "ppp", + .gpio = 3, + .active_low = 1, + }, + { + .name = "ppp-fail", + .gpio = 4, + .active_low = 1, + }, + { + .name = "power", + .gpio = 0, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "stop", + .gpio = 1, + .active_low = 1, + }, + }, +}; + +static struct board_info __initdata board_FAST2404 = { + .name = "F@ST2404", + .expected_cpu_id = 0x6348, + + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + + .has_ohci0 = 1, + .has_pccard = 1, + .has_ehci0 = 1, +}; + +static struct board_info __initdata board_DV201AMR = { + .name = "DV201AMR", + .expected_cpu_id = 0x6348, + + .has_pci = 1, + .has_ohci0 = 1, + + .has_enet0 = 1, + .has_enet1 = 1, + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, +}; + +static struct board_info __initdata board_96348gw_a = { + .name = "96348GW-A", + .expected_cpu_id = 0x6348, + + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + .has_ohci0 = 1, +}; +#endif + +/* + * known 6358 boards + */ +#ifdef CONFIG_BCM63XX_CPU_6358 +static struct board_info __initdata board_96358vw = { + .name = "96358VW", + .expected_cpu_id = 0x6358, + + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + + .has_ohci0 = 1, + .has_pccard = 1, + .has_ehci0 = 1, + + .leds = { + { + .name = "adsl-fail", + .gpio = 15, + .active_low = 1, + }, + { + .name = "ppp", + .gpio = 22, + .active_low = 1, + }, + { + .name = "ppp-fail", + .gpio = 23, + .active_low = 1, + }, + { + .name = "power", + .gpio = 4, + .default_trigger = "default-on", + }, + { + .name = "stop", + .gpio = 5, + }, + }, +}; + +static struct board_info __initdata board_96358vw2 = { + .name = "96358VW2", + .expected_cpu_id = 0x6358, + + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + + .has_ohci0 = 1, + .has_pccard = 1, + .has_ehci0 = 1, + + .leds = { + { + .name = "adsl", + .gpio = 22, + .active_low = 1, + }, + { + .name = "ppp-fail", + .gpio = 23, + }, + { + .name = "power", + .gpio = 5, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "stop", + .gpio = 4, + .active_low = 1, + }, + }, +}; + +static struct board_info __initdata board_AGPFS0 = { + .name = "AGPF-S0", + .expected_cpu_id = 0x6358, + + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + .has_ohci0 = 1, + .has_ehci0 = 1, +}; +#endif + +/* + * all boards + */ +static const struct board_info __initdata *bcm963xx_boards[] = { +#ifdef CONFIG_BCM63XX_CPU_6338 + &board_96338gw, + &board_96338w, +#endif +#ifdef CONFIG_BCM63XX_CPU_6345 + &board_96345gw2, +#endif +#ifdef CONFIG_BCM63XX_CPU_6348 + &board_96348r, + &board_96348gw, + &board_96348gw_10, + &board_96348gw_11, + &board_FAST2404, + &board_DV201AMR, + &board_96348gw_a, +#endif + +#ifdef CONFIG_BCM63XX_CPU_6358 + &board_96358vw, + &board_96358vw2, + &board_AGPFS0, +#endif +}; + +/* + * early init callback, read nvram data from flash and checksum it + */ +void __init board_prom_init(void) +{ + unsigned int check_len, i; + u8 *boot_addr, *cfe, *p; + char cfe_version[32]; + u32 val; + + /* read base address of boot chip select (0) + * 6345 does not have MPI but boots from standard + * MIPS Flash address */ + if (BCMCPU_IS_6345()) + val = 0x1fc00000; + else { + val = bcm_mpi_readl(MPI_CSBASE_REG(0)); + val &= MPI_CSBASE_BASE_MASK; + } + boot_addr = (u8 *)KSEG1ADDR(val); + + /* dump cfe version */ + cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET; + if (!memcmp(cfe, "cfe-v", 5)) + snprintf(cfe_version, sizeof(cfe_version), "%u.%u.%u-%u.%u", + cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]); + else + strcpy(cfe_version, "unknown"); + printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); + + /* extract nvram data */ + memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram)); + + /* check checksum before using data */ + if (nvram.version <= 4) + check_len = offsetof(struct bcm963xx_nvram, checksum_old); + else + check_len = sizeof(nvram); + val = 0; + p = (u8 *)&nvram; + while (check_len--) + val += *p; + if (val) { + printk(KERN_ERR PFX "invalid nvram checksum\n"); + return; + } + + /* find board by name */ + for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { + if (strncmp(nvram.name, bcm963xx_boards[i]->name, + sizeof(nvram.name))) + continue; + /* copy, board desc array is marked initdata */ + memcpy(&board, bcm963xx_boards[i], sizeof(board)); + break; + } + + /* bail out if board is not found, will complain later */ + if (!board.name[0]) { + char name[17]; + memcpy(name, nvram.name, 16); + name[16] = 0; + printk(KERN_ERR PFX "unknown bcm963xx board: %s\n", + name); + return; + } + + /* setup pin multiplexing depending on board enabled device, + * this has to be done this early since PCI init is done + * inside arch_initcall */ + val = 0; + +#ifdef CONFIG_PCI + if (board.has_pci) { + bcm63xx_pci_enabled = 1; + if (BCMCPU_IS_6348()) + val |= GPIO_MODE_6348_G2_PCI; + } +#endif + + if (board.has_pccard) { + if (BCMCPU_IS_6348()) + val |= GPIO_MODE_6348_G1_MII_PCCARD; + } + + if (board.has_enet0 && !board.enet0.use_internal_phy) { + if (BCMCPU_IS_6348()) + val |= GPIO_MODE_6348_G3_EXT_MII | + GPIO_MODE_6348_G0_EXT_MII; + } + + if (board.has_enet1 && !board.enet1.use_internal_phy) { + if (BCMCPU_IS_6348()) + val |= GPIO_MODE_6348_G3_EXT_MII | + GPIO_MODE_6348_G0_EXT_MII; + } + + bcm_gpio_writel(val, GPIO_MODE_REG); +} + +/* + * second stage init callback, good time to panic if we couldn't + * identify on which board we're running since early printk is working + */ +void __init board_setup(void) +{ + if (!board.name[0]) + panic("unable to detect bcm963xx board"); + printk(KERN_INFO PFX "board name: %s\n", board.name); + + /* make sure we're running on expected cpu */ + if (bcm63xx_get_cpu_id() != board.expected_cpu_id) + panic("unexpected CPU for bcm963xx board"); +} + +/* + * return board name for /proc/cpuinfo + */ +const char *board_get_name(void) +{ + return board.name; +} + +/* + * register & return a new board mac address + */ +static int board_get_mac_address(u8 *mac) +{ + u8 *p; + int count; + + if (mac_addr_used >= nvram.mac_addr_count) { + printk(KERN_ERR PFX "not enough mac address\n"); + return -ENODEV; + } + + memcpy(mac, nvram.mac_addr_base, ETH_ALEN); + p = mac + ETH_ALEN - 1; + count = mac_addr_used; + + while (count--) { + do { + (*p)++; + if (*p != 0) + break; + p--; + } while (p != mac); + } + + if (p == mac) { + printk(KERN_ERR PFX "unable to fetch mac address\n"); + return -ENODEV; + } + + mac_addr_used++; + return 0; +} + +static struct mtd_partition mtd_partitions[] = { + { + .name = "cfe", + .offset = 0x0, + .size = 0x40000, + } +}; + +static struct physmap_flash_data flash_data = { + .width = 2, + .nr_parts = ARRAY_SIZE(mtd_partitions), + .parts = mtd_partitions, +}; + +static struct resource mtd_resources[] = { + { + .start = 0, /* filled at runtime */ + .end = 0, /* filled at runtime */ + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device mtd_dev = { + .name = "physmap-flash", + .resource = mtd_resources, + .num_resources = ARRAY_SIZE(mtd_resources), + .dev = { + .platform_data = &flash_data, + }, +}; + +/* + * Register a sane SPROMv2 to make the on-board + * bcm4318 WLAN work + */ +#ifdef CONFIG_SSB_PCIHOST +static struct ssb_sprom bcm63xx_sprom = { + .revision = 0x02, + .board_rev = 0x17, + .country_code = 0x0, + .ant_available_bg = 0x3, + .pa0b0 = 0x15ae, + .pa0b1 = 0xfa85, + .pa0b2 = 0xfe8d, + .pa1b0 = 0xffff, + .pa1b1 = 0xffff, + .pa1b2 = 0xffff, + .gpio0 = 0xff, + .gpio1 = 0xff, + .gpio2 = 0xff, + .gpio3 = 0xff, + .maxpwr_bg = 0x004c, + .itssi_bg = 0x00, + .boardflags_lo = 0x2848, + .boardflags_hi = 0x0000, +}; +#endif + +static struct gpio_led_platform_data bcm63xx_led_data; + +static struct platform_device bcm63xx_gpio_leds = { + .name = "leds-gpio", + .id = 0, + .dev.platform_data = &bcm63xx_led_data, +}; + +/* + * third stage init callback, register all board devices. + */ +int __init board_register_devices(void) +{ + u32 val; + + if (board.has_enet0 && + !board_get_mac_address(board.enet0.mac_addr)) + bcm63xx_enet_register(0, &board.enet0); + + if (board.has_enet1 && + !board_get_mac_address(board.enet1.mac_addr)) + bcm63xx_enet_register(1, &board.enet1); + + if (board.has_dsp) + bcm63xx_dsp_register(&board.dsp); + + /* Generate MAC address for WLAN and + * register our SPROM */ +#ifdef CONFIG_SSB_PCIHOST + if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { + memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); + memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); + if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0) + printk(KERN_ERR "failed to register fallback SPROM\n"); + } +#endif + + /* read base address of boot chip select (0) */ + if (BCMCPU_IS_6345()) + val = 0x1fc00000; + else { + val = bcm_mpi_readl(MPI_CSBASE_REG(0)); + val &= MPI_CSBASE_BASE_MASK; + } + mtd_resources[0].start = val; + mtd_resources[0].end = 0x1FFFFFFF; + + platform_device_register(&mtd_dev); + + bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds); + bcm63xx_led_data.leds = board.leds; + + platform_device_register(&bcm63xx_gpio_leds); + + return 0; +} + diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c new file mode 100644 index 00000000000..2c68ee9ccee --- /dev/null +++ b/arch/mips/bcm63xx/clk.c @@ -0,0 +1,226 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + */ + +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <bcm63xx_cpu.h> +#include <bcm63xx_io.h> +#include <bcm63xx_regs.h> +#include <bcm63xx_clk.h> + +static DEFINE_MUTEX(clocks_mutex); + + +static void clk_enable_unlocked(struct clk *clk) +{ + if (clk->set && (clk->usage++) == 0) + clk->set(clk, 1); +} + +static void clk_disable_unlocked(struct clk *clk) +{ + if (clk->set && (--clk->usage) == 0) + clk->set(clk, 0); +} + +static void bcm_hwclock_set(u32 mask, int enable) +{ + u32 reg; + + reg = bcm_perf_readl(PERF_CKCTL_REG); + if (enable) + reg |= mask; + else + reg &= ~mask; + bcm_perf_writel(reg, PERF_CKCTL_REG); +} + +/* + * Ethernet MAC "misc" clock: dma clocks and main clock on 6348 + */ +static void enet_misc_set(struct clk *clk, int enable) +{ + u32 mask; + + if (BCMCPU_IS_6338()) + mask = CKCTL_6338_ENET_EN; + else if (BCMCPU_IS_6345()) + mask = CKCTL_6345_ENET_EN; + else if (BCMCPU_IS_6348()) + mask = CKCTL_6348_ENET_EN; + else + /* BCMCPU_IS_6358 */ + mask = CKCTL_6358_EMUSB_EN; + bcm_hwclock_set(mask, enable); +} + +static struct clk clk_enet_misc = { + .set = enet_misc_set, +}; + +/* + * Ethernet MAC clocks: only revelant on 6358, silently enable misc + * clocks + */ +static void enetx_set(struct clk *clk, int enable) +{ + if (enable) + clk_enable_unlocked(&clk_enet_misc); + else + clk_disable_unlocked(&clk_enet_misc); + + if (BCMCPU_IS_6358()) { + u32 mask; + + if (clk->id == 0) + mask = CKCTL_6358_ENET0_EN; + else + mask = CKCTL_6358_ENET1_EN; + bcm_hwclock_set(mask, enable); + } +} + +static struct clk clk_enet0 = { + .id = 0, + .set = enetx_set, +}; + +static struct clk clk_enet1 = { + .id = 1, + .set = enetx_set, +}; + +/* + * Ethernet PHY clock + */ +static void ephy_set(struct clk *clk, int enable) +{ + if (!BCMCPU_IS_6358()) + return; + bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable); +} + + +static struct clk clk_ephy = { + .set = ephy_set, +}; + +/* + * PCM clock + */ +static void pcm_set(struct clk *clk, int enable) +{ + if (!BCMCPU_IS_6358()) + return; + bcm_hwclock_set(CKCTL_6358_PCM_EN, enable); +} + +static struct clk clk_pcm = { + .set = pcm_set, +}; + +/* + * USB host clock + */ +static void usbh_set(struct clk *clk, int enable) +{ + if (!BCMCPU_IS_6348()) + return; + bcm_hwclock_set(CKCTL_6348_USBH_EN, enable); +} + +static struct clk clk_usbh = { + .set = usbh_set, +}; + +/* + * SPI clock + */ +static void spi_set(struct clk *clk, int enable) +{ + u32 mask; + + if (BCMCPU_IS_6338()) + mask = CKCTL_6338_SPI_EN; + else if (BCMCPU_IS_6348()) + mask = CKCTL_6348_SPI_EN; + else + /* BCMCPU_IS_6358 */ + mask = CKCTL_6358_SPI_EN; + bcm_hwclock_set(mask, enable); +} + +static struct clk clk_spi = { + .set = spi_set, +}; + +/* + * Internal peripheral clock + */ +static struct clk clk_periph = { + .rate = (50 * 1000 * 1000), +}; + + +/* + * Linux clock API implementation + */ +int clk_enable(struct clk *clk) +{ + mutex_lock(&clocks_mutex); + clk_enable_unlocked(clk); + mutex_unlock(&clocks_mutex); + return 0; +} + +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ + mutex_lock(&clocks_mutex); + clk_disable_unlocked(clk); + mutex_unlock(&clocks_mutex); +} + +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} + +EXPORT_SYMBOL(clk_get_rate); + +struct clk *clk_get(struct device *dev, const char *id) +{ + if (!strcmp(id, "enet0")) + return &clk_enet0; + if (!strcmp(id, "enet1")) + return &clk_enet1; + if (!strcmp(id, "ephy")) + return &clk_ephy; + if (!strcmp(id, "usbh")) + return &clk_usbh; + if (!strcmp(id, "spi")) + return &clk_spi; + if (!strcmp(id, "periph")) + return &clk_periph; + if (BCMCPU_IS_6358() && !strcmp(id, "pcm")) + return &clk_pcm; + return ERR_PTR(-ENOENT); +} + +EXPORT_SYMBOL(clk_get); + +void clk_put(struct clk *clk) +{ +} + +EXPORT_SYMBOL(clk_put); diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c new file mode 100644 index 00000000000..6dc43f0483e --- /dev/null +++ b/arch/mips/bcm63xx/cpu.c @@ -0,0 +1,345 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org> + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/cpu.h> +#include <bcm63xx_cpu.h> +#include <bcm63xx_regs.h> +#include <bcm63xx_io.h> +#include <bcm63xx_irq.h> + +const unsigned long *bcm63xx_regs_base; +EXPORT_SYMBOL(bcm63xx_regs_base); + +const int *bcm63xx_irqs; +EXPORT_SYMBOL(bcm63xx_irqs); + +static u16 bcm63xx_cpu_id; +static u16 bcm63xx_cpu_rev; +static unsigned int bcm63xx_cpu_freq; +static unsigned int bcm63xx_memory_size; + +/* + * 6338 register sets and irqs + */ +static const unsigned long bcm96338_regs_base[] = { + [RSET_DSL_LMEM] = BCM_6338_DSL_LMEM_BASE, + [RSET_PERF] = BCM_6338_PERF_BASE, + [RSET_TIMER] = BCM_6338_TIMER_BASE, + [RSET_WDT] = BCM_6338_WDT_BASE, + [RSET_UART0] = BCM_6338_UART0_BASE, + [RSET_GPIO] = BCM_6338_GPIO_BASE, + [RSET_SPI] = BCM_6338_SPI_BASE, + [RSET_OHCI0] = BCM_6338_OHCI0_BASE, + [RSET_OHCI_PRIV] = BCM_6338_OHCI_PRIV_BASE, + [RSET_USBH_PRIV] = BCM_6338_USBH_PRIV_BASE, + [RSET_UDC0] = BCM_6338_UDC0_BASE, + [RSET_MPI] = BCM_6338_MPI_BASE, + [RSET_PCMCIA] = BCM_6338_PCMCIA_BASE, + [RSET_SDRAM] = BCM_6338_SDRAM_BASE, + [RSET_DSL] = BCM_6338_DSL_BASE, + [RSET_ENET0] = BCM_6338_ENET0_BASE, + [RSET_ENET1] = BCM_6338_ENET1_BASE, + [RSET_ENETDMA] = BCM_6338_ENETDMA_BASE, + [RSET_MEMC] = BCM_6338_MEMC_BASE, + [RSET_DDR] = BCM_6338_DDR_BASE, +}; + +static const int bcm96338_irqs[] = { + [IRQ_TIMER] = BCM_6338_TIMER_IRQ, + [IRQ_UART0] = BCM_6338_UART0_IRQ, + [IRQ_DSL] = BCM_6338_DSL_IRQ, + [IRQ_ENET0] = BCM_6338_ENET0_IRQ, + [IRQ_ENET_PHY] = BCM_6338_ENET_PHY_IRQ, + [IRQ_ENET0_RXDMA] = BCM_6338_ENET0_RXDMA_IRQ, + [IRQ_ENET0_TXDMA] = BCM_6338_ENET0_TXDMA_IRQ, +}; + +/* + * 6345 register sets and irqs + */ +static const unsigned long bcm96345_regs_base[] = { + [RSET_DSL_LMEM] = BCM_6345_DSL_LMEM_BASE, + [RSET_PERF] = BCM_6345_PERF_BASE, + [RSET_TIMER] = BCM_6345_TIMER_BASE, + [RSET_WDT] = BCM_6345_WDT_BASE, + [RSET_UART0] = BCM_6345_UART0_BASE, + [RSET_GPIO] = BCM_6345_GPIO_BASE, + [RSET_SPI] = BCM_6345_SPI_BASE, + [RSET_UDC0] = BCM_6345_UDC0_BASE, + [RSET_OHCI0] = BCM_6345_OHCI0_BASE, + [RSET_OHCI_PRIV] = BCM_6345_OHCI_PRIV_BASE, + [RSET_USBH_PRIV] = BCM_6345_USBH_PRIV_BASE, + [RSET_MPI] = BCM_6345_MPI_BASE, + [RSET_PCMCIA] = BCM_6345_PCMCIA_BASE, + [RSET_DSL] = BCM_6345_DSL_BASE, + [RSET_ENET0] = BCM_6345_ENET0_BASE, + [RSET_ENET1] = BCM_6345_ENET1_BASE, + [RSET_ENETDMA] = BCM_6345_ENETDMA_BASE, + [RSET_EHCI0] = BCM_6345_EHCI0_BASE, + [RSET_SDRAM] = BCM_6345_SDRAM_BASE, + [RSET_MEMC] = BCM_6345_MEMC_BASE, + [RSET_DDR] = BCM_6345_DDR_BASE, +}; + +static const int bcm96345_irqs[] = { + [IRQ_TIMER] = BCM_6345_TIMER_IRQ, + [IRQ_UART0] = BCM_6345_UART0_IRQ, + [IRQ_DSL] = BCM_6345_DSL_IRQ, + [IRQ_ENET0] = BCM_6345_ENET0_IRQ, + [IRQ_ENET_PHY] = BCM_6345_ENET_PHY_IRQ, + [IRQ_ENET0_RXDMA] = BCM_6345_ENET0_RXDMA_IRQ, + [IRQ_ENET0_TXDMA] = BCM_6345_ENET0_TXDMA_IRQ, +}; + +/* + * 6348 register sets and irqs + */ +static const unsigned long bcm96348_regs_base[] = { + [RSET_DSL_LMEM] = BCM_6348_DSL_LMEM_BASE, + [RSET_PERF] = BCM_6348_PERF_BASE, + [RSET_TIMER] = BCM_6348_TIMER_BASE, + [RSET_WDT] = BCM_6348_WDT_BASE, + [RSET_UART0] = BCM_6348_UART0_BASE, + [RSET_GPIO] = BCM_6348_GPIO_BASE, + [RSET_SPI] = BCM_6348_SPI_BASE, + [RSET_OHCI0] = BCM_6348_OHCI0_BASE, + [RSET_OHCI_PRIV] = BCM_6348_OHCI_PRIV_BASE, + [RSET_USBH_PRIV] = BCM_6348_USBH_PRIV_BASE, + [RSET_MPI] = BCM_6348_MPI_BASE, + [RSET_PCMCIA] = BCM_6348_PCMCIA_BASE, + [RSET_SDRAM] = BCM_6348_SDRAM_BASE, + [RSET_DSL] = BCM_6348_DSL_BASE, + [RSET_ENET0] = BCM_6348_ENET0_BASE, + [RSET_ENET1] = BCM_6348_ENET1_BASE, + [RSET_ENETDMA] = BCM_6348_ENETDMA_BASE, + [RSET_MEMC] = BCM_6348_MEMC_BASE, + [RSET_DDR] = BCM_6348_DDR_BASE, +}; + +static const int bcm96348_irqs[] = { + [IRQ_TIMER] = BCM_6348_TIMER_IRQ, + [IRQ_UART0] = BCM_6348_UART0_IRQ, + [IRQ_DSL] = BCM_6348_DSL_IRQ, + [IRQ_ENET0] = BCM_6348_ENET0_IRQ, + [IRQ_ENET1] = BCM_6348_ENET1_IRQ, + [IRQ_ENET_PHY] = BCM_6348_ENET_PHY_IRQ, + [IRQ_OHCI0] = BCM_6348_OHCI0_IRQ, + [IRQ_PCMCIA] = BCM_6348_PCMCIA_IRQ, + [IRQ_ENET0_RXDMA] = BCM_6348_ENET0_RXDMA_IRQ, + [IRQ_ENET0_TXDMA] = BCM_6348_ENET0_TXDMA_IRQ, + [IRQ_ENET1_RXDMA] = BCM_6348_ENET1_RXDMA_IRQ, + [IRQ_ENET1_TXDMA] = BCM_6348_ENET1_TXDMA_IRQ, + [IRQ_PCI] = BCM_6348_PCI_IRQ, +}; + +/* + * 6358 register sets and irqs + */ +static const unsigned long bcm96358_regs_base[] = { + [RSET_DSL_LMEM] = BCM_6358_DSL_LMEM_BASE, + [RSET_PERF] = BCM_6358_PERF_BASE, + [RSET_TIMER] = BCM_6358_TIMER_BASE, + [RSET_WDT] = BCM_6358_WDT_BASE, + [RSET_UART0] = BCM_6358_UART0_BASE, + [RSET_GPIO] = BCM_6358_GPIO_BASE, + [RSET_SPI] = BCM_6358_SPI_BASE, + [RSET_OHCI0] = BCM_6358_OHCI0_BASE, + [RSET_EHCI0] = BCM_6358_EHCI0_BASE, + [RSET_OHCI_PRIV] = BCM_6358_OHCI_PRIV_BASE, + [RSET_USBH_PRIV] = BCM_6358_USBH_PRIV_BASE, + [RSET_MPI] = BCM_6358_MPI_BASE, + [RSET_PCMCIA] = BCM_6358_PCMCIA_BASE, + [RSET_SDRAM] = BCM_6358_SDRAM_BASE, + [RSET_DSL] = BCM_6358_DSL_BASE, + [RSET_ENET0] = BCM_6358_ENET0_BASE, + [RSET_ENET1] = BCM_6358_ENET1_BASE, + [RSET_ENETDMA] = BCM_6358_ENETDMA_BASE, + [RSET_MEMC] = BCM_6358_MEMC_BASE, + [RSET_DDR] = BCM_6358_DDR_BASE, +}; + +static const int bcm96358_irqs[] = { + [IRQ_TIMER] = BCM_6358_TIMER_IRQ, + [IRQ_UART0] = BCM_6358_UART0_IRQ, + [IRQ_DSL] = BCM_6358_DSL_IRQ, + [IRQ_ENET0] = BCM_6358_ENET0_IRQ, + [IRQ_ENET1] = BCM_6358_ENET1_IRQ, + [IRQ_ENET_PHY] = BCM_6358_ENET_PHY_IRQ, + [IRQ_OHCI0] = BCM_6358_OHCI0_IRQ, + [IRQ_EHCI0] = BCM_6358_EHCI0_IRQ, + [IRQ_PCMCIA] = BCM_6358_PCMCIA_IRQ, + [IRQ_ENET0_RXDMA] = BCM_6358_ENET0_RXDMA_IRQ, + [IRQ_ENET0_TXDMA] = BCM_6358_ENET0_TXDMA_IRQ, + [IRQ_ENET1_RXDMA] = BCM_6358_ENET1_RXDMA_IRQ, + [IRQ_ENET1_TXDMA] = BCM_6358_ENET1_TXDMA_IRQ, + [IRQ_PCI] = BCM_6358_PCI_IRQ, +}; + +u16 __bcm63xx_get_cpu_id(void) +{ + return bcm63xx_cpu_id; +} + +EXPORT_SYMBOL(__bcm63xx_get_cpu_id); + +u16 bcm63xx_get_cpu_rev(void) +{ + return bcm63xx_cpu_rev; +} + +EXPORT_SYMBOL(bcm63xx_get_cpu_rev); + +unsigned int bcm63xx_get_cpu_freq(void) +{ + return bcm63xx_cpu_freq; +} + +unsigned int bcm63xx_get_memory_size(void) +{ + return bcm63xx_memory_size; +} + +static unsigned int detect_cpu_clock(void) +{ + unsigned int tmp, n1 = 0, n2 = 0, m1 = 0; + + /* BCM6338 has a fixed 240 Mhz frequency */ + if (BCMCPU_IS_6338()) + return 240000000; + + /* BCM6345 has a fixed 140Mhz frequency */ + if (BCMCPU_IS_6345()) + return 140000000; + + /* + * frequency depends on PLL configuration: + */ + if (BCMCPU_IS_6348()) { + /* 16MHz * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) */ + tmp = bcm_perf_readl(PERF_MIPSPLLCTL_REG); + n1 = (tmp & MIPSPLLCTL_N1_MASK) >> MIPSPLLCTL_N1_SHIFT; + n2 = (tmp & MIPSPLLCTL_N2_MASK) >> MIPSPLLCTL_N2_SHIFT; + m1 = (tmp & MIPSPLLCTL_M1CPU_MASK) >> MIPSPLLCTL_M1CPU_SHIFT; + n1 += 1; + n2 += 2; + m1 += 1; + } + + if (BCMCPU_IS_6358()) { + /* 16MHz * N1 * N2 / M1_CPU */ + tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_REG); + n1 = (tmp & DMIPSPLLCFG_N1_MASK) >> DMIPSPLLCFG_N1_SHIFT; + n2 = (tmp & DMIPSPLLCFG_N2_MASK) >> DMIPSPLLCFG_N2_SHIFT; + m1 = (tmp & DMIPSPLLCFG_M1_MASK) >> DMIPSPLLCFG_M1_SHIFT; + } + + return (16 * 1000000 * n1 * n2) / m1; +} + +/* + * attempt to detect the amount of memory installed + */ +static unsigned int detect_memory_size(void) +{ + unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0; + u32 val; + + if (BCMCPU_IS_6345()) + return (8 * 1024 * 1024); + + if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { + val = bcm_sdram_readl(SDRAM_CFG_REG); + rows = (val & SDRAM_CFG_ROW_MASK) >> SDRAM_CFG_ROW_SHIFT; + cols = (val & SDRAM_CFG_COL_MASK) >> SDRAM_CFG_COL_SHIFT; + is_32bits = (val & SDRAM_CFG_32B_MASK) ? 1 : 0; + banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1; + } + + if (BCMCPU_IS_6358()) { + val = bcm_memc_readl(MEMC_CFG_REG); + rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT; + cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT; + is_32bits = (val & MEMC_CFG_32B_MASK) ? 0 : 1; + banks = 2; + } + + /* 0 => 11 address bits ... 2 => 13 address bits */ + rows += 11; + + /* 0 => 8 address bits ... 2 => 10 address bits */ + cols += 8; + + return 1 << (cols + rows + (is_32bits + 1) + banks); +} + +void __init bcm63xx_cpu_init(void) +{ + unsigned int tmp, expected_cpu_id; + struct cpuinfo_mips *c = ¤t_cpu_data; + + /* soc registers location depends on cpu type */ + expected_cpu_id = 0; + + switch (c->cputype) { + /* + * BCM6338 as the same PrId as BCM3302 see arch/mips/kernel/cpu-probe.c + */ + case CPU_BCM3302: + expected_cpu_id = BCM6338_CPU_ID; + bcm63xx_regs_base = bcm96338_regs_base; + bcm63xx_irqs = bcm96338_irqs; + break; + case CPU_BCM6345: + expected_cpu_id = BCM6345_CPU_ID; + bcm63xx_regs_base = bcm96345_regs_base; + bcm63xx_irqs = bcm96345_irqs; + break; + case CPU_BCM6348: + expected_cpu_id = BCM6348_CPU_ID; + bcm63xx_regs_base = bcm96348_regs_base; + bcm63xx_irqs = bcm96348_irqs; + break; + case CPU_BCM6358: + expected_cpu_id = BCM6358_CPU_ID; + bcm63xx_regs_base = bcm96358_regs_base; + bcm63xx_irqs = bcm96358_irqs; + break; + } + + /* + * really early to panic, but delaying panic would not help since we + * will never get any working console + */ + if (!expected_cpu_id) + panic("unsupported Broadcom CPU"); + + /* + * bcm63xx_regs_base is set, we can access soc registers + */ + + /* double check CPU type */ + tmp = bcm_perf_readl(PERF_REV_REG); + bcm63xx_cpu_id = (tmp & REV_CHIPID_MASK) >> REV_CHIPID_SHIFT; + bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT; + + if (bcm63xx_cpu_id != expected_cpu_id) + panic("bcm63xx CPU id mismatch"); + + bcm63xx_cpu_freq = detect_cpu_clock(); + bcm63xx_memory_size = detect_memory_size(); + + printk(KERN_INFO "Detected Broadcom 0x%04x CPU revision %02x\n", + bcm63xx_cpu_id, bcm63xx_cpu_rev); + printk(KERN_INFO "CPU frequency is %u MHz\n", + bcm63xx_cpu_freq / 1000000); + printk(KERN_INFO "%uMB of RAM installed\n", + bcm63xx_memory_size >> 20); +} diff --git a/arch/mips/bcm63xx/cs.c b/arch/mips/bcm63xx/cs.c new file mode 100644 index 00000000000..50d8190bbf7 --- /dev/null +++ b/arch/mips/bcm63xx/cs.c @@ -0,0 +1,144 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/log2.h> +#include <bcm63xx_cpu.h> +#include <bcm63xx_io.h> +#include <bcm63xx_regs.h> +#include <bcm63xx_cs.h> + +static DEFINE_SPINLOCK(bcm63xx_cs_lock); + +/* + * check if given chip select exists + */ +static int is_valid_cs(unsigned int cs) +{ + if (cs > 6) + return 0; + return 1; +} + +/* + * Configure chipselect base address and size (bytes). + * Size must be a power of two between 8k and 256M. + */ +int bcm63xx_set_cs_base(unsigned int cs, u32 base, unsigned int size) +{ + unsigned long flags; + u32 val; + + if (!is_valid_cs(cs)) + return -EINVAL; + + /* sanity check on size */ + if (size != roundup_pow_of_two(size)) + return -EINVAL; + + if (size < 8 * 1024 || size > 256 * 1024 * 1024) + return -EINVAL; + + val = (base & MPI_CSBASE_BASE_MASK); + /* 8k => 0 - 256M => 15 */ + val |= (ilog2(size) - ilog2(8 * 1024)) << MPI_CSBASE_SIZE_SHIFT; + + spin_lock_irqsave(&bcm63xx_cs_lock, flags); + bcm_mpi_writel(val, MPI_CSBASE_REG(cs)); + spin_unlock_irqrestore(&bcm63xx_cs_lock, flags); + + return 0; +} + +EXPORT_SYMBOL(bcm63xx_set_cs_base); + +/* + * configure chipselect timing (ns) + */ +int bcm63xx_set_cs_timing(unsigned int cs, unsigned int wait, + unsigned int setup, unsigned int hold) +{ + unsigned long flags; + u32 val; + + if (!is_valid_cs(cs)) + return -EINVAL; + + spin_lock_irqsave(&bcm63xx_cs_lock, flags); + val = bcm_mpi_readl(MPI_CSCTL_REG(cs)); + val &= ~(MPI_CSCTL_WAIT_MASK); + val &= ~(MPI_CSCTL_SETUP_MASK); + val &= ~(MPI_CSCTL_HOLD_MASK); + val |= wait << MPI_CSCTL_WAIT_SHIFT; + val |= setup << MPI_CSCTL_SETUP_SHIFT; + val |= hold << MPI_CSCTL_HOLD_SHIFT; + bcm_mpi_writel(val, MPI_CSCTL_REG(cs)); + spin_unlock_irqrestore(&bcm63xx_cs_lock, flags); + + return 0; +} + +EXPORT_SYMBOL(bcm63xx_set_cs_timing); + +/* + * configure other chipselect parameter (data bus size, ...) + */ +int bcm63xx_set_cs_param(unsigned int cs, u32 params) +{ + unsigned long flags; + u32 val; + + if (!is_valid_cs(cs)) + return -EINVAL; + + /* none of this fields apply to pcmcia */ + if (cs == MPI_CS_PCMCIA_COMMON || + cs == MPI_CS_PCMCIA_ATTR || + cs == MPI_CS_PCMCIA_IO) + return -EINVAL; + + spin_lock_irqsave(&bcm63xx_cs_lock, flags); + val = bcm_mpi_readl(MPI_CSCTL_REG(cs)); + val &= ~(MPI_CSCTL_DATA16_MASK); + val &= ~(MPI_CSCTL_SYNCMODE_MASK); + val &= ~(MPI_CSCTL_TSIZE_MASK); + val &= ~(MPI_CSCTL_ENDIANSWAP_MASK); + val |= params; + bcm_mpi_writel(val, MPI_CSCTL_REG(cs)); + spin_unlock_irqrestore(&bcm63xx_cs_lock, flags); + + return 0; +} + +EXPORT_SYMBOL(bcm63xx_set_cs_param); + +/* + * set cs status (enable/disable) + */ +int bcm63xx_set_cs_status(unsigned int cs, int enable) +{ + unsigned long flags; + u32 val; + + if (!is_valid_cs(cs)) + return -EINVAL; + + spin_lock_irqsave(&bcm63xx_cs_lock, flags); + val = bcm_mpi_readl(MPI_CSCTL_REG(cs)); + if (enable) + val |= MPI_CSCTL_ENABLE_MASK; + else + val &= ~MPI_CSCTL_ENABLE_MASK; + bcm_mpi_writel(val, MPI_CSCTL_REG(cs)); + spin_unlock_irqrestore(&bcm63xx_cs_lock, flags); + return 0; +} + +EXPORT_SYMBOL(bcm63xx_set_cs_status); diff --git a/arch/mips/bcm63xx/dev-dsp.c b/arch/mips/bcm63xx/dev-dsp.c new file mode 100644 index 00000000000..da46d1d3c77 --- /dev/null +++ b/arch/mips/bcm63xx/dev-dsp.c @@ -0,0 +1,56 @@ +/* + * Broadcom BCM63xx VoIP DSP registration + * + * 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) 2009 Florian Fainelli <florian@openwrt.org> + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> + +#include <bcm63xx_cpu.h> +#include <bcm63xx_dev_dsp.h> +#include <bcm63xx_regs.h> +#include <bcm63xx_io.h> + +static struct resource voip_dsp_resources[] = { + { + .start = -1, /* filled at runtime */ + .end = -1, /* filled at runtime */ + .flags = IORESOURCE_MEM, + }, + { + .start = -1, /* filled at runtime */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bcm63xx_voip_dsp_device = { + .name = "bcm63xx-voip-dsp", + .id = 0, + .num_resources = ARRAY_SIZE(voip_dsp_resources), + .resource = voip_dsp_resources, +}; + +int __init bcm63xx_dsp_register(const struct bcm63xx_dsp_platform_data *pd) +{ + struct bcm63xx_dsp_platform_data *dpd; + u32 val; + + /* Get the memory window */ + val = bcm_mpi_readl(MPI_CSBASE_REG(pd->cs - 1)); + val &= MPI_CSBASE_BASE_MASK; + voip_dsp_resources[0].start = val; + voip_dsp_resources[0].end = val + 0xFFFFFFF; + voip_dsp_resources[1].start = pd->ext_irq; + + /* copy given platform data */ + dpd = bcm63xx_voip_dsp_device.dev.platform_data; + memcpy(dpd, pd, sizeof (*pd)); + + return platform_device_register(&bcm63xx_voip_dsp_device); +} diff --git a/arch/mips/bcm63xx/dev-enet.c b/arch/mips/bcm63xx/dev-enet.c new file mode 100644 index 00000000000..9f544badd0b --- /dev/null +++ b/arch/mips/bcm63xx/dev-enet.c @@ -0,0 +1,159 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <bcm63xx_dev_enet.h> +#include <bcm63xx_io.h> +#include <bcm63xx_regs.h> + +static struct resource shared_res[] = { + { + .start = -1, /* filled at runtime */ + .end = -1, /* filled at runtime */ + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device bcm63xx_enet_shared_device = { + .name = "bcm63xx_enet_shared", + .id = 0, + .num_resources = ARRAY_SIZE(shared_res), + .resource = shared_res, +}; + +static int shared_device_registered; + +static struct resource enet0_res[] = { + { + .start = -1, /* filled at runtime */ + .end = -1, /* filled at runtime */ + .flags = IORESOURCE_MEM, + }, + { + .start = -1, /* filled at runtime */ + .flags = IORESOURCE_IRQ, + }, + { + .start = -1, /* filled at runtime */ + .flags = IORESOURCE_IRQ, + }, + { + .start = -1, /* filled at runtime */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct bcm63xx_enet_platform_data enet0_pd; + +static struct platform_device bcm63xx_enet0_device = { + .name = "bcm63xx_enet", + .id = 0, + .num_resources = ARRAY_SIZE(enet0_res), + .resource = enet0_res, + .dev = { + .platform_data = &enet0_pd, + }, +}; + +static struct resource enet1_res[] = { + { + .start = -1, /* filled at runtime */ + .end = -1, /* filled at runtime */ + .flags = IORESOURCE_MEM, + }, + { + .start = -1, /* filled at runtime */ + .flags = IORESOURCE_IRQ, + }, + { + .start = -1, /* filled at runtime */ + .flags = IORESOURCE_IRQ, + }, + { + .start = -1, /* filled at runtime */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct bcm63xx_enet_platform_data enet1_pd; + +static struct platform_device bcm63xx_enet1_device = { + .name = "bcm63xx_enet", + .id = 1, + .num_resources = ARRAY_SIZE(enet1_res), + .resource = enet1_res, + .dev = { + .platform_data = &enet1_pd, + }, +}; + +int __init bcm63xx_enet_register(int unit, + const struct bcm63xx_enet_platform_data *pd) +{ + struct platform_device *pdev; + struct bcm63xx_enet_platform_data *dpd; + int ret; + + if (unit > 1) + return -ENODEV; + + if (!shared_device_registered) { + shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA); + shared_res[0].end = shared_res[0].start; + if (BCMCPU_IS_6338()) + shared_res[0].end += (RSET_ENETDMA_SIZE / 2) - 1; + else + shared_res[0].end += (RSET_ENETDMA_SIZE) - 1; + + ret = platform_device_register(&bcm63xx_enet_shared_device); + if (ret) + return ret; + shared_device_registered = 1; + } + + if (unit == 0) { + enet0_res[0].start = bcm63xx_regset_address(RSET_ENET0); + enet0_res[0].end = enet0_res[0].start; + enet0_res[0].end += RSET_ENET_SIZE - 1; + enet0_res[1].start = bcm63xx_get_irq_number(IRQ_ENET0); + enet0_res[2].start = bcm63xx_get_irq_number(IRQ_ENET0_RXDMA); + enet0_res[3].start = bcm63xx_get_irq_number(IRQ_ENET0_TXDMA); + pdev = &bcm63xx_enet0_device; + } else { + enet1_res[0].start = bcm63xx_regset_address(RSET_ENET1); + enet1_res[0].end = enet1_res[0].start; + enet1_res[0].end += RSET_ENET_SIZE - 1; + enet1_res[1].start = bcm63xx_get_irq_number(IRQ_ENET1); + enet1_res[2].start = bcm63xx_get_irq_number(IRQ_ENET1_RXDMA); + enet1_res[3].start = bcm63xx_get_irq_number(IRQ_ENET1_TXDMA); + pdev = &bcm63xx_enet1_device; + } + + /* copy given platform data */ + dpd = pdev->dev.platform_data; + memcpy(dpd, pd, sizeof(*pd)); + + /* adjust them in case internal phy is used */ + if (dpd->use_internal_phy) { + + /* internal phy only exists for enet0 */ + if (unit == 1) + return -ENODEV; + + dpd->phy_id = 1; + dpd->has_phy_interrupt = 1; + dpd->phy_interrupt = bcm63xx_get_irq_number(IRQ_ENET_PHY); + } + + ret = platform_device_register(pdev); + if (ret) + return ret; + return 0; +} diff --git a/arch/mips/bcm63xx/early_printk.c b/arch/mips/bcm63xx/early_printk.c new file mode 100644 index 00000000000..bf353c937df --- /dev/null +++ b/arch/mips/bcm63xx/early_printk.c @@ -0,0 +1,30 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + */ + +#include <linux/init.h> +#include <bcm63xx_io.h> +#include <bcm63xx_regs.h> + +static void __init wait_xfered(void) +{ + unsigned int val; + + /* wait for any previous char to be transmitted */ + do { + val = bcm_uart0_readl(UART_IR_REG); + if (val & UART_IR_STAT(UART_IR_TXEMPTY)) + break; + } while (1); +} + +void __init prom_putchar(char c) +{ + wait_xfered(); + bcm_uart0_writel(c, UART_FIFO_REG); + wait_xfered(); +} diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c new file mode 100644 index 00000000000..87ca3904633 --- /dev/null +++ b/arch/mips/bcm63xx/gpio.c @@ -0,0 +1,134 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> + +#include <bcm63xx_cpu.h> +#include <bcm63xx_gpio.h> +#include <bcm63xx_io.h> +#include <bcm63xx_regs.h> + +static DEFINE_SPINLOCK(bcm63xx_gpio_lock); +static u32 gpio_out_low, gpio_out_high; + +static void bcm63xx_gpio_set(struct gpio_chip *chip, + unsigned gpio, int val) +{ + u32 reg; + u32 mask; + u32 *v; + unsigned long flags; + + if (gpio >= chip->ngpio) + BUG(); + + if (gpio < 32) { + reg = GPIO_DATA_LO_REG; + mask = 1 << gpio; + v = &gpio_out_low; + } else { + reg = GPIO_DATA_HI_REG; + mask = 1 << (gpio - 32); + v = &gpio_out_high; + } + + spin_lock_irqsave(&bcm63xx_gpio_lock, flags); + if (val) + *v |= mask; + else + *v &= ~mask; + bcm_gpio_writel(*v, reg); + spin_unlock_irqrestore(&bcm63xx_gpio_lock, flags); +} + +static int bcm63xx_gpio_get(struct gpio_chip *chip, unsigned gpio) +{ + u32 reg; + u32 mask; + + if (gpio >= chip->ngpio) + BUG(); + + if (gpio < 32) { + reg = GPIO_DATA_LO_REG; + mask = 1 << gpio; + } else { + reg = GPIO_DATA_HI_REG; + mask = 1 << (gpio - 32); + } + + return !!(bcm_gpio_readl(reg) & mask); +} + +static int bcm63xx_gpio_set_direction(struct gpio_chip *chip, + unsigned gpio, int dir) +{ + u32 reg; + u32 mask; + u32 tmp; + unsigned long flags; + + if (gpio >= chip->ngpio) + BUG(); + + if (gpio < 32) { + reg = GPIO_CTL_LO_REG; + mask = 1 << gpio; + } else { + reg = GPIO_CTL_HI_REG; + mask = 1 << (gpio - 32); + } + + spin_lock_irqsave(&bcm63xx_gpio_lock, flags); + tmp = bcm_gpio_readl(reg); + if (dir == GPIO_DIR_IN) + tmp &= ~mask; + else + tmp |= mask; + bcm_gpio_writel(tmp, reg); + spin_unlock_irqrestore(&bcm63xx_gpio_lock, flags); + + return 0; +} + +static int bcm63xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + return bcm63xx_gpio_set_direction(chip, gpio, GPIO_DIR_IN); +} + +static int bcm63xx_gpio_direction_output(struct gpio_chip *chip, + unsigned gpio, int value) +{ + bcm63xx_gpio_set(chip, gpio, value); + return bcm63xx_gpio_set_direction(chip, gpio, GPIO_DIR_OUT); +} + + +static struct gpio_chip bcm63xx_gpio_chip = { + .label = "bcm63xx-gpio", + .direction_input = bcm63xx_gpio_direction_input, + .direction_output = bcm63xx_gpio_direction_output, + .get = bcm63xx_gpio_get, + .set = bcm63xx_gpio_set, + .base = 0, +}; + +int __init bcm63xx_gpio_init(void) +{ + bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count(); + pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio); + + return gpiochip_add(&bcm63xx_gpio_chip); +} + +arch_initcall(bcm63xx_gpio_init); diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c new file mode 100644 index 00000000000..a0c5cd18c19 --- /dev/null +++ b/arch/mips/bcm63xx/irq.c @@ -0,0 +1,253 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + * Copyright (C) 2008 Nicolas Schichan <nschichan@freebox.fr> + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <asm/irq_cpu.h> +#include <asm/mipsregs.h> +#include <bcm63xx_cpu.h> +#include <bcm63xx_regs.h> +#include <bcm63xx_io.h> +#include <bcm63xx_irq.h> + +/* + * dispatch internal devices IRQ (uart, enet, watchdog, ...). do not + * prioritize any interrupt relatively to another. the static counter + * will resume the loop where it ended the last time we left this + * function. + */ +static void bcm63xx_irq_dispatch_internal(void) +{ + u32 pending; + static int i; + + pending = bcm_perf_readl(PERF_IRQMASK_REG) & + bcm_perf_readl(PERF_IRQSTAT_REG); + + if (!pending) + return ; + + while (1) { + int to_call = i; + + i = (i + 1) & 0x1f; + if (pending & (1 << to_call)) { + do_IRQ(to_call + IRQ_INTERNAL_BASE); + break; + } + } +} + +asmlinkage void plat_irq_dispatch(void) +{ + u32 cause; + + do { + cause = read_c0_cause() & read_c0_status() & ST0_IM; + + if (!cause) + break; + + if (cause & CAUSEF_IP7) + do_IRQ(7); + if (cause & CAUSEF_IP2) + bcm63xx_irq_dispatch_internal(); + if (cause & CAUSEF_IP3) + do_IRQ(IRQ_EXT_0); + if (cause & CAUSEF_IP4) + do_IRQ(IRQ_EXT_1); + if (cause & CAUSEF_IP5) + do_IRQ(IRQ_EXT_2); + if (cause & CAUSEF_IP6) + do_IRQ(IRQ_EXT_3); + } while (1); +} + +/* + * internal IRQs operations: only mask/unmask on PERF irq mask + * register. + */ +static inline void bcm63xx_internal_irq_mask(unsigned int irq) +{ + u32 mask; + + irq -= IRQ_INTERNAL_BASE; + mask = bcm_perf_readl(PERF_IRQMASK_REG); + mask &= ~(1 << irq); + bcm_perf_writel(mask, PERF_IRQMASK_REG); +} + +static void bcm63xx_internal_irq_unmask(unsigned int irq) +{ + u32 mask; + + irq -= IRQ_INTERNAL_BASE; + mask = bcm_perf_readl(PERF_IRQMASK_REG); + mask |= (1 << irq); + bcm_perf_writel(mask, PERF_IRQMASK_REG); +} + +static unsigned int bcm63xx_internal_irq_startup(unsigned int irq) +{ + bcm63xx_internal_irq_unmask(irq); + return 0; +} + +/* + * external IRQs operations: mask/unmask and clear on PERF external + * irq control register. + */ +static void bcm63xx_external_irq_mask(unsigned int irq) +{ + u32 reg; + + irq -= IRQ_EXT_BASE; + reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); + reg &= ~EXTIRQ_CFG_MASK(irq); + bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); +} + +static void bcm63xx_external_irq_unmask(unsigned int irq) +{ + u32 reg; + + irq -= IRQ_EXT_BASE; + reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); + reg |= EXTIRQ_CFG_MASK(irq); + bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); +} + +static void bcm63xx_external_irq_clear(unsigned int irq) +{ + u32 reg; + + irq -= IRQ_EXT_BASE; + reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); + reg |= EXTIRQ_CFG_CLEAR(irq); + bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); +} + +static unsigned int bcm63xx_external_irq_startup(unsigned int irq) +{ + set_c0_status(0x100 << (irq - IRQ_MIPS_BASE)); + irq_enable_hazard(); + bcm63xx_external_irq_unmask(irq); + return 0; +} + +static void bcm63xx_external_irq_shutdown(unsigned int irq) +{ + bcm63xx_external_irq_mask(irq); + clear_c0_status(0x100 << (irq - IRQ_MIPS_BASE)); + irq_disable_hazard(); +} + +static int bcm63xx_external_irq_set_type(unsigned int irq, + unsigned int flow_type) +{ + u32 reg; + struct irq_desc *desc = irq_desc + irq; + + irq -= IRQ_EXT_BASE; + + flow_type &= IRQ_TYPE_SENSE_MASK; + + if (flow_type == IRQ_TYPE_NONE) + flow_type = IRQ_TYPE_LEVEL_LOW; + + reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); + switch (flow_type) { + case IRQ_TYPE_EDGE_BOTH: + reg &= ~EXTIRQ_CFG_LEVELSENSE(irq); + reg |= EXTIRQ_CFG_BOTHEDGE(irq); + break; + + case IRQ_TYPE_EDGE_RISING: + reg &= ~EXTIRQ_CFG_LEVELSENSE(irq); + reg |= EXTIRQ_CFG_SENSE(irq); + reg &= ~EXTIRQ_CFG_BOTHEDGE(irq); + break; + + case IRQ_TYPE_EDGE_FALLING: + reg &= ~EXTIRQ_CFG_LEVELSENSE(irq); + reg &= ~EXTIRQ_CFG_SENSE(irq); + reg &= ~EXTIRQ_CFG_BOTHEDGE(irq); + break; + + case IRQ_TYPE_LEVEL_HIGH: + reg |= EXTIRQ_CFG_LEVELSENSE(irq); + reg |= EXTIRQ_CFG_SENSE(irq); + break; + + case IRQ_TYPE_LEVEL_LOW: + reg |= EXTIRQ_CFG_LEVELSENSE(irq); + reg &= ~EXTIRQ_CFG_SENSE(irq); + break; + + default: + printk(KERN_ERR "bogus flow type combination given !\n"); + return -EINVAL; + } + bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); + + if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) { + desc->status |= IRQ_LEVEL; + desc->handle_irq = handle_level_irq; + } else { + desc->handle_irq = handle_edge_irq; + } + + return 0; +} + +static struct irq_chip bcm63xx_internal_irq_chip = { + .name = "bcm63xx_ipic", + .startup = bcm63xx_internal_irq_startup, + .shutdown = bcm63xx_internal_irq_mask, + + .mask = bcm63xx_internal_irq_mask, + .mask_ack = bcm63xx_internal_irq_mask, + .unmask = bcm63xx_internal_irq_unmask, +}; + +static struct irq_chip bcm63xx_external_irq_chip = { + .name = "bcm63xx_epic", + .startup = bcm63xx_external_irq_startup, + .shutdown = bcm63xx_external_irq_shutdown, + + .ack = bcm63xx_external_irq_clear, + + .mask = bcm63xx_external_irq_mask, + .unmask = bcm63xx_external_irq_unmask, + + .set_type = bcm63xx_external_irq_set_type, +}; + +static struct irqaction cpu_ip2_cascade_action = { + .handler = no_action, + .name = "cascade_ip2", +}; + +void __init arch_init_irq(void) +{ + int i; + + mips_cpu_irq_init(); + for (i = IRQ_INTERNAL_BASE; i < NR_IRQS; ++i) + set_irq_chip_and_handler(i, &bcm63xx_internal_irq_chip, + handle_level_irq); + + for (i = IRQ_EXT_BASE; i < IRQ_EXT_BASE + 4; ++i) + set_irq_chip_and_handler(i, &bcm63xx_external_irq_chip, + handle_edge_irq); + + setup_irq(IRQ_MIPS_BASE + 2, &cpu_ip2_cascade_action); +} diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c new file mode 100644 index 00000000000..fb284fbc585 --- /dev/null +++ b/arch/mips/bcm63xx/prom.c @@ -0,0 +1,55 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + */ + +#include <linux/init.h> +#include <linux/bootmem.h> +#include <asm/bootinfo.h> +#include <bcm63xx_board.h> +#include <bcm63xx_cpu.h> +#include <bcm63xx_io.h> +#include <bcm63xx_regs.h> +#include <bcm63xx_gpio.h> + +void __init prom_init(void) +{ + u32 reg, mask; + + bcm63xx_cpu_init(); + + /* stop any running watchdog */ + bcm_wdt_writel(WDT_STOP_1, WDT_CTL_REG); + bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG); + + /* disable all hardware blocks clock for now */ + if (BCMCPU_IS_6338()) + mask = CKCTL_6338_ALL_SAFE_EN; + else if (BCMCPU_IS_6345()) + mask = CKCTL_6345_ALL_SAFE_EN; + else if (BCMCPU_IS_6348()) + mask = CKCTL_6348_ALL_SAFE_EN; + else + /* BCMCPU_IS_6358() */ + mask = CKCTL_6358_ALL_SAFE_EN; + + reg = bcm_perf_readl(PERF_CKCTL_REG); + reg &= ~mask; + bcm_perf_writel(reg, PERF_CKCTL_REG); + + /* assign command line from kernel config */ + strcpy(arcs_cmdline, CONFIG_CMDLINE); + + /* register gpiochip */ + bcm63xx_gpio_init(); + + /* do low level board init */ + board_prom_init(); +} + +void __init prom_free_prom_memory(void) +{ +} diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c new file mode 100644 index 00000000000..b18a0ca926f --- /dev/null +++ b/arch/mips/bcm63xx/setup.c @@ -0,0 +1,125 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/bootmem.h> +#include <linux/ioport.h> +#include <linux/pm.h> +#include <asm/bootinfo.h> +#include <asm/time.h> +#include <asm/reboot.h> +#include <asm/cacheflush.h> +#include <bcm63xx_board.h> +#include <bcm63xx_cpu.h> +#include <bcm63xx_regs.h> +#include <bcm63xx_io.h> + +void bcm63xx_machine_halt(void) +{ + printk(KERN_INFO "System halted\n"); + while (1) + ; +} + +static void bcm6348_a1_reboot(void) +{ + u32 reg; + + /* soft reset all blocks */ + printk(KERN_INFO "soft-reseting all blocks ...\n"); + reg = bcm_perf_readl(PERF_SOFTRESET_REG); + reg &= ~SOFTRESET_6348_ALL; + bcm_perf_writel(reg, PERF_SOFTRESET_REG); + mdelay(10); + + reg = bcm_perf_readl(PERF_SOFTRESET_REG); + reg |= SOFTRESET_6348_ALL; + bcm_perf_writel(reg, PERF_SOFTRESET_REG); + mdelay(10); + + /* Jump to the power on address. */ + printk(KERN_INFO "jumping to reset vector.\n"); + /* set high vectors (base at 0xbfc00000 */ + set_c0_status(ST0_BEV | ST0_ERL); + /* run uncached in kseg0 */ + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + __flush_cache_all(); + /* remove all wired TLB entries */ + write_c0_wired(0); + __asm__ __volatile__( + "jr\t%0" + : + : "r" (0xbfc00000)); + while (1) + ; +} + +void bcm63xx_machine_reboot(void) +{ + u32 reg; + + /* mask and clear all external irq */ + reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); + reg &= ~EXTIRQ_CFG_MASK_ALL; + reg |= EXTIRQ_CFG_CLEAR_ALL; + bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); + + if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() == 0xa1)) + bcm6348_a1_reboot(); + + printk(KERN_INFO "triggering watchdog soft-reset...\n"); + bcm_perf_writel(SYS_PLL_SOFT_RESET, PERF_SYS_PLL_CTL_REG); + while (1) + ; +} + +static void __bcm63xx_machine_reboot(char *p) +{ + bcm63xx_machine_reboot(); +} + +/* + * return system type in /proc/cpuinfo + */ +const char *get_system_type(void) +{ + static char buf[128]; + snprintf(buf, sizeof(buf), "bcm63xx/%s (0x%04x/0x%04X)", + board_get_name(), + bcm63xx_get_cpu_id(), bcm63xx_get_cpu_rev()); + return buf; +} + +void __init plat_time_init(void) +{ + mips_hpt_frequency = bcm63xx_get_cpu_freq() / 2; +} + +void __init plat_mem_setup(void) +{ + add_memory_region(0, bcm63xx_get_memory_size(), BOOT_MEM_RAM); + + _machine_halt = bcm63xx_machine_halt; + _machine_restart = __bcm63xx_machine_reboot; + pm_power_off = bcm63xx_machine_halt; + + set_io_port_base(0); + ioport_resource.start = 0; + ioport_resource.end = ~0; + + board_setup(); +} + +int __init bcm63xx_register_devices(void) +{ + return board_register_devices(); +} + +arch_initcall(bcm63xx_register_devices); diff --git a/arch/mips/bcm63xx/timer.c b/arch/mips/bcm63xx/timer.c new file mode 100644 index 00000000000..ba522bdcde4 --- /dev/null +++ b/arch/mips/bcm63xx/timer.c @@ -0,0 +1,205 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + */ + +#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/interrupt.h> +#include <linux/clk.h> +#include <bcm63xx_cpu.h> +#include <bcm63xx_io.h> +#include <bcm63xx_timer.h> +#include <bcm63xx_regs.h> + +static DEFINE_SPINLOCK(timer_reg_lock); +static DEFINE_SPINLOCK(timer_data_lock); +static struct clk *periph_clk; + +static struct timer_data { + void (*cb)(void *); + void *data; +} timer_data[BCM63XX_TIMER_COUNT]; + +static irqreturn_t timer_interrupt(int irq, void *dev_id) +{ + u32 stat; + int i; + + spin_lock(&timer_reg_lock); + stat = bcm_timer_readl(TIMER_IRQSTAT_REG); + bcm_timer_writel(stat, TIMER_IRQSTAT_REG); + spin_unlock(&timer_reg_lock); + + for (i = 0; i < BCM63XX_TIMER_COUNT; i++) { + if (!(stat & TIMER_IRQSTAT_TIMER_CAUSE(i))) + continue; + + spin_lock(&timer_data_lock); + if (!timer_data[i].cb) { + spin_unlock(&timer_data_lock); + continue; + } + + timer_data[i].cb(timer_data[i].data); + spin_unlock(&timer_data_lock); + } + + return IRQ_HANDLED; +} + +int bcm63xx_timer_enable(int id) +{ + u32 reg; + unsigned long flags; + + if (id >= BCM63XX_TIMER_COUNT) + return -EINVAL; + + spin_lock_irqsave(&timer_reg_lock, flags); + + reg = bcm_timer_readl(TIMER_CTLx_REG(id)); + reg |= TIMER_CTL_ENABLE_MASK; + bcm_timer_writel(reg, TIMER_CTLx_REG(id)); + + reg = bcm_timer_readl(TIMER_IRQSTAT_REG); + reg |= TIMER_IRQSTAT_TIMER_IR_EN(id); + bcm_timer_writel(reg, TIMER_IRQSTAT_REG); + + spin_unlock_irqrestore(&timer_reg_lock, flags); + return 0; +} + +EXPORT_SYMBOL(bcm63xx_timer_enable); + +int bcm63xx_timer_disable(int id) +{ + u32 reg; + unsigned long flags; + + if (id >= BCM63XX_TIMER_COUNT) + return -EINVAL; + + spin_lock_irqsave(&timer_reg_lock, flags); + + reg = bcm_timer_readl(TIMER_CTLx_REG(id)); + reg &= ~TIMER_CTL_ENABLE_MASK; + bcm_timer_writel(reg, TIMER_CTLx_REG(id)); + + reg = bcm_timer_readl(TIMER_IRQSTAT_REG); + reg &= ~TIMER_IRQSTAT_TIMER_IR_EN(id); + bcm_timer_writel(reg, TIMER_IRQSTAT_REG); + + spin_unlock_irqrestore(&timer_reg_lock, flags); + return 0; +} + +EXPORT_SYMBOL(bcm63xx_timer_disable); + +int bcm63xx_timer_register(int id, void (*callback)(void *data), void *data) +{ + unsigned long flags; + int ret; + + if (id >= BCM63XX_TIMER_COUNT || !callback) + return -EINVAL; + + ret = 0; + spin_lock_irqsave(&timer_data_lock, flags); + if (timer_data[id].cb) { + ret = -EBUSY; + goto out; + } + + timer_data[id].cb = callback; + timer_data[id].data = data; + +out: + spin_unlock_irqrestore(&timer_data_lock, flags); + return ret; +} + +EXPORT_SYMBOL(bcm63xx_timer_register); + +void bcm63xx_timer_unregister(int id) +{ + unsigned long flags; + + if (id >= BCM63XX_TIMER_COUNT) + return; + + spin_lock_irqsave(&timer_data_lock, flags); + timer_data[id].cb = NULL; + spin_unlock_irqrestore(&timer_data_lock, flags); +} + +EXPORT_SYMBOL(bcm63xx_timer_unregister); + +unsigned int bcm63xx_timer_countdown(unsigned int countdown_us) +{ + return (clk_get_rate(periph_clk) / (1000 * 1000)) * countdown_us; +} + +EXPORT_SYMBOL(bcm63xx_timer_countdown); + +int bcm63xx_timer_set(int id, int monotonic, unsigned int countdown_us) +{ + u32 reg, countdown; + unsigned long flags; + + if (id >= BCM63XX_TIMER_COUNT) + return -EINVAL; + + countdown = bcm63xx_timer_countdown(countdown_us); + if (countdown & ~TIMER_CTL_COUNTDOWN_MASK) + return -EINVAL; + + spin_lock_irqsave(&timer_reg_lock, flags); + reg = bcm_timer_readl(TIMER_CTLx_REG(id)); + + if (monotonic) + reg &= ~TIMER_CTL_MONOTONIC_MASK; + else + reg |= TIMER_CTL_MONOTONIC_MASK; + + reg &= ~TIMER_CTL_COUNTDOWN_MASK; + reg |= countdown; + bcm_timer_writel(reg, TIMER_CTLx_REG(id)); + + spin_unlock_irqrestore(&timer_reg_lock, flags); + return 0; +} + +EXPORT_SYMBOL(bcm63xx_timer_set); + +int bcm63xx_timer_init(void) +{ + int ret, irq; + u32 reg; + + reg = bcm_timer_readl(TIMER_IRQSTAT_REG); + reg &= ~TIMER_IRQSTAT_TIMER0_IR_EN; + reg &= ~TIMER_IRQSTAT_TIMER1_IR_EN; + reg &= ~TIMER_IRQSTAT_TIMER2_IR_EN; + bcm_timer_writel(reg, TIMER_IRQSTAT_REG); + + periph_clk = clk_get(NULL, "periph"); + if (IS_ERR(periph_clk)) + return -ENODEV; + + irq = bcm63xx_get_irq_number(IRQ_TIMER); + ret = request_irq(irq, timer_interrupt, 0, "bcm63xx_timer", NULL); + if (ret) { + printk(KERN_ERR "bcm63xx_timer: failed to register irq\n"); + return ret; + } + + return 0; +} + +arch_initcall(bcm63xx_timer_init); diff --git a/arch/mips/boot/elf2ecoff.c b/arch/mips/boot/elf2ecoff.c index c5a7f308c40..e19d906236a 100644 --- a/arch/mips/boot/elf2ecoff.c +++ b/arch/mips/boot/elf2ecoff.c @@ -59,8 +59,8 @@ struct sect { }; int *symTypeTable; -int must_convert_endian = 0; -int format_bigendian = 0; +int must_convert_endian; +int format_bigendian; static void copy(int out, int in, off_t offset, off_t size) { diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile index d6903c3f3d5..13943628052 100644 --- a/arch/mips/cavium-octeon/Makefile +++ b/arch/mips/cavium-octeon/Makefile @@ -6,10 +6,10 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (C) 2005-2008 Cavium Networks +# Copyright (C) 2005-2009 Cavium Networks # -obj-y := setup.o serial.o octeon-irq.o csrc-octeon.o +obj-y := setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o obj-y += dma-octeon.o flash_setup.o obj-y += octeon-memcpy.o diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c new file mode 100644 index 00000000000..be711dd2d91 --- /dev/null +++ b/arch/mips/cavium-octeon/octeon-platform.c @@ -0,0 +1,164 @@ +/* + * 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) 2004-2009 Cavium Networks + * Copyright (C) 2008 Wind River Systems + */ + +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <asm/octeon/octeon.h> +#include <asm/octeon/cvmx-rnm-defs.h> + +static struct octeon_cf_data octeon_cf_data; + +static int __init octeon_cf_device_init(void) +{ + union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg; + unsigned long base_ptr, region_base, region_size; + struct platform_device *pd; + struct resource cf_resources[3]; + unsigned int num_resources; + int i; + int ret = 0; + + /* Setup octeon-cf platform device if present. */ + base_ptr = 0; + if (octeon_bootinfo->major_version == 1 + && octeon_bootinfo->minor_version >= 1) { + if (octeon_bootinfo->compact_flash_common_base_addr) + base_ptr = + octeon_bootinfo->compact_flash_common_base_addr; + } else { + base_ptr = 0x1d000800; + } + + if (!base_ptr) + return ret; + + /* Find CS0 region. */ + for (i = 0; i < 8; i++) { + mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i)); + region_base = mio_boot_reg_cfg.s.base << 16; + region_size = (mio_boot_reg_cfg.s.size + 1) << 16; + if (mio_boot_reg_cfg.s.en && base_ptr >= region_base + && base_ptr < region_base + region_size) + break; + } + if (i >= 7) { + /* i and i + 1 are CS0 and CS1, both must be less than 8. */ + goto out; + } + octeon_cf_data.base_region = i; + octeon_cf_data.is16bit = mio_boot_reg_cfg.s.width; + octeon_cf_data.base_region_bias = base_ptr - region_base; + memset(cf_resources, 0, sizeof(cf_resources)); + num_resources = 0; + cf_resources[num_resources].flags = IORESOURCE_MEM; + cf_resources[num_resources].start = region_base; + cf_resources[num_resources].end = region_base + region_size - 1; + num_resources++; + + + if (!(base_ptr & 0xfffful)) { + /* + * Boot loader signals availability of DMA (true_ide + * mode) by setting low order bits of base_ptr to + * zero. + */ + + /* Asume that CS1 immediately follows. */ + mio_boot_reg_cfg.u64 = + cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1)); + region_base = mio_boot_reg_cfg.s.base << 16; + region_size = (mio_boot_reg_cfg.s.size + 1) << 16; + if (!mio_boot_reg_cfg.s.en) + goto out; + + cf_resources[num_resources].flags = IORESOURCE_MEM; + cf_resources[num_resources].start = region_base; + cf_resources[num_resources].end = region_base + region_size - 1; + num_resources++; + + octeon_cf_data.dma_engine = 0; + cf_resources[num_resources].flags = IORESOURCE_IRQ; + cf_resources[num_resources].start = OCTEON_IRQ_BOOTDMA; + cf_resources[num_resources].end = OCTEON_IRQ_BOOTDMA; + num_resources++; + } else { + octeon_cf_data.dma_engine = -1; + } + + pd = platform_device_alloc("pata_octeon_cf", -1); + if (!pd) { + ret = -ENOMEM; + goto out; + } + pd->dev.platform_data = &octeon_cf_data; + + ret = platform_device_add_resources(pd, cf_resources, num_resources); + if (ret) + goto fail; + + ret = platform_device_add(pd); + if (ret) + goto fail; + + return ret; +fail: + platform_device_put(pd); +out: + return ret; +} +device_initcall(octeon_cf_device_init); + +/* Octeon Random Number Generator. */ +static int __init octeon_rng_device_init(void) +{ + struct platform_device *pd; + int ret = 0; + + struct resource rng_resources[] = { + { + .flags = IORESOURCE_MEM, + .start = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS), + .end = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS) + 0xf + }, { + .flags = IORESOURCE_MEM, + .start = cvmx_build_io_address(8, 0), + .end = cvmx_build_io_address(8, 0) + 0x7 + } + }; + + pd = platform_device_alloc("octeon_rng", -1); + if (!pd) { + ret = -ENOMEM; + goto out; + } + + ret = platform_device_add_resources(pd, rng_resources, + ARRAY_SIZE(rng_resources)); + if (ret) + goto fail; + + ret = platform_device_add(pd); + if (ret) + goto fail; + + return ret; +fail: + platform_device_put(pd); + +out: + return ret; +} +device_initcall(octeon_rng_device_init); + +MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Platform driver for Octeon SOC"); diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index da559249cc2..b321d3b1687 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -11,7 +11,6 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/io.h> -#include <linux/irq.h> #include <linux/serial.h> #include <linux/smp.h> #include <linux/types.h> @@ -824,105 +823,3 @@ void prom_free_prom_memory(void) CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */ octeon_hal_setup_reserved32(); } - -static struct octeon_cf_data octeon_cf_data; - -static int __init octeon_cf_device_init(void) -{ - union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg; - unsigned long base_ptr, region_base, region_size; - struct platform_device *pd; - struct resource cf_resources[3]; - unsigned int num_resources; - int i; - int ret = 0; - - /* Setup octeon-cf platform device if present. */ - base_ptr = 0; - if (octeon_bootinfo->major_version == 1 - && octeon_bootinfo->minor_version >= 1) { - if (octeon_bootinfo->compact_flash_common_base_addr) - base_ptr = - octeon_bootinfo->compact_flash_common_base_addr; - } else { - base_ptr = 0x1d000800; - } - - if (!base_ptr) - return ret; - - /* Find CS0 region. */ - for (i = 0; i < 8; i++) { - mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i)); - region_base = mio_boot_reg_cfg.s.base << 16; - region_size = (mio_boot_reg_cfg.s.size + 1) << 16; - if (mio_boot_reg_cfg.s.en && base_ptr >= region_base - && base_ptr < region_base + region_size) - break; - } - if (i >= 7) { - /* i and i + 1 are CS0 and CS1, both must be less than 8. */ - goto out; - } - octeon_cf_data.base_region = i; - octeon_cf_data.is16bit = mio_boot_reg_cfg.s.width; - octeon_cf_data.base_region_bias = base_ptr - region_base; - memset(cf_resources, 0, sizeof(cf_resources)); - num_resources = 0; - cf_resources[num_resources].flags = IORESOURCE_MEM; - cf_resources[num_resources].start = region_base; - cf_resources[num_resources].end = region_base + region_size - 1; - num_resources++; - - - if (!(base_ptr & 0xfffful)) { - /* - * Boot loader signals availability of DMA (true_ide - * mode) by setting low order bits of base_ptr to - * zero. - */ - - /* Asume that CS1 immediately follows. */ - mio_boot_reg_cfg.u64 = - cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1)); - region_base = mio_boot_reg_cfg.s.base << 16; - region_size = (mio_boot_reg_cfg.s.size + 1) << 16; - if (!mio_boot_reg_cfg.s.en) - goto out; - - cf_resources[num_resources].flags = IORESOURCE_MEM; - cf_resources[num_resources].start = region_base; - cf_resources[num_resources].end = region_base + region_size - 1; - num_resources++; - - octeon_cf_data.dma_engine = 0; - cf_resources[num_resources].flags = IORESOURCE_IRQ; - cf_resources[num_resources].start = OCTEON_IRQ_BOOTDMA; - cf_resources[num_resources].end = OCTEON_IRQ_BOOTDMA; - num_resources++; - } else { - octeon_cf_data.dma_engine = -1; - } - - pd = platform_device_alloc("pata_octeon_cf", -1); - if (!pd) { - ret = -ENOMEM; - goto out; - } - pd->dev.platform_data = &octeon_cf_data; - - ret = platform_device_add_resources(pd, cf_resources, num_resources); - if (ret) - goto fail; - - ret = platform_device_add(pd); - if (ret) - goto fail; - - return ret; -fail: - platform_device_put(pd); -out: - return ret; -} -device_initcall(octeon_cf_device_init); diff --git a/arch/mips/configs/ar7_defconfig b/arch/mips/configs/ar7_defconfig index dad5b6769d7..35648302f7c 100644 --- a/arch/mips/configs/ar7_defconfig +++ b/arch/mips/configs/ar7_defconfig @@ -125,7 +125,6 @@ CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig index d8694332b34..94b7d57f906 100644 --- a/arch/mips/configs/bcm47xx_defconfig +++ b/arch/mips/configs/bcm47xx_defconfig @@ -111,7 +111,6 @@ CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/bcm63xx_defconfig b/arch/mips/configs/bcm63xx_defconfig new file mode 100644 index 00000000000..ea00c18d1f7 --- /dev/null +++ b/arch/mips/configs/bcm63xx_defconfig @@ -0,0 +1,972 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.30-rc6 +# Sun May 31 20:17:18 2009 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +CONFIG_BCM63XX=y +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_NEC_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_NXP_STB220 is not set +# CONFIG_NXP_STB225 is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_MIKROTIK_RB532 is not set +# CONFIG_WR_PPMC is not set +# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set +# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set + +# +# CPU support +# +CONFIG_BCM63XX_CPU_6348=y +CONFIG_BCM63XX_CPU_6358=y +CONFIG_BOARD_BCM963XX=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K_LIB=y +CONFIG_CEVT_R4K=y +CONFIG_CSRC_R4K_LIB=y +CONFIG_CSRC_R4K=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_EARLY_PRINTK=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_GPIO=y +CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R5500 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_CAVIUM_OCTEON is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_HARDWARE_WATCHPOINTS=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_32KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_KEXEC is not set +# CONFIG_SECCOMP is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SWAP is not set +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +# CONFIG_PCSPKR_PLATFORM is not set +CONFIG_BASE_FULL=y +# CONFIG_FUTEX is not set +# CONFIG_EPOLL is not set +# CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set +# CONFIG_EVENTFD is not set +# CONFIG_SHMEM is not set +# CONFIG_AIO is not set +# CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_PCI_QUIRKS=y +# CONFIG_SLUB_DEBUG is not set +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_BASE_SMALL=0 +# CONFIG_MODULES is not set +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_FREEZER is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCI_LEGACY is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +CONFIG_MMU=y +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_IOCTL=y +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +# CONFIG_YENTA is not set +# CONFIG_PD6729 is not set +# CONFIG_I82092 is not set +CONFIG_PCMCIA_BCM63XX=y +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# Power management options +# +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_PM is not set +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_CHAR is not set +# CONFIG_MTD_BLKDEVS is not set +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +# CONFIG_BLK_DEV is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# Enable only one of the two stacks, unless you know what you are doing +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +CONFIG_COMPAT_NET_DEV_OPS=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +CONFIG_BCM63XX_PHY=y +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +# CONFIG_ATL2 is not set +CONFIG_BCM63XX_ENET=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_NET_PCMCIA is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_DEVKMEM is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_SERIAL_BCM63XX=y +CONFIG_SERIAL_BCM63XX_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +# CONFIG_IPWIRELESS is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# +# CONFIG_GPIO_BT8XX is not set + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB=y +CONFIG_SSB_SPROM=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +# CONFIG_SSB_B43_PCI_BRIDGE is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +# CONFIG_SSB_SILENT is not set +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +# CONFIG_SSB_DRIVER_PCICORE is not set +# CONFIG_SSB_DRIVER_MIPS is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_REGULATOR is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +CONFIG_DISPLAY_SUPPORT=y + +# +# Display hardware drivers +# +# CONFIG_SOUND is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_HCD_SSB is not set +CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y +CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_UWB is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_FILE_LOCKING is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_TRACING_SUPPORT=y + +# +# Tracers +# +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_CMDLINE="console=ttyS0,115200" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index d6d35b2e5fe..13d9eb4736c 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -129,7 +129,6 @@ CONFIG_PAGE_SIZE_4KB=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index eb44b72254a..6c8cca8589b 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -112,7 +112,6 @@ CONFIG_PAGE_SIZE_4KB=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index a279165e3a7..dbdf3bb1a34 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -114,7 +114,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set CONFIG_64BIT_PHYS_ADDR=y -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index 8944d15caf1..fa681447589 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -114,7 +114,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set CONFIG_64BIT_PHYS_ADDR=y -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig index ab17973107f..d73f1de43b5 100644 --- a/arch/mips/configs/db1200_defconfig +++ b/arch/mips/configs/db1200_defconfig @@ -114,7 +114,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set CONFIG_64BIT_PHYS_ADDR=y -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index b65803f1935..ec3e028a5b2 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -116,7 +116,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set CONFIG_64BIT_PHYS_ADDR=y -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig index a190ac07740..7631dae51be 100644 --- a/arch/mips/configs/db1550_defconfig +++ b/arch/mips/configs/db1550_defconfig @@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set CONFIG_64BIT_PHYS_ADDR=y -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig index 4e465e94599..1995d43a2ed 100644 --- a/arch/mips/configs/excite_defconfig +++ b/arch/mips/configs/excite_defconfig @@ -118,7 +118,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set # CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/fulong_defconfig b/arch/mips/configs/fuloong2e_defconfig index 786a9bc9a69..0197f0de6b3 100644 --- a/arch/mips/configs/fulong_defconfig +++ b/arch/mips/configs/fuloong2e_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28-rc6 -# Fri Nov 28 17:53:48 2008 +# Linux kernel version: 2.6.31-rc1 +# Thu Jul 2 22:37:00 2009 # CONFIG_MIPS=y @@ -9,16 +9,17 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set +# CONFIG_AR7 is not set # CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set -CONFIG_LEMOTE_FULONG=y +CONFIG_MACH_LOONGSON=y # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SIM is not set -# CONFIG_MACH_EMMA is not set +# CONFIG_NEC_MARKEINS is not set # CONFIG_MACH_VR41XX is not set # CONFIG_NXP_STB220 is not set # CONFIG_NXP_STB225 is not set @@ -43,6 +44,11 @@ CONFIG_LEMOTE_FULONG=y # CONFIG_MACH_TX49XX is not set # CONFIG_MIKROTIK_RB532 is not set # CONFIG_WR_PPMC is not set +# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set +# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set +# CONFIG_ALCHEMY_GPIO_INDIRECT is not set +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_LEMOTE_FULOONG2E=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set @@ -53,15 +59,16 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K_LIB=y CONFIG_CEVT_R4K=y +CONFIG_CSRC_R4K_LIB=y CONFIG_CSRC_R4K=y CONFIG_DMA_NONCOHERENT=y CONFIG_DMA_NEED_PCI_MAP_STATE=y CONFIG_EARLY_PRINTK=y CONFIG_SYS_HAS_EARLY_PRINTK=y -# CONFIG_HOTPLUG_CPU is not set CONFIG_I8259=y # CONFIG_NO_IOPORT is not set CONFIG_GENERIC_ISA_DMA=y @@ -72,12 +79,11 @@ CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y CONFIG_BOOT_ELF32=y CONFIG_MIPS_L1_CACHE_SHIFT=5 -CONFIG_HAVE_STD_PC_SERIAL_PORT=y # # CPU selection # -CONFIG_CPU_LOONGSON2=y +CONFIG_CPU_LOONGSON2E=y # CONFIG_CPU_MIPS32_R1 is not set # CONFIG_CPU_MIPS32_R2 is not set # CONFIG_CPU_MIPS64_R1 is not set @@ -98,7 +104,9 @@ CONFIG_CPU_LOONGSON2=y # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_LOONGSON2=y +# CONFIG_CPU_CAVIUM_OCTEON is not set +CONFIG_CPU_LOONGSON2=y +CONFIG_SYS_HAS_CPU_LOONGSON2E=y CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y @@ -112,6 +120,7 @@ CONFIG_64BIT=y # CONFIG_PAGE_SIZE_4KB is not set # CONFIG_PAGE_SIZE_8KB is not set CONFIG_PAGE_SIZE_16KB=y +# CONFIG_PAGE_SIZE_32KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y CONFIG_MIPS_MT_DISABLED=y @@ -125,7 +134,6 @@ CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_SYS_SUPPORTS_HIGHMEM=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -135,11 +143,12 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_SPARSEMEM_STATIC=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_RESOURCES_64BIT=y CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y -CONFIG_UNEVICTABLE_LRU=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -161,6 +170,7 @@ CONFIG_SECCOMP=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -168,21 +178,31 @@ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="lm32" +CONFIG_LOCALVERSION="-fuloong2e" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -191,9 +211,11 @@ CONFIG_NAMESPACES=y # CONFIG_IPC_NS is not set CONFIG_USER_NS=y CONFIG_PID_NS=y +# CONFIG_NET_NS is not set # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y @@ -203,29 +225,40 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y # CONFIG_PCSPKR_PLATFORM is not set -# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y + +# +# Performance Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -# CONFIG_MARKERS is not set +CONFIG_TRACEPOINTS=y +CONFIG_MARKERS=y CONFIG_OPROFILE=m CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_SYSCALL_WRAPPERS=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -233,9 +266,7 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_BLK_DEV_IO_TRACE is not set CONFIG_BLK_DEV_BSG=y # CONFIG_BLK_DEV_INTEGRITY is not set CONFIG_BLOCK_COMPAT=y @@ -252,8 +283,7 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y -CONFIG_FREEZER=y +# CONFIG_FREEZER is not set # # Bus options (PCI, PCMCIA, EISA, ISA, TC) @@ -263,6 +293,8 @@ CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set CONFIG_ISA=y CONFIG_MMU=y # CONFIG_PCCARD is not set @@ -285,12 +317,12 @@ CONFIG_BINFMT_ELF32=y # # Power management options # +CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_PM=y # CONFIG_PM_DEBUG is not set -CONFIG_PM_SLEEP=y -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND is not set +# CONFIG_HIBERNATION is not set CONFIG_NET=y # @@ -346,9 +378,11 @@ CONFIG_NETFILTER_NETLINK=m CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NETFILTER_NETLINK_LOG=m # CONFIG_NF_CONNTRACK is not set +# CONFIG_NETFILTER_TPROXY is not set CONFIG_NETFILTER_XTABLES=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m # CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_HL=m CONFIG_NETFILTER_XT_TARGET_MARK=m # CONFIG_NETFILTER_XT_TARGET_NFLOG is not set CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m @@ -361,6 +395,7 @@ CONFIG_NETFILTER_XT_MATCH_DCCP=m # CONFIG_NETFILTER_XT_MATCH_DSCP is not set CONFIG_NETFILTER_XT_MATCH_ESP=m # CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +CONFIG_NETFILTER_XT_MATCH_HL=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -381,6 +416,7 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +# CONFIG_NETFILTER_XT_MATCH_OSF is not set # CONFIG_IP_VS is not set # @@ -419,30 +455,34 @@ CONFIG_IP_NF_ARP_MANGLE=m # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +CONFIG_PHONET=m +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set CONFIG_NET_CLS_ROUTE=y +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -CONFIG_PHONET=m CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set CONFIG_WIRELESS_OLD_REGULATORY=y CONFIG_WIRELESS_EXT=y CONFIG_WIRELESS_EXT_SYSFS=y -# CONFIG_MAC80211 is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -# CONFIG_IEEE80211_CRYPT_CCMP is not set -# CONFIG_IEEE80211_CRYPT_TKIP is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +CONFIG_MAC80211_DEFAULT_PS_VALUE=0 +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set CONFIG_NET_9P=m # CONFIG_NET_9P_DEBUG is not set @@ -466,6 +506,7 @@ CONFIG_MTD=m # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set # CONFIG_MTD_PARTITIONS is not set +# CONFIG_MTD_TESTS is not set # # User Modules And Translation Layers @@ -516,9 +557,7 @@ CONFIG_MTD_CFI_UTIL=m # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=m -CONFIG_MTD_PHYSMAP_START=0x1fc00000 -CONFIG_MTD_PHYSMAP_LEN=0x80000 -CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +# CONFIG_MTD_PHYSMAP_COMPAT is not set # CONFIG_MTD_INTEL_VR_NOR is not set # CONFIG_MTD_PLATRAM is not set @@ -541,6 +580,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -573,6 +617,7 @@ CONFIG_IDE=y # # Please see Documentation/ide/ide.txt for help/info on IDE drives # +CONFIG_IDE_XFER_MODE=y CONFIG_IDE_TIMINGS=y CONFIG_IDE_ATAPI=y # CONFIG_BLK_DEV_IDE_SATA is not set @@ -582,7 +627,6 @@ CONFIG_IDE_GD_ATA=y CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y # CONFIG_BLK_DEV_IDETAPE is not set -CONFIG_BLK_DEV_IDESCSI=y CONFIG_IDE_TASK_IOCTL=y CONFIG_IDE_PROC_FS=y @@ -613,6 +657,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8172 is not set # CONFIG_BLK_DEV_IT8213 is not set # CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set @@ -660,10 +705,6 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y # CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# # CONFIG_SCSI_MULTI_LUN is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -681,6 +722,7 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SRP_ATTRS is not set # CONFIG_SCSI_LOWLEVEL is not set # CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set # CONFIG_MD is not set # CONFIG_FUSION is not set @@ -690,7 +732,11 @@ CONFIG_SCSI_WAIT_SCAN=m # # -# Enable only one of the two stacks, unless you know what you are doing +# You can enable one or both FireWire driver stacks. +# + +# +# See the help texts for more information. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -718,6 +764,9 @@ CONFIG_CICADA_PHY=m # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y @@ -729,7 +778,9 @@ CONFIG_MII=y # CONFIG_NET_VENDOR_SMC is not set # CONFIG_SMC91X is not set # CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set # CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_DNET is not set # CONFIG_NET_TULIP is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set @@ -752,7 +803,6 @@ CONFIG_NET_PCI=y # CONFIG_FORCEDETH is not set # CONFIG_CS89x0 is not set # CONFIG_TC35815 is not set -# CONFIG_EEPRO100 is not set # CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -766,8 +816,10 @@ CONFIG_8139TOO=y # CONFIG_R6040 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set +# CONFIG_SMSC9420 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set +# CONFIG_KS8842 is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set # CONFIG_ATL2 is not set @@ -778,6 +830,7 @@ CONFIG_NETDEV_1000=y # CONFIG_E1000E is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set +# CONFIG_IGBVF is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -788,17 +841,21 @@ CONFIG_NETDEV_1000=y # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set +# CONFIG_CNIC is not set # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set # CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set # CONFIG_JME is not set CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set # CONFIG_ENIC is not set # CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_VXGE is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NIU is not set @@ -808,6 +865,7 @@ CONFIG_NETDEV_10000=y # CONFIG_BNX2X is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set +# CONFIG_BE2NET is not set # CONFIG_TR is not set # @@ -815,7 +873,10 @@ CONFIG_NETDEV_10000=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # # USB Network Adapters @@ -872,7 +933,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=m +CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_SUNKBD is not set # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set @@ -883,7 +944,6 @@ CONFIG_MOUSE_PS2=y CONFIG_MOUSE_PS2_ALPS=y CONFIG_MOUSE_PS2_LOGIPS2PP=y CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_LIFEBOOK=y CONFIG_MOUSE_PS2_TRACKPOINT=y # CONFIG_MOUSE_PS2_ELANTECH is not set # CONFIG_MOUSE_PS2_TOUCHKIT is not set @@ -894,6 +954,7 @@ CONFIG_MOUSE_SERIAL=y # CONFIG_MOUSE_LOGIBM is not set # CONFIG_MOUSE_PC110PAD is not set # CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set @@ -939,10 +1000,13 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_IPMI_HANDLER is not set CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -1006,19 +1070,20 @@ CONFIG_I2C_VIAPRO=m # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_LEGACY is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_PCF8575 is not set # CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -1041,140 +1106,10 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_TMIO is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set # CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -CONFIG_VIDEO_DEV=m -CONFIG_VIDEO_V4L2_COMMON=m -CONFIG_VIDEO_ALLOW_V4L1=y -CONFIG_VIDEO_V4L1_COMPAT=y -# CONFIG_DVB_CORE is not set -CONFIG_VIDEO_MEDIA=m - -# -# Multimedia drivers -# -CONFIG_MEDIA_ATTACH=y -CONFIG_MEDIA_TUNER=m -CONFIG_MEDIA_TUNER_CUSTOMIZE=y -CONFIG_MEDIA_TUNER_SIMPLE=m -CONFIG_MEDIA_TUNER_TDA8290=m -CONFIG_MEDIA_TUNER_TDA827X=m -CONFIG_MEDIA_TUNER_TDA18271=m -CONFIG_MEDIA_TUNER_TDA9887=m -CONFIG_MEDIA_TUNER_TEA5761=m -CONFIG_MEDIA_TUNER_TEA5767=m -CONFIG_MEDIA_TUNER_MT20XX=m -CONFIG_MEDIA_TUNER_MT2060=m -CONFIG_MEDIA_TUNER_MT2266=m -CONFIG_MEDIA_TUNER_MT2131=m -CONFIG_MEDIA_TUNER_QT1010=m -CONFIG_MEDIA_TUNER_XC2028=m -CONFIG_MEDIA_TUNER_XC5000=m -CONFIG_MEDIA_TUNER_MXL5005S=m -CONFIG_MEDIA_TUNER_MXL5007T=m -CONFIG_VIDEO_V4L2=m -CONFIG_VIDEO_V4L1=m -CONFIG_VIDEOBUF_GEN=m -CONFIG_VIDEOBUF_VMALLOC=m -CONFIG_VIDEOBUF_DMA_CONTIG=m -CONFIG_VIDEO_CAPTURE_DRIVERS=y -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -CONFIG_VIDEO_HELPER_CHIPS_AUTO=y -# CONFIG_VIDEO_VIVI is not set -# CONFIG_VIDEO_BT848 is not set -# CONFIG_VIDEO_PMS is not set -# CONFIG_VIDEO_CPIA is not set -# CONFIG_VIDEO_CPIA2 is not set -# CONFIG_VIDEO_SAA5246A is not set -# CONFIG_VIDEO_SAA5249 is not set -# CONFIG_VIDEO_STRADIS is not set -# CONFIG_VIDEO_SAA7134 is not set -# CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_HEXIUM_ORION is not set -# CONFIG_VIDEO_HEXIUM_GEMINI is not set -# CONFIG_VIDEO_CX88 is not set -# CONFIG_VIDEO_IVTV is not set -# CONFIG_VIDEO_CAFE_CCIC is not set -CONFIG_SOC_CAMERA=m -CONFIG_SOC_CAMERA_MT9M001=m -CONFIG_SOC_CAMERA_MT9M111=m -CONFIG_SOC_CAMERA_MT9V022=m -CONFIG_SOC_CAMERA_PLATFORM=m -CONFIG_VIDEO_SH_MOBILE_CEU=m -CONFIG_V4L_USB_DRIVERS=y -CONFIG_USB_VIDEO_CLASS=m -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -CONFIG_USB_GSPCA=m -CONFIG_USB_M5602=m -CONFIG_USB_GSPCA_CONEX=m -CONFIG_USB_GSPCA_ETOMS=m -CONFIG_USB_GSPCA_FINEPIX=m -CONFIG_USB_GSPCA_MARS=m -CONFIG_USB_GSPCA_OV519=m -CONFIG_USB_GSPCA_PAC207=m -CONFIG_USB_GSPCA_PAC7311=m -CONFIG_USB_GSPCA_SONIXB=m -CONFIG_USB_GSPCA_SONIXJ=m -CONFIG_USB_GSPCA_SPCA500=m -CONFIG_USB_GSPCA_SPCA501=m -CONFIG_USB_GSPCA_SPCA505=m -CONFIG_USB_GSPCA_SPCA506=m -CONFIG_USB_GSPCA_SPCA508=m -CONFIG_USB_GSPCA_SPCA561=m -CONFIG_USB_GSPCA_STK014=m -CONFIG_USB_GSPCA_SUNPLUS=m -CONFIG_USB_GSPCA_T613=m -CONFIG_USB_GSPCA_TV8532=m -CONFIG_USB_GSPCA_VC032X=m -CONFIG_USB_GSPCA_ZC3XX=m -# CONFIG_VIDEO_PVRUSB2 is not set -# CONFIG_VIDEO_EM28XX is not set -# CONFIG_VIDEO_USBVISION is not set -CONFIG_VIDEO_USBVIDEO=m -CONFIG_USB_VICAM=m -CONFIG_USB_IBMCAM=m -CONFIG_USB_KONICAWC=m -CONFIG_USB_QUICKCAM_MESSENGER=m -CONFIG_USB_ET61X251=m -# CONFIG_VIDEO_OVCAMCHIP is not set -CONFIG_USB_OV511=m -CONFIG_USB_SE401=m -CONFIG_USB_SN9C102=m -CONFIG_USB_STV680=m -CONFIG_USB_ZC0301=m -CONFIG_USB_PWC=m -# CONFIG_USB_PWC_DEBUG is not set -# CONFIG_USB_ZR364XX is not set -CONFIG_USB_STKWEBCAM=m -CONFIG_USB_S2255=m -CONFIG_RADIO_ADAPTERS=y -# CONFIG_RADIO_CADET is not set -# CONFIG_RADIO_RTRACK is not set -# CONFIG_RADIO_RTRACK2 is not set -# CONFIG_RADIO_AZTECH is not set -# CONFIG_RADIO_GEMTEK is not set -# CONFIG_RADIO_GEMTEK_PCI is not set -# CONFIG_RADIO_MAXIRADIO is not set -# CONFIG_RADIO_MAESTRO is not set -# CONFIG_RADIO_SF16FMI is not set -# CONFIG_RADIO_SF16FMR2 is not set -# CONFIG_RADIO_TERRATEC is not set -# CONFIG_RADIO_TRUST is not set -# CONFIG_RADIO_TYPHOON is not set -# CONFIG_RADIO_ZOLTRIX is not set -# CONFIG_USB_DSBR is not set -CONFIG_USB_SI470X=m -CONFIG_USB_MR800=m -CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -1235,12 +1170,13 @@ CONFIG_FB_RADEON_BACKLIGHT=y # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=m # CONFIG_LCD_ILI9320 is not set # CONFIG_LCD_PLATFORM is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_CORGI is not set +CONFIG_BACKLIGHT_GENERIC=y # # Display device support @@ -1273,12 +1209,19 @@ CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_RTCTIMER is not set # CONFIG_SND_DYNAMIC_MINORS is not set CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set CONFIG_SND_VMASTER=y +CONFIG_SND_RAWMIDI_SEQ=m +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set CONFIG_SND_MPU401_UART=m CONFIG_SND_AC97_CODEC=m CONFIG_SND_DRIVERS=y @@ -1305,6 +1248,7 @@ CONFIG_SND_PCI=y # CONFIG_SND_OXYGEN is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_CS46XX is not set +# CONFIG_SND_CTXFI is not set # CONFIG_SND_DARLA20 is not set # CONFIG_SND_GINA20 is not set # CONFIG_SND_LAYLA20 is not set @@ -1317,6 +1261,8 @@ CONFIG_SND_PCI=y # CONFIG_SND_INDIGO is not set # CONFIG_SND_INDIGOIO is not set # CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set # CONFIG_SND_EMU10K1 is not set # CONFIG_SND_EMU10K1X is not set # CONFIG_SND_ENS1370 is not set @@ -1333,6 +1279,7 @@ CONFIG_SND_PCI=y # CONFIG_SND_INTEL8X0 is not set # CONFIG_SND_INTEL8X0M is not set # CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LX6464ES is not set # CONFIG_SND_MAESTRO3 is not set # CONFIG_SND_MIXART is not set # CONFIG_SND_NM256 is not set @@ -1363,43 +1310,18 @@ CONFIG_HIDRAW=y # # USB Input Devices # -CONFIG_USB_HID=m +# CONFIG_USB_HID is not set CONFIG_HID_PID=y -CONFIG_USB_HIDDEV=y # # USB HID Boot Protocol drivers # -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set +CONFIG_USB_KBD=y +CONFIG_USB_MOUSE=y # # Special HID drivers # -CONFIG_HID_COMPAT=y -CONFIG_HID_A4TECH=m -CONFIG_HID_APPLE=m -CONFIG_HID_BELKIN=m -CONFIG_HID_BRIGHT=m -CONFIG_HID_CHERRY=m -CONFIG_HID_CHICONY=m -CONFIG_HID_CYPRESS=m -CONFIG_HID_DELL=m -CONFIG_HID_EZKEY=m -CONFIG_HID_GYRATION=m -CONFIG_HID_LOGITECH=m -CONFIG_LOGITECH_FF=y -CONFIG_LOGIRUMBLEPAD2_FF=y -CONFIG_HID_MICROSOFT=m -CONFIG_HID_MONTEREY=m -CONFIG_HID_PANTHERLORD=m -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=m -CONFIG_HID_SAMSUNG=m -CONFIG_HID_SONY=m -CONFIG_HID_SUNPLUS=m -# CONFIG_THRUSTMASTER_FF is not set -CONFIG_ZEROPLUS_FF=m CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -1427,9 +1349,11 @@ CONFIG_USB_WUSB_CBAF=m # USB Host Controller Drivers # CONFIG_USB_C67X00_HCD=m +# CONFIG_USB_XHCI_HCD is not set CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_ISP1760_HCD=m CONFIG_USB_OHCI_HCD=y @@ -1451,18 +1375,17 @@ CONFIG_USB_WDM=m CONFIG_USB_TMC=m # -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # -# see USB_STORAGE Help for more information +# also be needed; see USB_STORAGE Help for more info # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set @@ -1498,7 +1421,6 @@ CONFIG_USB_SEVSEG=m # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set # CONFIG_USB_IDMOUSE is not set # CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set @@ -1510,72 +1432,32 @@ CONFIG_USB_SEVSEG=m CONFIG_USB_ISIGHTFW=m CONFIG_USB_VST=m # CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_NOP_USB_XCEIV is not set # CONFIG_UWB is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=m - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -CONFIG_RTC_INTF_DEV_UIE_EMUL=y -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8581 is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -CONFIG_RTC_DRV_CMOS=m -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# +# CONFIG_RTC_CLASS is not set # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set CONFIG_UIO=m CONFIG_UIO_CIF=m # CONFIG_UIO_PDRV is not set # CONFIG_UIO_PDRV_GENIRQ is not set # CONFIG_UIO_SMX is not set +# CONFIG_UIO_AEC is not set # CONFIG_UIO_SERCOS3 is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set -CONFIG_STAGING_EXCLUDE_BUILD=y # # File systems @@ -1584,6 +1466,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set CONFIG_EXT2_FS_XIP=y CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set CONFIG_EXT4_FS=m CONFIG_EXT4DEV_COMPAT=y @@ -1592,7 +1475,9 @@ CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y CONFIG_FS_XIP=y CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set CONFIG_FS_MBCACHE=m CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set @@ -1600,10 +1485,12 @@ CONFIG_REISERFS_FS=m # CONFIG_REISERFS_FS_XATTR is not set # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1611,6 +1498,12 @@ CONFIG_INOTIFY_USER=y CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y CONFIG_FUSE_FS=y +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set # # CD-ROM/DVD Filesystems @@ -1645,10 +1538,7 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1658,6 +1548,7 @@ CONFIG_TMPFS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set CONFIG_OMFS_FS=m @@ -1666,11 +1557,13 @@ CONFIG_OMFS_FS=m # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set CONFIG_NFSD=m CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3=y @@ -1683,7 +1576,6 @@ CONFIG_NFS_ACL_SUPPORT=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m -# CONFIG_SUNRPC_REGISTER_V4 is not set CONFIG_RPCSEC_GSS_KRB5=m # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1775,17 +1667,21 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_FRAME_WARN=2048 # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set +CONFIG_STACKTRACE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SYSCTL_SYSCALL_CHECK=y - -# -# Tracers -# -CONFIG_DYNAMIC_PRINTK_DEBUG=y +CONFIG_NOP_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_CMDLINE="" @@ -1804,13 +1700,21 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_FIPS=y CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_GF128MUL=m # CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_AUTHENC=m # CONFIG_CRYPTO_TEST is not set @@ -1879,6 +1783,7 @@ CONFIG_CRYPTO_SEED=m # Compression # CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_ZLIB is not set CONFIG_CRYPTO_LZO=m # @@ -1886,11 +1791,13 @@ CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG=m # CONFIG_CRYPTO_HW is not set +CONFIG_BINARY_PRINTF=y # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=y CONFIG_CRC16=m # CONFIG_CRC_T10DIF is not set @@ -1906,7 +1813,7 @@ CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=m CONFIG_TEXTSEARCH_BM=m CONFIG_TEXTSEARCH_FSM=m -CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index 11582287641..f14d38ba603 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -130,7 +130,6 @@ CONFIG_IP22_CPU_SCACHE=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index 0208723adf2..1fc73aa7b50 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -105,7 +105,6 @@ CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/ip28_defconfig b/arch/mips/configs/ip28_defconfig index 70a744e9a8c..539dccb0345 100644 --- a/arch/mips/configs/ip28_defconfig +++ b/arch/mips/configs/ip28_defconfig @@ -123,7 +123,6 @@ CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index de4c7a0a96d..d934bdefb39 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -118,7 +118,6 @@ CONFIG_RM7000_CPU_SCACHE=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index bbacc35d804..d22df61833a 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig @@ -119,7 +119,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set # CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/lasat_defconfig b/arch/mips/configs/lasat_defconfig index bc9159fda72..044074db7e5 100644 --- a/arch/mips/configs/lasat_defconfig +++ b/arch/mips/configs/lasat_defconfig @@ -108,7 +108,6 @@ CONFIG_R5000_CPU_SCACHE=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 1ecdd3b65dc..3f01870b4d6 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -139,7 +139,6 @@ CONFIG_SYS_SUPPORTS_SCHED_SMT=y CONFIG_SYS_SUPPORTS_MULTITHREADING=y CONFIG_MIPS_MT_FPAFF=y # CONFIG_MIPS_VPE_LOADER is not set -CONFIG_CPU_HAS_LLSC=y # CONFIG_CPU_HAS_SMARTMIPS is not set CONFIG_CPU_MIPSR2_IRQ_VI=y CONFIG_CPU_MIPSR2_IRQ_EI=y diff --git a/arch/mips/configs/markeins_defconfig b/arch/mips/configs/markeins_defconfig index bad8901f8f3..d001f7e8741 100644 --- a/arch/mips/configs/markeins_defconfig +++ b/arch/mips/configs/markeins_defconfig @@ -112,7 +112,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set # CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig index 2c0a6314e90..7358454deaa 100644 --- a/arch/mips/configs/mipssim_defconfig +++ b/arch/mips/configs/mipssim_defconfig @@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set CONFIG_SYS_SUPPORTS_MULTITHREADING=y # CONFIG_MIPS_VPE_LOADER is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/msp71xx_defconfig b/arch/mips/configs/msp71xx_defconfig index 84d6491b3d4..ecbc030b7b6 100644 --- a/arch/mips/configs/msp71xx_defconfig +++ b/arch/mips/configs/msp71xx_defconfig @@ -129,7 +129,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_VPE_LOADER is not set CONFIG_SYS_SUPPORTS_MULTITHREADING=y # CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index fadb351d249..9477f040796 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -116,7 +116,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set CONFIG_64BIT_PHYS_ADDR=y -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index 9e21e333a2f..be8091ef0a7 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set CONFIG_64BIT_PHYS_ADDR=y -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index af67ed4f71a..e74ba794c78 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -114,7 +114,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set CONFIG_64BIT_PHYS_ADDR=y -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index 7956f56cbf3..1d896fd830d 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set CONFIG_64BIT_PHYS_ADDR=y -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/pnx8335-stb225_defconfig b/arch/mips/configs/pnx8335-stb225_defconfig index 2728caa6c2f..fef4d31c205 100644 --- a/arch/mips/configs/pnx8335-stb225_defconfig +++ b/arch/mips/configs/pnx8335-stb225_defconfig @@ -112,7 +112,6 @@ CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_MIPSR2_IRQ_VI=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig index 723bd5176a3..e10c7116c3c 100644 --- a/arch/mips/configs/pnx8550-jbs_defconfig +++ b/arch/mips/configs/pnx8550-jbs_defconfig @@ -112,7 +112,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set # CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig index b5052fb42e9..5ed3c8dfa0a 100644 --- a/arch/mips/configs/pnx8550-stb810_defconfig +++ b/arch/mips/configs/pnx8550-stb810_defconfig @@ -112,7 +112,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set # CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/rb532_defconfig b/arch/mips/configs/rb532_defconfig index f28dc32974e..f40c3a04739 100644 --- a/arch/mips/configs/rb532_defconfig +++ b/arch/mips/configs/rb532_defconfig @@ -113,7 +113,6 @@ CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/rbtx49xx_defconfig b/arch/mips/configs/rbtx49xx_defconfig index 1efe977497d..c69813b8488 100644 --- a/arch/mips/configs/rbtx49xx_defconfig +++ b/arch/mips/configs/rbtx49xx_defconfig @@ -142,7 +142,6 @@ CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 0f4da0325ea..e53b8d096cf 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -124,7 +124,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set # CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index a9acaa2f9da..7f38c0b956f 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -133,7 +133,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set CONFIG_SB1_PASS_2_WORKAROUNDS=y -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig index fc2c56731b9..06acc7482e4 100644 --- a/arch/mips/configs/wrppmc_defconfig +++ b/arch/mips/configs/wrppmc_defconfig @@ -120,7 +120,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set # CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index ea8249c75b3..69feaf88b51 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set # CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c index 5a557e268f7..e95ff3054ff 100644 --- a/arch/mips/dec/prom/memory.c +++ b/arch/mips/dec/prom/memory.c @@ -18,7 +18,7 @@ #include <asm/sections.h> -volatile unsigned long mem_err = 0; /* So we know an error occurred */ +volatile unsigned long mem_err; /* So we know an error occurred */ /* * Probe memory in 4MB chunks, waiting for an error to tell us we've fallen diff --git a/arch/mips/emma/markeins/setup.c b/arch/mips/emma/markeins/setup.c index 335dc8c1a1b..9b3f51e5f14 100644 --- a/arch/mips/emma/markeins/setup.c +++ b/arch/mips/emma/markeins/setup.c @@ -32,7 +32,7 @@ extern void markeins_led(const char *); -static int bus_frequency = 0; +static int bus_frequency; static void markeins_machine_restart(char *command) { diff --git a/arch/mips/fw/arc/Makefile b/arch/mips/fw/arc/Makefile index 4f349ec1ea2..e0aaad482b0 100644 --- a/arch/mips/fw/arc/Makefile +++ b/arch/mips/fw/arc/Makefile @@ -8,3 +8,5 @@ lib-y += cmdline.o env.o file.o identify.o init.o \ lib-$(CONFIG_ARC_MEMORY) += memory.o lib-$(CONFIG_ARC_CONSOLE) += arc_con.o lib-$(CONFIG_ARC_PROMLIB) += promlib.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/fw/cfe/cfe_api.c b/arch/mips/fw/cfe/cfe_api.c index 717db74f7c6..d06dc5a6b8d 100644 --- a/arch/mips/fw/cfe/cfe_api.c +++ b/arch/mips/fw/cfe/cfe_api.c @@ -45,8 +45,8 @@ int cfe_iocb_dispatch(struct cfe_xiocb *xiocb); * passed in two registers each, and CFE expects one. */ -static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb) = 0; -static u64 cfe_handle = 0; +static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb); +static u64 cfe_handle; int cfe_init(u64 handle, u64 ept) { diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index eb7f01cfd1a..dd75d673447 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -49,7 +49,7 @@ */ static __inline__ void atomic_add(int i, atomic_t * v) { - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { int temp; __asm__ __volatile__( @@ -61,7 +61,7 @@ static __inline__ void atomic_add(int i, atomic_t * v) " .set mips0 \n" : "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter)); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { int temp; __asm__ __volatile__( @@ -94,7 +94,7 @@ static __inline__ void atomic_add(int i, atomic_t * v) */ static __inline__ void atomic_sub(int i, atomic_t * v) { - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { int temp; __asm__ __volatile__( @@ -106,7 +106,7 @@ static __inline__ void atomic_sub(int i, atomic_t * v) " .set mips0 \n" : "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter)); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { int temp; __asm__ __volatile__( @@ -139,7 +139,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v) smp_llsc_mb(); - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { int temp; __asm__ __volatile__( @@ -153,7 +153,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v) : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) : "memory"); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { int temp; __asm__ __volatile__( @@ -191,7 +191,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) smp_llsc_mb(); - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { int temp; __asm__ __volatile__( @@ -205,7 +205,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) : "memory"); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { int temp; __asm__ __volatile__( @@ -251,7 +251,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) smp_llsc_mb(); - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { int temp; __asm__ __volatile__( @@ -269,7 +269,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) : "memory"); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { int temp; __asm__ __volatile__( @@ -428,7 +428,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) */ static __inline__ void atomic64_add(long i, atomic64_t * v) { - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { long temp; __asm__ __volatile__( @@ -440,7 +440,7 @@ static __inline__ void atomic64_add(long i, atomic64_t * v) " .set mips0 \n" : "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter)); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { long temp; __asm__ __volatile__( @@ -473,7 +473,7 @@ static __inline__ void atomic64_add(long i, atomic64_t * v) */ static __inline__ void atomic64_sub(long i, atomic64_t * v) { - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { long temp; __asm__ __volatile__( @@ -485,7 +485,7 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v) " .set mips0 \n" : "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter)); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { long temp; __asm__ __volatile__( @@ -518,7 +518,7 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v) smp_llsc_mb(); - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { long temp; __asm__ __volatile__( @@ -532,7 +532,7 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v) : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) : "memory"); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { long temp; __asm__ __volatile__( @@ -570,7 +570,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) smp_llsc_mb(); - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { long temp; __asm__ __volatile__( @@ -584,7 +584,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) : "memory"); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { long temp; __asm__ __volatile__( @@ -630,7 +630,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) smp_llsc_mb(); - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { long temp; __asm__ __volatile__( @@ -648,7 +648,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) : "memory"); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { long temp; __asm__ __volatile__( diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index b1e9e97a9c7..84a383806b2 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -61,7 +61,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) unsigned short bit = nr & SZLONG_MASK; unsigned long temp; - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { __asm__ __volatile__( " .set mips3 \n" "1: " __LL "%0, %1 # set_bit \n" @@ -72,7 +72,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "=m" (*m) : "ir" (1UL << bit), "m" (*m)); #ifdef CONFIG_CPU_MIPSR2 - } else if (__builtin_constant_p(bit)) { + } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { __asm__ __volatile__( "1: " __LL "%0, %1 # set_bit \n" " " __INS "%0, %4, %2, 1 \n" @@ -84,7 +84,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "=m" (*m) : "ir" (bit), "m" (*m), "r" (~0)); #endif /* CONFIG_CPU_MIPSR2 */ - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { __asm__ __volatile__( " .set mips3 \n" "1: " __LL "%0, %1 # set_bit \n" @@ -126,7 +126,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) unsigned short bit = nr & SZLONG_MASK; unsigned long temp; - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { __asm__ __volatile__( " .set mips3 \n" "1: " __LL "%0, %1 # clear_bit \n" @@ -137,7 +137,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "=m" (*m) : "ir" (~(1UL << bit)), "m" (*m)); #ifdef CONFIG_CPU_MIPSR2 - } else if (__builtin_constant_p(bit)) { + } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { __asm__ __volatile__( "1: " __LL "%0, %1 # clear_bit \n" " " __INS "%0, $0, %2, 1 \n" @@ -149,7 +149,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "=m" (*m) : "ir" (bit), "m" (*m)); #endif /* CONFIG_CPU_MIPSR2 */ - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { __asm__ __volatile__( " .set mips3 \n" "1: " __LL "%0, %1 # clear_bit \n" @@ -202,7 +202,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) { unsigned short bit = nr & SZLONG_MASK; - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -215,7 +215,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) " .set mips0 \n" : "=&r" (temp), "=m" (*m) : "ir" (1UL << bit), "m" (*m)); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -260,7 +260,7 @@ static inline int test_and_set_bit(unsigned long nr, smp_llsc_mb(); - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -275,7 +275,7 @@ static inline int test_and_set_bit(unsigned long nr, : "=&r" (temp), "=m" (*m), "=&r" (res) : "r" (1UL << bit), "m" (*m) : "memory"); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -328,7 +328,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, unsigned short bit = nr & SZLONG_MASK; unsigned long res; - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -343,7 +343,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, : "=&r" (temp), "=m" (*m), "=&r" (res) : "r" (1UL << bit), "m" (*m) : "memory"); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -397,7 +397,7 @@ static inline int test_and_clear_bit(unsigned long nr, smp_llsc_mb(); - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -414,7 +414,7 @@ static inline int test_and_clear_bit(unsigned long nr, : "r" (1UL << bit), "m" (*m) : "memory"); #ifdef CONFIG_CPU_MIPSR2 - } else if (__builtin_constant_p(nr)) { + } else if (kernel_uses_llsc && __builtin_constant_p(nr)) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -431,7 +431,7 @@ static inline int test_and_clear_bit(unsigned long nr, : "ir" (bit), "m" (*m) : "memory"); #endif - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -487,7 +487,7 @@ static inline int test_and_change_bit(unsigned long nr, smp_llsc_mb(); - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -502,7 +502,7 @@ static inline int test_and_change_bit(unsigned long nr, : "=&r" (temp), "=m" (*m), "=&r" (res) : "r" (1UL << bit), "m" (*m) : "memory"); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index 610fe3af7a0..f5dfaf6a160 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h @@ -7,6 +7,7 @@ * Copyright (C) 1995, 1996 Andreas Busse * Copyright (C) 1995, 1996 Stoned Elipot * Copyright (C) 1995, 1996 Paul M. Antoine. + * Copyright (C) 2009 Zhang Le */ #ifndef _ASM_BOOTINFO_H #define _ASM_BOOTINFO_H @@ -57,6 +58,17 @@ #define MACH_MIKROTIK_RB532 0 /* Mikrotik RouterBoard 532 */ #define MACH_MIKROTIK_RB532A 1 /* Mikrotik RouterBoard 532A */ +/* + * Valid machtype for Loongson family + */ +#define MACH_LOONGSON_UNKNOWN 0 +#define MACH_LEMOTE_FL2E 1 +#define MACH_LEMOTE_FL2F 2 +#define MACH_LEMOTE_ML2F7 3 +#define MACH_LEMOTE_YL2F89 4 +#define MACH_DEXXON_GDIUM2F10 5 +#define MACH_LOONGSON_END 6 + #define CL_SIZE COMMAND_LINE_SIZE extern char *system_type; diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h index 4a812c3ceb9..815a438a268 100644 --- a/arch/mips/include/asm/cmpxchg.h +++ b/arch/mips/include/asm/cmpxchg.h @@ -16,7 +16,7 @@ ({ \ __typeof(*(m)) __ret; \ \ - if (cpu_has_llsc && R10000_LLSC_WAR) { \ + if (kernel_uses_llsc && R10000_LLSC_WAR) { \ __asm__ __volatile__( \ " .set push \n" \ " .set noat \n" \ @@ -33,7 +33,7 @@ : "=&r" (__ret), "=R" (*m) \ : "R" (*m), "Jr" (old), "Jr" (new) \ : "memory"); \ - } else if (cpu_has_llsc) { \ + } else if (kernel_uses_llsc) { \ __asm__ __volatile__( \ " .set push \n" \ " .set noat \n" \ diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 8ab1d12ba7f..1f4df647c38 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -80,6 +80,9 @@ #ifndef cpu_has_llsc #define cpu_has_llsc (cpu_data[0].options & MIPS_CPU_LLSC) #endif +#ifndef kernel_uses_llsc +#define kernel_uses_llsc cpu_has_llsc +#endif #ifndef cpu_has_mips16 #define cpu_has_mips16 (cpu_data[0].ases & MIPS_ASE_MIPS16) #endif diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 3bdc0e3d89c..4b96d1a3605 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -113,6 +113,12 @@ #define PRID_IMP_BCM4710 0x4000 #define PRID_IMP_BCM3302 0x9000 +#define PRID_IMP_BCM6338 0x9000 +#define PRID_IMP_BCM6345 0x8000 +#define PRID_IMP_BCM6348 0x9100 +#define PRID_IMP_BCM4350 0xA000 +#define PRID_REV_BCM6358 0x0010 +#define PRID_REV_BCM6368 0x0030 /* * These are the PRID's for when 23:16 == PRID_COMP_CAVIUM @@ -210,6 +216,7 @@ enum cpu_type_enum { */ CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, CPU_ALCHEMY, CPU_PR4450, CPU_BCM3302, CPU_BCM4710, + CPU_BCM6338, CPU_BCM6345, CPU_BCM6348, CPU_BCM6358, /* * MIPS64 class processors diff --git a/arch/mips/include/asm/delay.h b/arch/mips/include/asm/delay.h index d2d8949be6b..e7cd78277c2 100644 --- a/arch/mips/include/asm/delay.h +++ b/arch/mips/include/asm/delay.h @@ -11,6 +11,8 @@ #ifndef _ASM_DELAY_H #define _ASM_DELAY_H +#include <linux/param.h> + extern void __delay(unsigned int loops); extern void __ndelay(unsigned int ns); extern void __udelay(unsigned int us); diff --git a/arch/mips/include/asm/fixmap.h b/arch/mips/include/asm/fixmap.h index 0f5caa1307f..efeddc8db8b 100644 --- a/arch/mips/include/asm/fixmap.h +++ b/arch/mips/include/asm/fixmap.h @@ -67,11 +67,15 @@ enum fixed_addresses { * the start of the fixmap, and leave one page empty * at the top of mem.. */ +#ifdef CONFIG_BCM63XX +#define FIXADDR_TOP ((unsigned long)(long)(int)0xff000000) +#else #if defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_TX49XX) #define FIXADDR_TOP ((unsigned long)(long)(int)(0xff000000 - 0x20000)) #else #define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000) #endif +#endif #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) diff --git a/arch/mips/include/asm/hardirq.h b/arch/mips/include/asm/hardirq.h index 90bf399e6dd..c977a86c2c6 100644 --- a/arch/mips/include/asm/hardirq.h +++ b/arch/mips/include/asm/hardirq.h @@ -10,15 +10,9 @@ #ifndef _ASM_HARDIRQ_H #define _ASM_HARDIRQ_H -#include <linux/threads.h> -#include <linux/irq.h> - -typedef struct { - unsigned int __softirq_pending; -} ____cacheline_aligned irq_cpustat_t; - -#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ - extern void ack_bad_irq(unsigned int irq); +#define ack_bad_irq ack_bad_irq + +#include <asm-generic/hardirq.h> #endif /* _ASM_HARDIRQ_H */ diff --git a/arch/mips/include/asm/lasat/lasat.h b/arch/mips/include/asm/lasat/lasat.h index caeba1e302a..a1ada1c27c1 100644 --- a/arch/mips/include/asm/lasat/lasat.h +++ b/arch/mips/include/asm/lasat/lasat.h @@ -227,6 +227,7 @@ extern void lasat_write_eeprom_info(void); * It is used for the bit-banging rtc and eeprom drivers */ #include <linux/delay.h> +#include <linux/smp.h> /* calculating with the slowest board with 100 MHz clock */ #define LASAT_100_DIVIDER 20 diff --git a/arch/mips/include/asm/local.h b/arch/mips/include/asm/local.h index f96fd59e084..361f4f16c30 100644 --- a/arch/mips/include/asm/local.h +++ b/arch/mips/include/asm/local.h @@ -29,7 +29,7 @@ static __inline__ long local_add_return(long i, local_t * l) { unsigned long result; - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { unsigned long temp; __asm__ __volatile__( @@ -43,7 +43,7 @@ static __inline__ long local_add_return(long i, local_t * l) : "=&r" (result), "=&r" (temp), "=m" (l->a.counter) : "Ir" (i), "m" (l->a.counter) : "memory"); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { unsigned long temp; __asm__ __volatile__( @@ -74,7 +74,7 @@ static __inline__ long local_sub_return(long i, local_t * l) { unsigned long result; - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { unsigned long temp; __asm__ __volatile__( @@ -88,7 +88,7 @@ static __inline__ long local_sub_return(long i, local_t * l) : "=&r" (result), "=&r" (temp), "=m" (l->a.counter) : "Ir" (i), "m" (l->a.counter) : "memory"); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { unsigned long temp; __asm__ __volatile__( diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h index 127d4ed9f07..feea00148b5 100644 --- a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h +++ b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h @@ -578,6 +578,15 @@ static inline int irq_to_gpio(int irq) return alchemy_irq_to_gpio(irq); } +static inline int gpio_request(unsigned gpio, const char *label) +{ + return 0; +} + +static inline void gpio_free(unsigned gpio) +{ +} + #endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h new file mode 100644 index 00000000000..fa3e7e617b0 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h @@ -0,0 +1,12 @@ +#ifndef BCM63XX_BOARD_H_ +#define BCM63XX_BOARD_H_ + +const char *board_get_name(void); + +void board_prom_init(void); + +void board_setup(void); + +int board_register_devices(void); + +#endif /* ! BCM63XX_BOARD_H_ */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_clk.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_clk.h new file mode 100644 index 00000000000..8fcf8df4418 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_clk.h @@ -0,0 +1,11 @@ +#ifndef BCM63XX_CLK_H_ +#define BCM63XX_CLK_H_ + +struct clk { + void (*set)(struct clk *, int); + unsigned int rate; + unsigned int usage; + int id; +}; + +#endif /* ! BCM63XX_CLK_H_ */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h new file mode 100644 index 00000000000..b12c4aca2cc --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h @@ -0,0 +1,538 @@ +#ifndef BCM63XX_CPU_H_ +#define BCM63XX_CPU_H_ + +#include <linux/types.h> +#include <linux/init.h> + +/* + * Macro to fetch bcm63xx cpu id and revision, should be optimized at + * compile time if only one CPU support is enabled (idea stolen from + * arm mach-types) + */ +#define BCM6338_CPU_ID 0x6338 +#define BCM6345_CPU_ID 0x6345 +#define BCM6348_CPU_ID 0x6348 +#define BCM6358_CPU_ID 0x6358 + +void __init bcm63xx_cpu_init(void); +u16 __bcm63xx_get_cpu_id(void); +u16 bcm63xx_get_cpu_rev(void); +unsigned int bcm63xx_get_cpu_freq(void); + +#ifdef CONFIG_BCM63XX_CPU_6338 +# ifdef bcm63xx_get_cpu_id +# undef bcm63xx_get_cpu_id +# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() +# define BCMCPU_RUNTIME_DETECT +# else +# define bcm63xx_get_cpu_id() BCM6338_CPU_ID +# endif +# define BCMCPU_IS_6338() (bcm63xx_get_cpu_id() == BCM6338_CPU_ID) +#else +# define BCMCPU_IS_6338() (0) +#endif + +#ifdef CONFIG_BCM63XX_CPU_6345 +# ifdef bcm63xx_get_cpu_id +# undef bcm63xx_get_cpu_id +# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() +# define BCMCPU_RUNTIME_DETECT +# else +# define bcm63xx_get_cpu_id() BCM6345_CPU_ID +# endif +# define BCMCPU_IS_6345() (bcm63xx_get_cpu_id() == BCM6345_CPU_ID) +#else +# define BCMCPU_IS_6345() (0) +#endif + +#ifdef CONFIG_BCM63XX_CPU_6348 +# ifdef bcm63xx_get_cpu_id +# undef bcm63xx_get_cpu_id +# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() +# define BCMCPU_RUNTIME_DETECT +# else +# define bcm63xx_get_cpu_id() BCM6348_CPU_ID +# endif +# define BCMCPU_IS_6348() (bcm63xx_get_cpu_id() == BCM6348_CPU_ID) +#else +# define BCMCPU_IS_6348() (0) +#endif + +#ifdef CONFIG_BCM63XX_CPU_6358 +# ifdef bcm63xx_get_cpu_id +# undef bcm63xx_get_cpu_id +# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() +# define BCMCPU_RUNTIME_DETECT +# else +# define bcm63xx_get_cpu_id() BCM6358_CPU_ID +# endif +# define BCMCPU_IS_6358() (bcm63xx_get_cpu_id() == BCM6358_CPU_ID) +#else +# define BCMCPU_IS_6358() (0) +#endif + +#ifndef bcm63xx_get_cpu_id +#error "No CPU support configured" +#endif + +/* + * While registers sets are (mostly) the same across 63xx CPU, base + * address of these sets do change. + */ +enum bcm63xx_regs_set { + RSET_DSL_LMEM = 0, + RSET_PERF, + RSET_TIMER, + RSET_WDT, + RSET_UART0, + RSET_GPIO, + RSET_SPI, + RSET_UDC0, + RSET_OHCI0, + RSET_OHCI_PRIV, + RSET_USBH_PRIV, + RSET_MPI, + RSET_PCMCIA, + RSET_DSL, + RSET_ENET0, + RSET_ENET1, + RSET_ENETDMA, + RSET_EHCI0, + RSET_SDRAM, + RSET_MEMC, + RSET_DDR, +}; + +#define RSET_DSL_LMEM_SIZE (64 * 1024 * 4) +#define RSET_DSL_SIZE 4096 +#define RSET_WDT_SIZE 12 +#define RSET_ENET_SIZE 2048 +#define RSET_ENETDMA_SIZE 2048 +#define RSET_UART_SIZE 24 +#define RSET_UDC_SIZE 256 +#define RSET_OHCI_SIZE 256 +#define RSET_EHCI_SIZE 256 +#define RSET_PCMCIA_SIZE 12 + +/* + * 6338 register sets base address + */ +#define BCM_6338_DSL_LMEM_BASE (0xfff00000) +#define BCM_6338_PERF_BASE (0xfffe0000) +#define BCM_6338_BB_BASE (0xfffe0100) +#define BCM_6338_TIMER_BASE (0xfffe0200) +#define BCM_6338_WDT_BASE (0xfffe021c) +#define BCM_6338_UART0_BASE (0xfffe0300) +#define BCM_6338_GPIO_BASE (0xfffe0400) +#define BCM_6338_SPI_BASE (0xfffe0c00) +#define BCM_6338_UDC0_BASE (0xdeadbeef) +#define BCM_6338_USBDMA_BASE (0xfffe2400) +#define BCM_6338_OHCI0_BASE (0xdeadbeef) +#define BCM_6338_OHCI_PRIV_BASE (0xfffe3000) +#define BCM_6338_USBH_PRIV_BASE (0xdeadbeef) +#define BCM_6338_MPI_BASE (0xfffe3160) +#define BCM_6338_PCMCIA_BASE (0xdeadbeef) +#define BCM_6338_SDRAM_REGS_BASE (0xfffe3100) +#define BCM_6338_DSL_BASE (0xfffe1000) +#define BCM_6338_SAR_BASE (0xfffe2000) +#define BCM_6338_UBUS_BASE (0xdeadbeef) +#define BCM_6338_ENET0_BASE (0xfffe2800) +#define BCM_6338_ENET1_BASE (0xdeadbeef) +#define BCM_6338_ENETDMA_BASE (0xfffe2400) +#define BCM_6338_EHCI0_BASE (0xdeadbeef) +#define BCM_6338_SDRAM_BASE (0xfffe3100) +#define BCM_6338_MEMC_BASE (0xdeadbeef) +#define BCM_6338_DDR_BASE (0xdeadbeef) + +/* + * 6345 register sets base address + */ +#define BCM_6345_DSL_LMEM_BASE (0xfff00000) +#define BCM_6345_PERF_BASE (0xfffe0000) +#define BCM_6345_BB_BASE (0xfffe0100) +#define BCM_6345_TIMER_BASE (0xfffe0200) +#define BCM_6345_WDT_BASE (0xfffe021c) +#define BCM_6345_UART0_BASE (0xfffe0300) +#define BCM_6345_GPIO_BASE (0xfffe0400) +#define BCM_6345_SPI_BASE (0xdeadbeef) +#define BCM_6345_UDC0_BASE (0xdeadbeef) +#define BCM_6345_USBDMA_BASE (0xfffe2800) +#define BCM_6345_ENET0_BASE (0xfffe1800) +#define BCM_6345_ENETDMA_BASE (0xfffe2800) +#define BCM_6345_PCMCIA_BASE (0xfffe2028) +#define BCM_6345_MPI_BASE (0xdeadbeef) +#define BCM_6345_OHCI0_BASE (0xfffe2100) +#define BCM_6345_OHCI_PRIV_BASE (0xfffe2200) +#define BCM_6345_USBH_PRIV_BASE (0xdeadbeef) +#define BCM_6345_SDRAM_REGS_BASE (0xfffe2300) +#define BCM_6345_DSL_BASE (0xdeadbeef) +#define BCM_6345_SAR_BASE (0xdeadbeef) +#define BCM_6345_UBUS_BASE (0xdeadbeef) +#define BCM_6345_ENET1_BASE (0xdeadbeef) +#define BCM_6345_EHCI0_BASE (0xdeadbeef) +#define BCM_6345_SDRAM_BASE (0xfffe2300) +#define BCM_6345_MEMC_BASE (0xdeadbeef) +#define BCM_6345_DDR_BASE (0xdeadbeef) + +/* + * 6348 register sets base address + */ +#define BCM_6348_DSL_LMEM_BASE (0xfff00000) +#define BCM_6348_PERF_BASE (0xfffe0000) +#define BCM_6348_TIMER_BASE (0xfffe0200) +#define BCM_6348_WDT_BASE (0xfffe021c) +#define BCM_6348_UART0_BASE (0xfffe0300) +#define BCM_6348_GPIO_BASE (0xfffe0400) +#define BCM_6348_SPI_BASE (0xfffe0c00) +#define BCM_6348_UDC0_BASE (0xfffe1000) +#define BCM_6348_OHCI0_BASE (0xfffe1b00) +#define BCM_6348_OHCI_PRIV_BASE (0xfffe1c00) +#define BCM_6348_USBH_PRIV_BASE (0xdeadbeef) +#define BCM_6348_MPI_BASE (0xfffe2000) +#define BCM_6348_PCMCIA_BASE (0xfffe2054) +#define BCM_6348_SDRAM_REGS_BASE (0xfffe2300) +#define BCM_6348_DSL_BASE (0xfffe3000) +#define BCM_6348_ENET0_BASE (0xfffe6000) +#define BCM_6348_ENET1_BASE (0xfffe6800) +#define BCM_6348_ENETDMA_BASE (0xfffe7000) +#define BCM_6348_EHCI0_BASE (0xdeadbeef) +#define BCM_6348_SDRAM_BASE (0xfffe2300) +#define BCM_6348_MEMC_BASE (0xdeadbeef) +#define BCM_6348_DDR_BASE (0xdeadbeef) + +/* + * 6358 register sets base address + */ +#define BCM_6358_DSL_LMEM_BASE (0xfff00000) +#define BCM_6358_PERF_BASE (0xfffe0000) +#define BCM_6358_TIMER_BASE (0xfffe0040) +#define BCM_6358_WDT_BASE (0xfffe005c) +#define BCM_6358_UART0_BASE (0xfffe0100) +#define BCM_6358_GPIO_BASE (0xfffe0080) +#define BCM_6358_SPI_BASE (0xdeadbeef) +#define BCM_6358_UDC0_BASE (0xfffe0800) +#define BCM_6358_OHCI0_BASE (0xfffe1400) +#define BCM_6358_OHCI_PRIV_BASE (0xdeadbeef) +#define BCM_6358_USBH_PRIV_BASE (0xfffe1500) +#define BCM_6358_MPI_BASE (0xfffe1000) +#define BCM_6358_PCMCIA_BASE (0xfffe1054) +#define BCM_6358_SDRAM_REGS_BASE (0xfffe2300) +#define BCM_6358_DSL_BASE (0xfffe3000) +#define BCM_6358_ENET0_BASE (0xfffe4000) +#define BCM_6358_ENET1_BASE (0xfffe4800) +#define BCM_6358_ENETDMA_BASE (0xfffe5000) +#define BCM_6358_EHCI0_BASE (0xfffe1300) +#define BCM_6358_SDRAM_BASE (0xdeadbeef) +#define BCM_6358_MEMC_BASE (0xfffe1200) +#define BCM_6358_DDR_BASE (0xfffe12a0) + + +extern const unsigned long *bcm63xx_regs_base; + +static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) +{ +#ifdef BCMCPU_RUNTIME_DETECT + return bcm63xx_regs_base[set]; +#else +#ifdef CONFIG_BCM63XX_CPU_6338 + switch (set) { + case RSET_DSL_LMEM: + return BCM_6338_DSL_LMEM_BASE; + case RSET_PERF: + return BCM_6338_PERF_BASE; + case RSET_TIMER: + return BCM_6338_TIMER_BASE; + case RSET_WDT: + return BCM_6338_WDT_BASE; + case RSET_UART0: + return BCM_6338_UART0_BASE; + case RSET_GPIO: + return BCM_6338_GPIO_BASE; + case RSET_SPI: + return BCM_6338_SPI_BASE; + case RSET_UDC0: + return BCM_6338_UDC0_BASE; + case RSET_OHCI0: + return BCM_6338_OHCI0_BASE; + case RSET_OHCI_PRIV: + return BCM_6338_OHCI_PRIV_BASE; + case RSET_USBH_PRIV: + return BCM_6338_USBH_PRIV_BASE; + case RSET_MPI: + return BCM_6338_MPI_BASE; + case RSET_PCMCIA: + return BCM_6338_PCMCIA_BASE; + case RSET_DSL: + return BCM_6338_DSL_BASE; + case RSET_ENET0: + return BCM_6338_ENET0_BASE; + case RSET_ENET1: + return BCM_6338_ENET1_BASE; + case RSET_ENETDMA: + return BCM_6338_ENETDMA_BASE; + case RSET_EHCI0: + return BCM_6338_EHCI0_BASE; + case RSET_SDRAM: + return BCM_6338_SDRAM_BASE; + case RSET_MEMC: + return BCM_6338_MEMC_BASE; + case RSET_DDR: + return BCM_6338_DDR_BASE; + } +#endif +#ifdef CONFIG_BCM63XX_CPU_6345 + switch (set) { + case RSET_DSL_LMEM: + return BCM_6345_DSL_LMEM_BASE; + case RSET_PERF: + return BCM_6345_PERF_BASE; + case RSET_TIMER: + return BCM_6345_TIMER_BASE; + case RSET_WDT: + return BCM_6345_WDT_BASE; + case RSET_UART0: + return BCM_6345_UART0_BASE; + case RSET_GPIO: + return BCM_6345_GPIO_BASE; + case RSET_SPI: + return BCM_6345_SPI_BASE; + case RSET_UDC0: + return BCM_6345_UDC0_BASE; + case RSET_OHCI0: + return BCM_6345_OHCI0_BASE; + case RSET_OHCI_PRIV: + return BCM_6345_OHCI_PRIV_BASE; + case RSET_USBH_PRIV: + return BCM_6345_USBH_PRIV_BASE; + case RSET_MPI: + return BCM_6345_MPI_BASE; + case RSET_PCMCIA: + return BCM_6345_PCMCIA_BASE; + case RSET_DSL: + return BCM_6345_DSL_BASE; + case RSET_ENET0: + return BCM_6345_ENET0_BASE; + case RSET_ENET1: + return BCM_6345_ENET1_BASE; + case RSET_ENETDMA: + return BCM_6345_ENETDMA_BASE; + case RSET_EHCI0: + return BCM_6345_EHCI0_BASE; + case RSET_SDRAM: + return BCM_6345_SDRAM_BASE; + case RSET_MEMC: + return BCM_6345_MEMC_BASE; + case RSET_DDR: + return BCM_6345_DDR_BASE; + } +#endif +#ifdef CONFIG_BCM63XX_CPU_6348 + switch (set) { + case RSET_DSL_LMEM: + return BCM_6348_DSL_LMEM_BASE; + case RSET_PERF: + return BCM_6348_PERF_BASE; + case RSET_TIMER: + return BCM_6348_TIMER_BASE; + case RSET_WDT: + return BCM_6348_WDT_BASE; + case RSET_UART0: + return BCM_6348_UART0_BASE; + case RSET_GPIO: + return BCM_6348_GPIO_BASE; + case RSET_SPI: + return BCM_6348_SPI_BASE; + case RSET_UDC0: + return BCM_6348_UDC0_BASE; + case RSET_OHCI0: + return BCM_6348_OHCI0_BASE; + case RSET_OHCI_PRIV: + return BCM_6348_OHCI_PRIV_BASE; + case RSET_USBH_PRIV: + return BCM_6348_USBH_PRIV_BASE; + case RSET_MPI: + return BCM_6348_MPI_BASE; + case RSET_PCMCIA: + return BCM_6348_PCMCIA_BASE; + case RSET_DSL: + return BCM_6348_DSL_BASE; + case RSET_ENET0: + return BCM_6348_ENET0_BASE; + case RSET_ENET1: + return BCM_6348_ENET1_BASE; + case RSET_ENETDMA: + return BCM_6348_ENETDMA_BASE; + case RSET_EHCI0: + return BCM_6348_EHCI0_BASE; + case RSET_SDRAM: + return BCM_6348_SDRAM_BASE; + case RSET_MEMC: + return BCM_6348_MEMC_BASE; + case RSET_DDR: + return BCM_6348_DDR_BASE; + } +#endif +#ifdef CONFIG_BCM63XX_CPU_6358 + switch (set) { + case RSET_DSL_LMEM: + return BCM_6358_DSL_LMEM_BASE; + case RSET_PERF: + return BCM_6358_PERF_BASE; + case RSET_TIMER: + return BCM_6358_TIMER_BASE; + case RSET_WDT: + return BCM_6358_WDT_BASE; + case RSET_UART0: + return BCM_6358_UART0_BASE; + case RSET_GPIO: + return BCM_6358_GPIO_BASE; + case RSET_SPI: + return BCM_6358_SPI_BASE; + case RSET_UDC0: + return BCM_6358_UDC0_BASE; + case RSET_OHCI0: + return BCM_6358_OHCI0_BASE; + case RSET_OHCI_PRIV: + return BCM_6358_OHCI_PRIV_BASE; + case RSET_USBH_PRIV: + return BCM_6358_USBH_PRIV_BASE; + case RSET_MPI: + return BCM_6358_MPI_BASE; + case RSET_PCMCIA: + return BCM_6358_PCMCIA_BASE; + case RSET_ENET0: + return BCM_6358_ENET0_BASE; + case RSET_ENET1: + return BCM_6358_ENET1_BASE; + case RSET_ENETDMA: + return BCM_6358_ENETDMA_BASE; + case RSET_DSL: + return BCM_6358_DSL_BASE; + case RSET_EHCI0: + return BCM_6358_EHCI0_BASE; + case RSET_SDRAM: + return BCM_6358_SDRAM_BASE; + case RSET_MEMC: + return BCM_6358_MEMC_BASE; + case RSET_DDR: + return BCM_6358_DDR_BASE; + } +#endif +#endif + /* unreached */ + return 0; +} + +/* + * IRQ number changes across CPU too + */ +enum bcm63xx_irq { + IRQ_TIMER = 0, + IRQ_UART0, + IRQ_DSL, + IRQ_ENET0, + IRQ_ENET1, + IRQ_ENET_PHY, + IRQ_OHCI0, + IRQ_EHCI0, + IRQ_PCMCIA0, + IRQ_ENET0_RXDMA, + IRQ_ENET0_TXDMA, + IRQ_ENET1_RXDMA, + IRQ_ENET1_TXDMA, + IRQ_PCI, + IRQ_PCMCIA, +}; + +/* + * 6338 irqs + */ +#define BCM_6338_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) +#define BCM_6338_SPI_IRQ (IRQ_INTERNAL_BASE + 1) +#define BCM_6338_UART0_IRQ (IRQ_INTERNAL_BASE + 2) +#define BCM_6338_DG_IRQ (IRQ_INTERNAL_BASE + 4) +#define BCM_6338_DSL_IRQ (IRQ_INTERNAL_BASE + 5) +#define BCM_6338_ATM_IRQ (IRQ_INTERNAL_BASE + 6) +#define BCM_6338_UDC0_IRQ (IRQ_INTERNAL_BASE + 7) +#define BCM_6338_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) +#define BCM_6338_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9) +#define BCM_6338_SDRAM_IRQ (IRQ_INTERNAL_BASE + 10) +#define BCM_6338_USB_CNTL_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 11) +#define BCM_6338_USB_CNTL_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 12) +#define BCM_6338_USB_BULK_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 13) +#define BCM_6338_USB_BULK_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 14) +#define BCM_6338_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15) +#define BCM_6338_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 16) +#define BCM_6338_SDIO_IRQ (IRQ_INTERNAL_BASE + 17) + +/* + * 6345 irqs + */ +#define BCM_6345_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) +#define BCM_6345_UART0_IRQ (IRQ_INTERNAL_BASE + 2) +#define BCM_6345_DSL_IRQ (IRQ_INTERNAL_BASE + 3) +#define BCM_6345_ATM_IRQ (IRQ_INTERNAL_BASE + 4) +#define BCM_6345_USB_IRQ (IRQ_INTERNAL_BASE + 5) +#define BCM_6345_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) +#define BCM_6345_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12) +#define BCM_6345_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 13 + 1) +#define BCM_6345_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 13 + 2) +#define BCM_6345_EBI_RX_IRQ (IRQ_INTERNAL_BASE + 13 + 5) +#define BCM_6345_EBI_TX_IRQ (IRQ_INTERNAL_BASE + 13 + 6) +#define BCM_6345_RESERVED_RX_IRQ (IRQ_INTERNAL_BASE + 13 + 9) +#define BCM_6345_RESERVED_TX_IRQ (IRQ_INTERNAL_BASE + 13 + 10) +#define BCM_6345_USB_BULK_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 13) +#define BCM_6345_USB_BULK_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 14) +#define BCM_6345_USB_CNTL_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 15) +#define BCM_6345_USB_CNTL_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 16) +#define BCM_6345_USB_ISO_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 17) +#define BCM_6345_USB_ISO_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 18) + +/* + * 6348 irqs + */ +#define BCM_6348_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) +#define BCM_6348_UART0_IRQ (IRQ_INTERNAL_BASE + 2) +#define BCM_6348_DSL_IRQ (IRQ_INTERNAL_BASE + 4) +#define BCM_6348_ENET1_IRQ (IRQ_INTERNAL_BASE + 7) +#define BCM_6348_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) +#define BCM_6348_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9) +#define BCM_6348_OHCI0_IRQ (IRQ_INTERNAL_BASE + 12) +#define BCM_6348_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 20) +#define BCM_6348_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 21) +#define BCM_6348_ENET1_RXDMA_IRQ (IRQ_INTERNAL_BASE + 22) +#define BCM_6348_ENET1_TXDMA_IRQ (IRQ_INTERNAL_BASE + 23) +#define BCM_6348_PCMCIA_IRQ (IRQ_INTERNAL_BASE + 24) +#define BCM_6348_PCI_IRQ (IRQ_INTERNAL_BASE + 24) + +/* + * 6358 irqs + */ +#define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) +#define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2) +#define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5) +#define BCM_6358_ENET1_IRQ (IRQ_INTERNAL_BASE + 6) +#define BCM_6358_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) +#define BCM_6358_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9) +#define BCM_6358_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10) +#define BCM_6358_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15) +#define BCM_6358_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 16) +#define BCM_6358_ENET1_RXDMA_IRQ (IRQ_INTERNAL_BASE + 17) +#define BCM_6358_ENET1_TXDMA_IRQ (IRQ_INTERNAL_BASE + 18) +#define BCM_6358_DSL_IRQ (IRQ_INTERNAL_BASE + 29) +#define BCM_6358_PCI_IRQ (IRQ_INTERNAL_BASE + 31) +#define BCM_6358_PCMCIA_IRQ (IRQ_INTERNAL_BASE + 24) + +extern const int *bcm63xx_irqs; + +static inline int bcm63xx_get_irq_number(enum bcm63xx_irq irq) +{ + return bcm63xx_irqs[irq]; +} + +/* + * return installed memory size + */ +unsigned int bcm63xx_get_memory_size(void); + +#endif /* !BCM63XX_CPU_H_ */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h new file mode 100644 index 00000000000..b1821c866e5 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h @@ -0,0 +1,10 @@ +#ifndef BCM63XX_CS_H +#define BCM63XX_CS_H + +int bcm63xx_set_cs_base(unsigned int cs, u32 base, unsigned int size); +int bcm63xx_set_cs_timing(unsigned int cs, unsigned int wait, + unsigned int setup, unsigned int hold); +int bcm63xx_set_cs_param(unsigned int cs, u32 flags); +int bcm63xx_set_cs_status(unsigned int cs, int enable); + +#endif /* !BCM63XX_CS_H */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h new file mode 100644 index 00000000000..b587d45c304 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h @@ -0,0 +1,13 @@ +#ifndef __BCM63XX_DSP_H +#define __BCM63XX_DSP_H + +struct bcm63xx_dsp_platform_data { + unsigned gpio_rst; + unsigned gpio_int; + unsigned cs; + unsigned ext_irq; +}; + +int __init bcm63xx_dsp_register(const struct bcm63xx_dsp_platform_data *pd); + +#endif /* __BCM63XX_DSP_H */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h new file mode 100644 index 00000000000..d53f611184b --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h @@ -0,0 +1,45 @@ +#ifndef BCM63XX_DEV_ENET_H_ +#define BCM63XX_DEV_ENET_H_ + +#include <linux/if_ether.h> +#include <linux/init.h> + +/* + * on board ethernet platform data + */ +struct bcm63xx_enet_platform_data { + char mac_addr[ETH_ALEN]; + + int has_phy; + + /* if has_phy, then set use_internal_phy */ + int use_internal_phy; + + /* or fill phy info to use an external one */ + int phy_id; + int has_phy_interrupt; + int phy_interrupt; + + /* if has_phy, use autonegociated pause parameters or force + * them */ + int pause_auto; + int pause_rx; + int pause_tx; + + /* if !has_phy, set desired forced speed/duplex */ + int force_speed_100; + int force_duplex_full; + + /* if !has_phy, set callback to perform mii device + * init/remove */ + int (*mii_config)(struct net_device *dev, int probe, + int (*mii_read)(struct net_device *dev, + int phy_id, int reg), + void (*mii_write)(struct net_device *dev, + int phy_id, int reg, int val)); +}; + +int __init bcm63xx_enet_register(int unit, + const struct bcm63xx_enet_platform_data *pd); + +#endif /* ! BCM63XX_DEV_ENET_H_ */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h new file mode 100644 index 00000000000..c549344b70a --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h @@ -0,0 +1,6 @@ +#ifndef BCM63XX_DEV_PCI_H_ +#define BCM63XX_DEV_PCI_H_ + +extern int bcm63xx_pci_enabled; + +#endif /* BCM63XX_DEV_PCI_H_ */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h new file mode 100644 index 00000000000..76a0b7216af --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h @@ -0,0 +1,22 @@ +#ifndef BCM63XX_GPIO_H +#define BCM63XX_GPIO_H + +#include <linux/init.h> + +int __init bcm63xx_gpio_init(void); + +static inline unsigned long bcm63xx_gpio_count(void) +{ + switch (bcm63xx_get_cpu_id()) { + case BCM6358_CPU_ID: + return 40; + case BCM6348_CPU_ID: + default: + return 37; + } +} + +#define GPIO_DIR_OUT 0x0 +#define GPIO_DIR_IN 0x1 + +#endif /* !BCM63XX_GPIO_H */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h new file mode 100644 index 00000000000..91180fac6ed --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h @@ -0,0 +1,93 @@ +#ifndef BCM63XX_IO_H_ +#define BCM63XX_IO_H_ + +#include "bcm63xx_cpu.h" + +/* + * Physical memory map, RAM is mapped at 0x0. + * + * Note that size MUST be a power of two. + */ +#define BCM_PCMCIA_COMMON_BASE_PA (0x20000000) +#define BCM_PCMCIA_COMMON_SIZE (16 * 1024 * 1024) +#define BCM_PCMCIA_COMMON_END_PA (BCM_PCMCIA_COMMON_BASE_PA + \ + BCM_PCMCIA_COMMON_SIZE - 1) + +#define BCM_PCMCIA_ATTR_BASE_PA (0x21000000) +#define BCM_PCMCIA_ATTR_SIZE (16 * 1024 * 1024) +#define BCM_PCMCIA_ATTR_END_PA (BCM_PCMCIA_ATTR_BASE_PA + \ + BCM_PCMCIA_ATTR_SIZE - 1) + +#define BCM_PCMCIA_IO_BASE_PA (0x22000000) +#define BCM_PCMCIA_IO_SIZE (64 * 1024) +#define BCM_PCMCIA_IO_END_PA (BCM_PCMCIA_IO_BASE_PA + \ + BCM_PCMCIA_IO_SIZE - 1) + +#define BCM_PCI_MEM_BASE_PA (0x30000000) +#define BCM_PCI_MEM_SIZE (128 * 1024 * 1024) +#define BCM_PCI_MEM_END_PA (BCM_PCI_MEM_BASE_PA + \ + BCM_PCI_MEM_SIZE - 1) + +#define BCM_PCI_IO_BASE_PA (0x08000000) +#define BCM_PCI_IO_SIZE (64 * 1024) +#define BCM_PCI_IO_END_PA (BCM_PCI_IO_BASE_PA + \ + BCM_PCI_IO_SIZE - 1) +#define BCM_PCI_IO_HALF_PA (BCM_PCI_IO_BASE_PA + \ + (BCM_PCI_IO_SIZE / 2) - 1) + +#define BCM_CB_MEM_BASE_PA (0x38000000) +#define BCM_CB_MEM_SIZE (128 * 1024 * 1024) +#define BCM_CB_MEM_END_PA (BCM_CB_MEM_BASE_PA + \ + BCM_CB_MEM_SIZE - 1) + + +/* + * Internal registers are accessed through KSEG3 + */ +#define BCM_REGS_VA(x) ((void __iomem *)(x)) + +#define bcm_readb(a) (*(volatile unsigned char *) BCM_REGS_VA(a)) +#define bcm_readw(a) (*(volatile unsigned short *) BCM_REGS_VA(a)) +#define bcm_readl(a) (*(volatile unsigned int *) BCM_REGS_VA(a)) +#define bcm_writeb(v, a) (*(volatile unsigned char *) BCM_REGS_VA((a)) = (v)) +#define bcm_writew(v, a) (*(volatile unsigned short *) BCM_REGS_VA((a)) = (v)) +#define bcm_writel(v, a) (*(volatile unsigned int *) BCM_REGS_VA((a)) = (v)) + +/* + * IO helpers to access register set for current CPU + */ +#define bcm_rset_readb(s, o) bcm_readb(bcm63xx_regset_address(s) + (o)) +#define bcm_rset_readw(s, o) bcm_readw(bcm63xx_regset_address(s) + (o)) +#define bcm_rset_readl(s, o) bcm_readl(bcm63xx_regset_address(s) + (o)) +#define bcm_rset_writeb(s, v, o) bcm_writeb((v), \ + bcm63xx_regset_address(s) + (o)) +#define bcm_rset_writew(s, v, o) bcm_writew((v), \ + bcm63xx_regset_address(s) + (o)) +#define bcm_rset_writel(s, v, o) bcm_writel((v), \ + bcm63xx_regset_address(s) + (o)) + +/* + * helpers for frequently used register sets + */ +#define bcm_perf_readl(o) bcm_rset_readl(RSET_PERF, (o)) +#define bcm_perf_writel(v, o) bcm_rset_writel(RSET_PERF, (v), (o)) +#define bcm_timer_readl(o) bcm_rset_readl(RSET_TIMER, (o)) +#define bcm_timer_writel(v, o) bcm_rset_writel(RSET_TIMER, (v), (o)) +#define bcm_wdt_readl(o) bcm_rset_readl(RSET_WDT, (o)) +#define bcm_wdt_writel(v, o) bcm_rset_writel(RSET_WDT, (v), (o)) +#define bcm_gpio_readl(o) bcm_rset_readl(RSET_GPIO, (o)) +#define bcm_gpio_writel(v, o) bcm_rset_writel(RSET_GPIO, (v), (o)) +#define bcm_uart0_readl(o) bcm_rset_readl(RSET_UART0, (o)) +#define bcm_uart0_writel(v, o) bcm_rset_writel(RSET_UART0, (v), (o)) +#define bcm_mpi_readl(o) bcm_rset_readl(RSET_MPI, (o)) +#define bcm_mpi_writel(v, o) bcm_rset_writel(RSET_MPI, (v), (o)) +#define bcm_pcmcia_readl(o) bcm_rset_readl(RSET_PCMCIA, (o)) +#define bcm_pcmcia_writel(v, o) bcm_rset_writel(RSET_PCMCIA, (v), (o)) +#define bcm_sdram_readl(o) bcm_rset_readl(RSET_SDRAM, (o)) +#define bcm_sdram_writel(v, o) bcm_rset_writel(RSET_SDRAM, (v), (o)) +#define bcm_memc_readl(o) bcm_rset_readl(RSET_MEMC, (o)) +#define bcm_memc_writel(v, o) bcm_rset_writel(RSET_MEMC, (v), (o)) +#define bcm_ddr_readl(o) bcm_rset_readl(RSET_DDR, (o)) +#define bcm_ddr_writel(v, o) bcm_rset_writel(RSET_DDR, (v), (o)) + +#endif /* ! BCM63XX_IO_H_ */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h new file mode 100644 index 00000000000..5f95577c821 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h @@ -0,0 +1,15 @@ +#ifndef BCM63XX_IRQ_H_ +#define BCM63XX_IRQ_H_ + +#include <bcm63xx_cpu.h> + +#define IRQ_MIPS_BASE 0 +#define IRQ_INTERNAL_BASE 8 + +#define IRQ_EXT_BASE (IRQ_MIPS_BASE + 3) +#define IRQ_EXT_0 (IRQ_EXT_BASE + 0) +#define IRQ_EXT_1 (IRQ_EXT_BASE + 1) +#define IRQ_EXT_2 (IRQ_EXT_BASE + 2) +#define IRQ_EXT_3 (IRQ_EXT_BASE + 3) + +#endif /* ! BCM63XX_IRQ_H_ */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h new file mode 100644 index 00000000000..ed4ccec87dd --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h @@ -0,0 +1,773 @@ +#ifndef BCM63XX_REGS_H_ +#define BCM63XX_REGS_H_ + +/************************************************************************* + * _REG relative to RSET_PERF + *************************************************************************/ + +/* Chip Identifier / Revision register */ +#define PERF_REV_REG 0x0 +#define REV_CHIPID_SHIFT 16 +#define REV_CHIPID_MASK (0xffff << REV_CHIPID_SHIFT) +#define REV_REVID_SHIFT 0 +#define REV_REVID_MASK (0xffff << REV_REVID_SHIFT) + +/* Clock Control register */ +#define PERF_CKCTL_REG 0x4 + +#define CKCTL_6338_ADSLPHY_EN (1 << 0) +#define CKCTL_6338_MPI_EN (1 << 1) +#define CKCTL_6338_DRAM_EN (1 << 2) +#define CKCTL_6338_ENET_EN (1 << 4) +#define CKCTL_6338_USBS_EN (1 << 4) +#define CKCTL_6338_SAR_EN (1 << 5) +#define CKCTL_6338_SPI_EN (1 << 9) + +#define CKCTL_6338_ALL_SAFE_EN (CKCTL_6338_ADSLPHY_EN | \ + CKCTL_6338_MPI_EN | \ + CKCTL_6338_ENET_EN | \ + CKCTL_6338_SAR_EN | \ + CKCTL_6338_SPI_EN) + +#define CKCTL_6345_CPU_EN (1 << 0) +#define CKCTL_6345_BUS_EN (1 << 1) +#define CKCTL_6345_EBI_EN (1 << 2) +#define CKCTL_6345_UART_EN (1 << 3) +#define CKCTL_6345_ADSLPHY_EN (1 << 4) +#define CKCTL_6345_ENET_EN (1 << 7) +#define CKCTL_6345_USBH_EN (1 << 8) + +#define CKCTL_6345_ALL_SAFE_EN (CKCTL_6345_ENET_EN | \ + CKCTL_6345_USBH_EN | \ + CKCTL_6345_ADSLPHY_EN) + +#define CKCTL_6348_ADSLPHY_EN (1 << 0) +#define CKCTL_6348_MPI_EN (1 << 1) +#define CKCTL_6348_SDRAM_EN (1 << 2) +#define CKCTL_6348_M2M_EN (1 << 3) +#define CKCTL_6348_ENET_EN (1 << 4) +#define CKCTL_6348_SAR_EN (1 << 5) +#define CKCTL_6348_USBS_EN (1 << 6) +#define CKCTL_6348_USBH_EN (1 << 8) +#define CKCTL_6348_SPI_EN (1 << 9) + +#define CKCTL_6348_ALL_SAFE_EN (CKCTL_6348_ADSLPHY_EN | \ + CKCTL_6348_M2M_EN | \ + CKCTL_6348_ENET_EN | \ + CKCTL_6348_SAR_EN | \ + CKCTL_6348_USBS_EN | \ + CKCTL_6348_USBH_EN | \ + CKCTL_6348_SPI_EN) + +#define CKCTL_6358_ENET_EN (1 << 4) +#define CKCTL_6358_ADSLPHY_EN (1 << 5) +#define CKCTL_6358_PCM_EN (1 << 8) +#define CKCTL_6358_SPI_EN (1 << 9) +#define CKCTL_6358_USBS_EN (1 << 10) +#define CKCTL_6358_SAR_EN (1 << 11) +#define CKCTL_6358_EMUSB_EN (1 << 17) +#define CKCTL_6358_ENET0_EN (1 << 18) +#define CKCTL_6358_ENET1_EN (1 << 19) +#define CKCTL_6358_USBSU_EN (1 << 20) +#define CKCTL_6358_EPHY_EN (1 << 21) + +#define CKCTL_6358_ALL_SAFE_EN (CKCTL_6358_ENET_EN | \ + CKCTL_6358_ADSLPHY_EN | \ + CKCTL_6358_PCM_EN | \ + CKCTL_6358_SPI_EN | \ + CKCTL_6358_USBS_EN | \ + CKCTL_6358_SAR_EN | \ + CKCTL_6358_EMUSB_EN | \ + CKCTL_6358_ENET0_EN | \ + CKCTL_6358_ENET1_EN | \ + CKCTL_6358_USBSU_EN | \ + CKCTL_6358_EPHY_EN) + +/* System PLL Control register */ +#define PERF_SYS_PLL_CTL_REG 0x8 +#define SYS_PLL_SOFT_RESET 0x1 + +/* Interrupt Mask register */ +#define PERF_IRQMASK_REG 0xc +#define PERF_IRQSTAT_REG 0x10 + +/* Interrupt Status register */ +#define PERF_IRQSTAT_REG 0x10 + +/* External Interrupt Configuration register */ +#define PERF_EXTIRQ_CFG_REG 0x14 +#define EXTIRQ_CFG_SENSE(x) (1 << (x)) +#define EXTIRQ_CFG_STAT(x) (1 << (x + 5)) +#define EXTIRQ_CFG_CLEAR(x) (1 << (x + 10)) +#define EXTIRQ_CFG_MASK(x) (1 << (x + 15)) +#define EXTIRQ_CFG_BOTHEDGE(x) (1 << (x + 20)) +#define EXTIRQ_CFG_LEVELSENSE(x) (1 << (x + 25)) + +#define EXTIRQ_CFG_CLEAR_ALL (0xf << 10) +#define EXTIRQ_CFG_MASK_ALL (0xf << 15) + +/* Soft Reset register */ +#define PERF_SOFTRESET_REG 0x28 + +#define SOFTRESET_6338_SPI_MASK (1 << 0) +#define SOFTRESET_6338_ENET_MASK (1 << 2) +#define SOFTRESET_6338_USBH_MASK (1 << 3) +#define SOFTRESET_6338_USBS_MASK (1 << 4) +#define SOFTRESET_6338_ADSL_MASK (1 << 5) +#define SOFTRESET_6338_DMAMEM_MASK (1 << 6) +#define SOFTRESET_6338_SAR_MASK (1 << 7) +#define SOFTRESET_6338_ACLC_MASK (1 << 8) +#define SOFTRESET_6338_ADSLMIPSPLL_MASK (1 << 10) +#define SOFTRESET_6338_ALL (SOFTRESET_6338_SPI_MASK | \ + SOFTRESET_6338_ENET_MASK | \ + SOFTRESET_6338_USBH_MASK | \ + SOFTRESET_6338_USBS_MASK | \ + SOFTRESET_6338_ADSL_MASK | \ + SOFTRESET_6338_DMAMEM_MASK | \ + SOFTRESET_6338_SAR_MASK | \ + SOFTRESET_6338_ACLC_MASK | \ + SOFTRESET_6338_ADSLMIPSPLL_MASK) + +#define SOFTRESET_6348_SPI_MASK (1 << 0) +#define SOFTRESET_6348_ENET_MASK (1 << 2) +#define SOFTRESET_6348_USBH_MASK (1 << 3) +#define SOFTRESET_6348_USBS_MASK (1 << 4) +#define SOFTRESET_6348_ADSL_MASK (1 << 5) +#define SOFTRESET_6348_DMAMEM_MASK (1 << 6) +#define SOFTRESET_6348_SAR_MASK (1 << 7) +#define SOFTRESET_6348_ACLC_MASK (1 << 8) +#define SOFTRESET_6348_ADSLMIPSPLL_MASK (1 << 10) + +#define SOFTRESET_6348_ALL (SOFTRESET_6348_SPI_MASK | \ + SOFTRESET_6348_ENET_MASK | \ + SOFTRESET_6348_USBH_MASK | \ + SOFTRESET_6348_USBS_MASK | \ + SOFTRESET_6348_ADSL_MASK | \ + SOFTRESET_6348_DMAMEM_MASK | \ + SOFTRESET_6348_SAR_MASK | \ + SOFTRESET_6348_ACLC_MASK | \ + SOFTRESET_6348_ADSLMIPSPLL_MASK) + +/* MIPS PLL control register */ +#define PERF_MIPSPLLCTL_REG 0x34 +#define MIPSPLLCTL_N1_SHIFT 20 +#define MIPSPLLCTL_N1_MASK (0x7 << MIPSPLLCTL_N1_SHIFT) +#define MIPSPLLCTL_N2_SHIFT 15 +#define MIPSPLLCTL_N2_MASK (0x1f << MIPSPLLCTL_N2_SHIFT) +#define MIPSPLLCTL_M1REF_SHIFT 12 +#define MIPSPLLCTL_M1REF_MASK (0x7 << MIPSPLLCTL_M1REF_SHIFT) +#define MIPSPLLCTL_M2REF_SHIFT 9 +#define MIPSPLLCTL_M2REF_MASK (0x7 << MIPSPLLCTL_M2REF_SHIFT) +#define MIPSPLLCTL_M1CPU_SHIFT 6 +#define MIPSPLLCTL_M1CPU_MASK (0x7 << MIPSPLLCTL_M1CPU_SHIFT) +#define MIPSPLLCTL_M1BUS_SHIFT 3 +#define MIPSPLLCTL_M1BUS_MASK (0x7 << MIPSPLLCTL_M1BUS_SHIFT) +#define MIPSPLLCTL_M2BUS_SHIFT 0 +#define MIPSPLLCTL_M2BUS_MASK (0x7 << MIPSPLLCTL_M2BUS_SHIFT) + +/* ADSL PHY PLL Control register */ +#define PERF_ADSLPLLCTL_REG 0x38 +#define ADSLPLLCTL_N1_SHIFT 20 +#define ADSLPLLCTL_N1_MASK (0x7 << ADSLPLLCTL_N1_SHIFT) +#define ADSLPLLCTL_N2_SHIFT 15 +#define ADSLPLLCTL_N2_MASK (0x1f << ADSLPLLCTL_N2_SHIFT) +#define ADSLPLLCTL_M1REF_SHIFT 12 +#define ADSLPLLCTL_M1REF_MASK (0x7 << ADSLPLLCTL_M1REF_SHIFT) +#define ADSLPLLCTL_M2REF_SHIFT 9 +#define ADSLPLLCTL_M2REF_MASK (0x7 << ADSLPLLCTL_M2REF_SHIFT) +#define ADSLPLLCTL_M1CPU_SHIFT 6 +#define ADSLPLLCTL_M1CPU_MASK (0x7 << ADSLPLLCTL_M1CPU_SHIFT) +#define ADSLPLLCTL_M1BUS_SHIFT 3 +#define ADSLPLLCTL_M1BUS_MASK (0x7 << ADSLPLLCTL_M1BUS_SHIFT) +#define ADSLPLLCTL_M2BUS_SHIFT 0 +#define ADSLPLLCTL_M2BUS_MASK (0x7 << ADSLPLLCTL_M2BUS_SHIFT) + +#define ADSLPLLCTL_VAL(n1, n2, m1ref, m2ref, m1cpu, m1bus, m2bus) \ + (((n1) << ADSLPLLCTL_N1_SHIFT) | \ + ((n2) << ADSLPLLCTL_N2_SHIFT) | \ + ((m1ref) << ADSLPLLCTL_M1REF_SHIFT) | \ + ((m2ref) << ADSLPLLCTL_M2REF_SHIFT) | \ + ((m1cpu) << ADSLPLLCTL_M1CPU_SHIFT) | \ + ((m1bus) << ADSLPLLCTL_M1BUS_SHIFT) | \ + ((m2bus) << ADSLPLLCTL_M2BUS_SHIFT)) + + +/************************************************************************* + * _REG relative to RSET_TIMER + *************************************************************************/ + +#define BCM63XX_TIMER_COUNT 4 +#define TIMER_T0_ID 0 +#define TIMER_T1_ID 1 +#define TIMER_T2_ID 2 +#define TIMER_WDT_ID 3 + +/* Timer irqstat register */ +#define TIMER_IRQSTAT_REG 0 +#define TIMER_IRQSTAT_TIMER_CAUSE(x) (1 << (x)) +#define TIMER_IRQSTAT_TIMER0_CAUSE (1 << 0) +#define TIMER_IRQSTAT_TIMER1_CAUSE (1 << 1) +#define TIMER_IRQSTAT_TIMER2_CAUSE (1 << 2) +#define TIMER_IRQSTAT_WDT_CAUSE (1 << 3) +#define TIMER_IRQSTAT_TIMER_IR_EN(x) (1 << ((x) + 8)) +#define TIMER_IRQSTAT_TIMER0_IR_EN (1 << 8) +#define TIMER_IRQSTAT_TIMER1_IR_EN (1 << 9) +#define TIMER_IRQSTAT_TIMER2_IR_EN (1 << 10) + +/* Timer control register */ +#define TIMER_CTLx_REG(x) (0x4 + (x * 4)) +#define TIMER_CTL0_REG 0x4 +#define TIMER_CTL1_REG 0x8 +#define TIMER_CTL2_REG 0xC +#define TIMER_CTL_COUNTDOWN_MASK (0x3fffffff) +#define TIMER_CTL_MONOTONIC_MASK (1 << 30) +#define TIMER_CTL_ENABLE_MASK (1 << 31) + + +/************************************************************************* + * _REG relative to RSET_WDT + *************************************************************************/ + +/* Watchdog default count register */ +#define WDT_DEFVAL_REG 0x0 + +/* Watchdog control register */ +#define WDT_CTL_REG 0x4 + +/* Watchdog control register constants */ +#define WDT_START_1 (0xff00) +#define WDT_START_2 (0x00ff) +#define WDT_STOP_1 (0xee00) +#define WDT_STOP_2 (0x00ee) + +/* Watchdog reset length register */ +#define WDT_RSTLEN_REG 0x8 + + +/************************************************************************* + * _REG relative to RSET_UARTx + *************************************************************************/ + +/* UART Control Register */ +#define UART_CTL_REG 0x0 +#define UART_CTL_RXTMOUTCNT_SHIFT 0 +#define UART_CTL_RXTMOUTCNT_MASK (0x1f << UART_CTL_RXTMOUTCNT_SHIFT) +#define UART_CTL_RSTTXDN_SHIFT 5 +#define UART_CTL_RSTTXDN_MASK (1 << UART_CTL_RSTTXDN_SHIFT) +#define UART_CTL_RSTRXFIFO_SHIFT 6 +#define UART_CTL_RSTRXFIFO_MASK (1 << UART_CTL_RSTRXFIFO_SHIFT) +#define UART_CTL_RSTTXFIFO_SHIFT 7 +#define UART_CTL_RSTTXFIFO_MASK (1 << UART_CTL_RSTTXFIFO_SHIFT) +#define UART_CTL_STOPBITS_SHIFT 8 +#define UART_CTL_STOPBITS_MASK (0xf << UART_CTL_STOPBITS_SHIFT) +#define UART_CTL_STOPBITS_1 (0x7 << UART_CTL_STOPBITS_SHIFT) +#define UART_CTL_STOPBITS_2 (0xf << UART_CTL_STOPBITS_SHIFT) +#define UART_CTL_BITSPERSYM_SHIFT 12 +#define UART_CTL_BITSPERSYM_MASK (0x3 << UART_CTL_BITSPERSYM_SHIFT) +#define UART_CTL_XMITBRK_SHIFT 14 +#define UART_CTL_XMITBRK_MASK (1 << UART_CTL_XMITBRK_SHIFT) +#define UART_CTL_RSVD_SHIFT 15 +#define UART_CTL_RSVD_MASK (1 << UART_CTL_RSVD_SHIFT) +#define UART_CTL_RXPAREVEN_SHIFT 16 +#define UART_CTL_RXPAREVEN_MASK (1 << UART_CTL_RXPAREVEN_SHIFT) +#define UART_CTL_RXPAREN_SHIFT 17 +#define UART_CTL_RXPAREN_MASK (1 << UART_CTL_RXPAREN_SHIFT) +#define UART_CTL_TXPAREVEN_SHIFT 18 +#define UART_CTL_TXPAREVEN_MASK (1 << UART_CTL_TXPAREVEN_SHIFT) +#define UART_CTL_TXPAREN_SHIFT 18 +#define UART_CTL_TXPAREN_MASK (1 << UART_CTL_TXPAREN_SHIFT) +#define UART_CTL_LOOPBACK_SHIFT 20 +#define UART_CTL_LOOPBACK_MASK (1 << UART_CTL_LOOPBACK_SHIFT) +#define UART_CTL_RXEN_SHIFT 21 +#define UART_CTL_RXEN_MASK (1 << UART_CTL_RXEN_SHIFT) +#define UART_CTL_TXEN_SHIFT 22 +#define UART_CTL_TXEN_MASK (1 << UART_CTL_TXEN_SHIFT) +#define UART_CTL_BRGEN_SHIFT 23 +#define UART_CTL_BRGEN_MASK (1 << UART_CTL_BRGEN_SHIFT) + +/* UART Baudword register */ +#define UART_BAUD_REG 0x4 + +/* UART Misc Control register */ +#define UART_MCTL_REG 0x8 +#define UART_MCTL_DTR_SHIFT 0 +#define UART_MCTL_DTR_MASK (1 << UART_MCTL_DTR_SHIFT) +#define UART_MCTL_RTS_SHIFT 1 +#define UART_MCTL_RTS_MASK (1 << UART_MCTL_RTS_SHIFT) +#define UART_MCTL_RXFIFOTHRESH_SHIFT 8 +#define UART_MCTL_RXFIFOTHRESH_MASK (0xf << UART_MCTL_RXFIFOTHRESH_SHIFT) +#define UART_MCTL_TXFIFOTHRESH_SHIFT 12 +#define UART_MCTL_TXFIFOTHRESH_MASK (0xf << UART_MCTL_TXFIFOTHRESH_SHIFT) +#define UART_MCTL_RXFIFOFILL_SHIFT 16 +#define UART_MCTL_RXFIFOFILL_MASK (0x1f << UART_MCTL_RXFIFOFILL_SHIFT) +#define UART_MCTL_TXFIFOFILL_SHIFT 24 +#define UART_MCTL_TXFIFOFILL_MASK (0x1f << UART_MCTL_TXFIFOFILL_SHIFT) + +/* UART External Input Configuration register */ +#define UART_EXTINP_REG 0xc +#define UART_EXTINP_RI_SHIFT 0 +#define UART_EXTINP_RI_MASK (1 << UART_EXTINP_RI_SHIFT) +#define UART_EXTINP_CTS_SHIFT 1 +#define UART_EXTINP_CTS_MASK (1 << UART_EXTINP_CTS_SHIFT) +#define UART_EXTINP_DCD_SHIFT 2 +#define UART_EXTINP_DCD_MASK (1 << UART_EXTINP_DCD_SHIFT) +#define UART_EXTINP_DSR_SHIFT 3 +#define UART_EXTINP_DSR_MASK (1 << UART_EXTINP_DSR_SHIFT) +#define UART_EXTINP_IRSTAT(x) (1 << (x + 4)) +#define UART_EXTINP_IRMASK(x) (1 << (x + 8)) +#define UART_EXTINP_IR_RI 0 +#define UART_EXTINP_IR_CTS 1 +#define UART_EXTINP_IR_DCD 2 +#define UART_EXTINP_IR_DSR 3 +#define UART_EXTINP_RI_NOSENSE_SHIFT 16 +#define UART_EXTINP_RI_NOSENSE_MASK (1 << UART_EXTINP_RI_NOSENSE_SHIFT) +#define UART_EXTINP_CTS_NOSENSE_SHIFT 17 +#define UART_EXTINP_CTS_NOSENSE_MASK (1 << UART_EXTINP_CTS_NOSENSE_SHIFT) +#define UART_EXTINP_DCD_NOSENSE_SHIFT 18 +#define UART_EXTINP_DCD_NOSENSE_MASK (1 << UART_EXTINP_DCD_NOSENSE_SHIFT) +#define UART_EXTINP_DSR_NOSENSE_SHIFT 19 +#define UART_EXTINP_DSR_NOSENSE_MASK (1 << UART_EXTINP_DSR_NOSENSE_SHIFT) + +/* UART Interrupt register */ +#define UART_IR_REG 0x10 +#define UART_IR_MASK(x) (1 << (x + 16)) +#define UART_IR_STAT(x) (1 << (x)) +#define UART_IR_EXTIP 0 +#define UART_IR_TXUNDER 1 +#define UART_IR_TXOVER 2 +#define UART_IR_TXTRESH 3 +#define UART_IR_TXRDLATCH 4 +#define UART_IR_TXEMPTY 5 +#define UART_IR_RXUNDER 6 +#define UART_IR_RXOVER 7 +#define UART_IR_RXTIMEOUT 8 +#define UART_IR_RXFULL 9 +#define UART_IR_RXTHRESH 10 +#define UART_IR_RXNOTEMPTY 11 +#define UART_IR_RXFRAMEERR 12 +#define UART_IR_RXPARERR 13 +#define UART_IR_RXBRK 14 +#define UART_IR_TXDONE 15 + +/* UART Fifo register */ +#define UART_FIFO_REG 0x14 +#define UART_FIFO_VALID_SHIFT 0 +#define UART_FIFO_VALID_MASK 0xff +#define UART_FIFO_FRAMEERR_SHIFT 8 +#define UART_FIFO_FRAMEERR_MASK (1 << UART_FIFO_FRAMEERR_SHIFT) +#define UART_FIFO_PARERR_SHIFT 9 +#define UART_FIFO_PARERR_MASK (1 << UART_FIFO_PARERR_SHIFT) +#define UART_FIFO_BRKDET_SHIFT 10 +#define UART_FIFO_BRKDET_MASK (1 << UART_FIFO_BRKDET_SHIFT) +#define UART_FIFO_ANYERR_MASK (UART_FIFO_FRAMEERR_MASK | \ + UART_FIFO_PARERR_MASK | \ + UART_FIFO_BRKDET_MASK) + + +/************************************************************************* + * _REG relative to RSET_GPIO + *************************************************************************/ + +/* GPIO registers */ +#define GPIO_CTL_HI_REG 0x0 +#define GPIO_CTL_LO_REG 0x4 +#define GPIO_DATA_HI_REG 0x8 +#define GPIO_DATA_LO_REG 0xC + +/* GPIO mux registers and constants */ +#define GPIO_MODE_REG 0x18 + +#define GPIO_MODE_6348_G4_DIAG 0x00090000 +#define GPIO_MODE_6348_G4_UTOPIA 0x00080000 +#define GPIO_MODE_6348_G4_LEGACY_LED 0x00030000 +#define GPIO_MODE_6348_G4_MII_SNOOP 0x00020000 +#define GPIO_MODE_6348_G4_EXT_EPHY 0x00010000 +#define GPIO_MODE_6348_G3_DIAG 0x00009000 +#define GPIO_MODE_6348_G3_UTOPIA 0x00008000 +#define GPIO_MODE_6348_G3_EXT_MII 0x00007000 +#define GPIO_MODE_6348_G2_DIAG 0x00000900 +#define GPIO_MODE_6348_G2_PCI 0x00000500 +#define GPIO_MODE_6348_G1_DIAG 0x00000090 +#define GPIO_MODE_6348_G1_UTOPIA 0x00000080 +#define GPIO_MODE_6348_G1_SPI_UART 0x00000060 +#define GPIO_MODE_6348_G1_SPI_MASTER 0x00000060 +#define GPIO_MODE_6348_G1_MII_PCCARD 0x00000040 +#define GPIO_MODE_6348_G1_MII_SNOOP 0x00000020 +#define GPIO_MODE_6348_G1_EXT_EPHY 0x00000010 +#define GPIO_MODE_6348_G0_DIAG 0x00000009 +#define GPIO_MODE_6348_G0_EXT_MII 0x00000007 + +#define GPIO_MODE_6358_EXTRACS (1 << 5) +#define GPIO_MODE_6358_UART1 (1 << 6) +#define GPIO_MODE_6358_EXTRA_SPI_SS (1 << 7) +#define GPIO_MODE_6358_SERIAL_LED (1 << 10) +#define GPIO_MODE_6358_UTOPIA (1 << 12) + + +/************************************************************************* + * _REG relative to RSET_ENET + *************************************************************************/ + +/* Receiver Configuration register */ +#define ENET_RXCFG_REG 0x0 +#define ENET_RXCFG_ALLMCAST_SHIFT 1 +#define ENET_RXCFG_ALLMCAST_MASK (1 << ENET_RXCFG_ALLMCAST_SHIFT) +#define ENET_RXCFG_PROMISC_SHIFT 3 +#define ENET_RXCFG_PROMISC_MASK (1 << ENET_RXCFG_PROMISC_SHIFT) +#define ENET_RXCFG_LOOPBACK_SHIFT 4 +#define ENET_RXCFG_LOOPBACK_MASK (1 << ENET_RXCFG_LOOPBACK_SHIFT) +#define ENET_RXCFG_ENFLOW_SHIFT 5 +#define ENET_RXCFG_ENFLOW_MASK (1 << ENET_RXCFG_ENFLOW_SHIFT) + +/* Receive Maximum Length register */ +#define ENET_RXMAXLEN_REG 0x4 +#define ENET_RXMAXLEN_SHIFT 0 +#define ENET_RXMAXLEN_MASK (0x7ff << ENET_RXMAXLEN_SHIFT) + +/* Transmit Maximum Length register */ +#define ENET_TXMAXLEN_REG 0x8 +#define ENET_TXMAXLEN_SHIFT 0 +#define ENET_TXMAXLEN_MASK (0x7ff << ENET_TXMAXLEN_SHIFT) + +/* MII Status/Control register */ +#define ENET_MIISC_REG 0x10 +#define ENET_MIISC_MDCFREQDIV_SHIFT 0 +#define ENET_MIISC_MDCFREQDIV_MASK (0x7f << ENET_MIISC_MDCFREQDIV_SHIFT) +#define ENET_MIISC_PREAMBLEEN_SHIFT 7 +#define ENET_MIISC_PREAMBLEEN_MASK (1 << ENET_MIISC_PREAMBLEEN_SHIFT) + +/* MII Data register */ +#define ENET_MIIDATA_REG 0x14 +#define ENET_MIIDATA_DATA_SHIFT 0 +#define ENET_MIIDATA_DATA_MASK (0xffff << ENET_MIIDATA_DATA_SHIFT) +#define ENET_MIIDATA_TA_SHIFT 16 +#define ENET_MIIDATA_TA_MASK (0x3 << ENET_MIIDATA_TA_SHIFT) +#define ENET_MIIDATA_REG_SHIFT 18 +#define ENET_MIIDATA_REG_MASK (0x1f << ENET_MIIDATA_REG_SHIFT) +#define ENET_MIIDATA_PHYID_SHIFT 23 +#define ENET_MIIDATA_PHYID_MASK (0x1f << ENET_MIIDATA_PHYID_SHIFT) +#define ENET_MIIDATA_OP_READ_MASK (0x6 << 28) +#define ENET_MIIDATA_OP_WRITE_MASK (0x5 << 28) + +/* Ethernet Interrupt Mask register */ +#define ENET_IRMASK_REG 0x18 + +/* Ethernet Interrupt register */ +#define ENET_IR_REG 0x1c +#define ENET_IR_MII (1 << 0) +#define ENET_IR_MIB (1 << 1) +#define ENET_IR_FLOWC (1 << 2) + +/* Ethernet Control register */ +#define ENET_CTL_REG 0x2c +#define ENET_CTL_ENABLE_SHIFT 0 +#define ENET_CTL_ENABLE_MASK (1 << ENET_CTL_ENABLE_SHIFT) +#define ENET_CTL_DISABLE_SHIFT 1 +#define ENET_CTL_DISABLE_MASK (1 << ENET_CTL_DISABLE_SHIFT) +#define ENET_CTL_SRESET_SHIFT 2 +#define ENET_CTL_SRESET_MASK (1 << ENET_CTL_SRESET_SHIFT) +#define ENET_CTL_EPHYSEL_SHIFT 3 +#define ENET_CTL_EPHYSEL_MASK (1 << ENET_CTL_EPHYSEL_SHIFT) + +/* Transmit Control register */ +#define ENET_TXCTL_REG 0x30 +#define ENET_TXCTL_FD_SHIFT 0 +#define ENET_TXCTL_FD_MASK (1 << ENET_TXCTL_FD_SHIFT) + +/* Transmit Watermask register */ +#define ENET_TXWMARK_REG 0x34 +#define ENET_TXWMARK_WM_SHIFT 0 +#define ENET_TXWMARK_WM_MASK (0x3f << ENET_TXWMARK_WM_SHIFT) + +/* MIB Control register */ +#define ENET_MIBCTL_REG 0x38 +#define ENET_MIBCTL_RDCLEAR_SHIFT 0 +#define ENET_MIBCTL_RDCLEAR_MASK (1 << ENET_MIBCTL_RDCLEAR_SHIFT) + +/* Perfect Match Data Low register */ +#define ENET_PML_REG(x) (0x58 + (x) * 8) +#define ENET_PMH_REG(x) (0x5c + (x) * 8) +#define ENET_PMH_DATAVALID_SHIFT 16 +#define ENET_PMH_DATAVALID_MASK (1 << ENET_PMH_DATAVALID_SHIFT) + +/* MIB register */ +#define ENET_MIB_REG(x) (0x200 + (x) * 4) +#define ENET_MIB_REG_COUNT 55 + + +/************************************************************************* + * _REG relative to RSET_ENETDMA + *************************************************************************/ + +/* Controller Configuration Register */ +#define ENETDMA_CFG_REG (0x0) +#define ENETDMA_CFG_EN_SHIFT 0 +#define ENETDMA_CFG_EN_MASK (1 << ENETDMA_CFG_EN_SHIFT) +#define ENETDMA_CFG_FLOWCH_MASK(x) (1 << ((x >> 1) + 1)) + +/* Flow Control Descriptor Low Threshold register */ +#define ENETDMA_FLOWCL_REG(x) (0x4 + (x) * 6) + +/* Flow Control Descriptor High Threshold register */ +#define ENETDMA_FLOWCH_REG(x) (0x8 + (x) * 6) + +/* Flow Control Descriptor Buffer Alloca Threshold register */ +#define ENETDMA_BUFALLOC_REG(x) (0xc + (x) * 6) +#define ENETDMA_BUFALLOC_FORCE_SHIFT 31 +#define ENETDMA_BUFALLOC_FORCE_MASK (1 << ENETDMA_BUFALLOC_FORCE_SHIFT) + +/* Channel Configuration register */ +#define ENETDMA_CHANCFG_REG(x) (0x100 + (x) * 0x10) +#define ENETDMA_CHANCFG_EN_SHIFT 0 +#define ENETDMA_CHANCFG_EN_MASK (1 << ENETDMA_CHANCFG_EN_SHIFT) +#define ENETDMA_CHANCFG_PKTHALT_SHIFT 1 +#define ENETDMA_CHANCFG_PKTHALT_MASK (1 << ENETDMA_CHANCFG_PKTHALT_SHIFT) + +/* Interrupt Control/Status register */ +#define ENETDMA_IR_REG(x) (0x104 + (x) * 0x10) +#define ENETDMA_IR_BUFDONE_MASK (1 << 0) +#define ENETDMA_IR_PKTDONE_MASK (1 << 1) +#define ENETDMA_IR_NOTOWNER_MASK (1 << 2) + +/* Interrupt Mask register */ +#define ENETDMA_IRMASK_REG(x) (0x108 + (x) * 0x10) + +/* Maximum Burst Length */ +#define ENETDMA_MAXBURST_REG(x) (0x10C + (x) * 0x10) + +/* Ring Start Address register */ +#define ENETDMA_RSTART_REG(x) (0x200 + (x) * 0x10) + +/* State Ram Word 2 */ +#define ENETDMA_SRAM2_REG(x) (0x204 + (x) * 0x10) + +/* State Ram Word 3 */ +#define ENETDMA_SRAM3_REG(x) (0x208 + (x) * 0x10) + +/* State Ram Word 4 */ +#define ENETDMA_SRAM4_REG(x) (0x20c + (x) * 0x10) + + +/************************************************************************* + * _REG relative to RSET_OHCI_PRIV + *************************************************************************/ + +#define OHCI_PRIV_REG 0x0 +#define OHCI_PRIV_PORT1_HOST_SHIFT 0 +#define OHCI_PRIV_PORT1_HOST_MASK (1 << OHCI_PRIV_PORT1_HOST_SHIFT) +#define OHCI_PRIV_REG_SWAP_SHIFT 3 +#define OHCI_PRIV_REG_SWAP_MASK (1 << OHCI_PRIV_REG_SWAP_SHIFT) + + +/************************************************************************* + * _REG relative to RSET_USBH_PRIV + *************************************************************************/ + +#define USBH_PRIV_SWAP_REG 0x0 +#define USBH_PRIV_SWAP_EHCI_ENDN_SHIFT 4 +#define USBH_PRIV_SWAP_EHCI_ENDN_MASK (1 << USBH_PRIV_SWAP_EHCI_ENDN_SHIFT) +#define USBH_PRIV_SWAP_EHCI_DATA_SHIFT 3 +#define USBH_PRIV_SWAP_EHCI_DATA_MASK (1 << USBH_PRIV_SWAP_EHCI_DATA_SHIFT) +#define USBH_PRIV_SWAP_OHCI_ENDN_SHIFT 1 +#define USBH_PRIV_SWAP_OHCI_ENDN_MASK (1 << USBH_PRIV_SWAP_OHCI_ENDN_SHIFT) +#define USBH_PRIV_SWAP_OHCI_DATA_SHIFT 0 +#define USBH_PRIV_SWAP_OHCI_DATA_MASK (1 << USBH_PRIV_SWAP_OHCI_DATA_SHIFT) + +#define USBH_PRIV_TEST_REG 0x24 + + +/************************************************************************* + * _REG relative to RSET_MPI + *************************************************************************/ + +/* well known (hard wired) chip select */ +#define MPI_CS_PCMCIA_COMMON 4 +#define MPI_CS_PCMCIA_ATTR 5 +#define MPI_CS_PCMCIA_IO 6 + +/* Chip select base register */ +#define MPI_CSBASE_REG(x) (0x0 + (x) * 8) +#define MPI_CSBASE_BASE_SHIFT 13 +#define MPI_CSBASE_BASE_MASK (0x1ffff << MPI_CSBASE_BASE_SHIFT) +#define MPI_CSBASE_SIZE_SHIFT 0 +#define MPI_CSBASE_SIZE_MASK (0xf << MPI_CSBASE_SIZE_SHIFT) + +#define MPI_CSBASE_SIZE_8K 0 +#define MPI_CSBASE_SIZE_16K 1 +#define MPI_CSBASE_SIZE_32K 2 +#define MPI_CSBASE_SIZE_64K 3 +#define MPI_CSBASE_SIZE_128K 4 +#define MPI_CSBASE_SIZE_256K 5 +#define MPI_CSBASE_SIZE_512K 6 +#define MPI_CSBASE_SIZE_1M 7 +#define MPI_CSBASE_SIZE_2M 8 +#define MPI_CSBASE_SIZE_4M 9 +#define MPI_CSBASE_SIZE_8M 10 +#define MPI_CSBASE_SIZE_16M 11 +#define MPI_CSBASE_SIZE_32M 12 +#define MPI_CSBASE_SIZE_64M 13 +#define MPI_CSBASE_SIZE_128M 14 +#define MPI_CSBASE_SIZE_256M 15 + +/* Chip select control register */ +#define MPI_CSCTL_REG(x) (0x4 + (x) * 8) +#define MPI_CSCTL_ENABLE_MASK (1 << 0) +#define MPI_CSCTL_WAIT_SHIFT 1 +#define MPI_CSCTL_WAIT_MASK (0x7 << MPI_CSCTL_WAIT_SHIFT) +#define MPI_CSCTL_DATA16_MASK (1 << 4) +#define MPI_CSCTL_SYNCMODE_MASK (1 << 7) +#define MPI_CSCTL_TSIZE_MASK (1 << 8) +#define MPI_CSCTL_ENDIANSWAP_MASK (1 << 10) +#define MPI_CSCTL_SETUP_SHIFT 16 +#define MPI_CSCTL_SETUP_MASK (0xf << MPI_CSCTL_SETUP_SHIFT) +#define MPI_CSCTL_HOLD_SHIFT 20 +#define MPI_CSCTL_HOLD_MASK (0xf << MPI_CSCTL_HOLD_SHIFT) + +/* PCI registers */ +#define MPI_SP0_RANGE_REG 0x100 +#define MPI_SP0_REMAP_REG 0x104 +#define MPI_SP0_REMAP_ENABLE_MASK (1 << 0) +#define MPI_SP1_RANGE_REG 0x10C +#define MPI_SP1_REMAP_REG 0x110 +#define MPI_SP1_REMAP_ENABLE_MASK (1 << 0) + +#define MPI_L2PCFG_REG 0x11C +#define MPI_L2PCFG_CFG_TYPE_SHIFT 0 +#define MPI_L2PCFG_CFG_TYPE_MASK (0x3 << MPI_L2PCFG_CFG_TYPE_SHIFT) +#define MPI_L2PCFG_REG_SHIFT 2 +#define MPI_L2PCFG_REG_MASK (0x3f << MPI_L2PCFG_REG_SHIFT) +#define MPI_L2PCFG_FUNC_SHIFT 8 +#define MPI_L2PCFG_FUNC_MASK (0x7 << MPI_L2PCFG_FUNC_SHIFT) +#define MPI_L2PCFG_DEVNUM_SHIFT 11 +#define MPI_L2PCFG_DEVNUM_MASK (0x1f << MPI_L2PCFG_DEVNUM_SHIFT) +#define MPI_L2PCFG_CFG_USEREG_MASK (1 << 30) +#define MPI_L2PCFG_CFG_SEL_MASK (1 << 31) + +#define MPI_L2PMEMRANGE1_REG 0x120 +#define MPI_L2PMEMBASE1_REG 0x124 +#define MPI_L2PMEMREMAP1_REG 0x128 +#define MPI_L2PMEMRANGE2_REG 0x12C +#define MPI_L2PMEMBASE2_REG 0x130 +#define MPI_L2PMEMREMAP2_REG 0x134 +#define MPI_L2PIORANGE_REG 0x138 +#define MPI_L2PIOBASE_REG 0x13C +#define MPI_L2PIOREMAP_REG 0x140 +#define MPI_L2P_BASE_MASK (0xffff8000) +#define MPI_L2PREMAP_ENABLED_MASK (1 << 0) +#define MPI_L2PREMAP_IS_CARDBUS_MASK (1 << 2) + +#define MPI_PCIMODESEL_REG 0x144 +#define MPI_PCIMODESEL_BAR1_NOSWAP_MASK (1 << 0) +#define MPI_PCIMODESEL_BAR2_NOSWAP_MASK (1 << 1) +#define MPI_PCIMODESEL_EXT_ARB_MASK (1 << 2) +#define MPI_PCIMODESEL_PREFETCH_SHIFT 4 +#define MPI_PCIMODESEL_PREFETCH_MASK (0xf << MPI_PCIMODESEL_PREFETCH_SHIFT) + +#define MPI_LOCBUSCTL_REG 0x14C +#define MPI_LOCBUSCTL_EN_PCI_GPIO_MASK (1 << 0) +#define MPI_LOCBUSCTL_U2P_NOSWAP_MASK (1 << 1) + +#define MPI_LOCINT_REG 0x150 +#define MPI_LOCINT_MASK(x) (1 << (x + 16)) +#define MPI_LOCINT_STAT(x) (1 << (x)) +#define MPI_LOCINT_DIR_FAILED 6 +#define MPI_LOCINT_EXT_PCI_INT 7 +#define MPI_LOCINT_SERR 8 +#define MPI_LOCINT_CSERR 9 + +#define MPI_PCICFGCTL_REG 0x178 +#define MPI_PCICFGCTL_CFGADDR_SHIFT 2 +#define MPI_PCICFGCTL_CFGADDR_MASK (0x1f << MPI_PCICFGCTL_CFGADDR_SHIFT) +#define MPI_PCICFGCTL_WRITEEN_MASK (1 << 7) + +#define MPI_PCICFGDATA_REG 0x17C + +/* PCI host bridge custom register */ +#define BCMPCI_REG_TIMERS 0x40 +#define REG_TIMER_TRDY_SHIFT 0 +#define REG_TIMER_TRDY_MASK (0xff << REG_TIMER_TRDY_SHIFT) +#define REG_TIMER_RETRY_SHIFT 8 +#define REG_TIMER_RETRY_MASK (0xff << REG_TIMER_RETRY_SHIFT) + + +/************************************************************************* + * _REG relative to RSET_PCMCIA + *************************************************************************/ + +#define PCMCIA_C1_REG 0x0 +#define PCMCIA_C1_CD1_MASK (1 << 0) +#define PCMCIA_C1_CD2_MASK (1 << 1) +#define PCMCIA_C1_VS1_MASK (1 << 2) +#define PCMCIA_C1_VS2_MASK (1 << 3) +#define PCMCIA_C1_VS1OE_MASK (1 << 6) +#define PCMCIA_C1_VS2OE_MASK (1 << 7) +#define PCMCIA_C1_CBIDSEL_SHIFT (8) +#define PCMCIA_C1_CBIDSEL_MASK (0x1f << PCMCIA_C1_CBIDSEL_SHIFT) +#define PCMCIA_C1_EN_PCMCIA_GPIO_MASK (1 << 13) +#define PCMCIA_C1_EN_PCMCIA_MASK (1 << 14) +#define PCMCIA_C1_EN_CARDBUS_MASK (1 << 15) +#define PCMCIA_C1_RESET_MASK (1 << 18) + +#define PCMCIA_C2_REG 0x8 +#define PCMCIA_C2_DATA16_MASK (1 << 0) +#define PCMCIA_C2_BYTESWAP_MASK (1 << 1) +#define PCMCIA_C2_RWCOUNT_SHIFT 2 +#define PCMCIA_C2_RWCOUNT_MASK (0x3f << PCMCIA_C2_RWCOUNT_SHIFT) +#define PCMCIA_C2_INACTIVE_SHIFT 8 +#define PCMCIA_C2_INACTIVE_MASK (0x3f << PCMCIA_C2_INACTIVE_SHIFT) +#define PCMCIA_C2_SETUP_SHIFT 16 +#define PCMCIA_C2_SETUP_MASK (0x3f << PCMCIA_C2_SETUP_SHIFT) +#define PCMCIA_C2_HOLD_SHIFT 24 +#define PCMCIA_C2_HOLD_MASK (0x3f << PCMCIA_C2_HOLD_SHIFT) + + +/************************************************************************* + * _REG relative to RSET_SDRAM + *************************************************************************/ + +#define SDRAM_CFG_REG 0x0 +#define SDRAM_CFG_ROW_SHIFT 4 +#define SDRAM_CFG_ROW_MASK (0x3 << SDRAM_CFG_ROW_SHIFT) +#define SDRAM_CFG_COL_SHIFT 6 +#define SDRAM_CFG_COL_MASK (0x3 << SDRAM_CFG_COL_SHIFT) +#define SDRAM_CFG_32B_SHIFT 10 +#define SDRAM_CFG_32B_MASK (1 << SDRAM_CFG_32B_SHIFT) +#define SDRAM_CFG_BANK_SHIFT 13 +#define SDRAM_CFG_BANK_MASK (1 << SDRAM_CFG_BANK_SHIFT) + +#define SDRAM_PRIO_REG 0x2C +#define SDRAM_PRIO_MIPS_SHIFT 29 +#define SDRAM_PRIO_MIPS_MASK (1 << SDRAM_PRIO_MIPS_SHIFT) +#define SDRAM_PRIO_ADSL_SHIFT 30 +#define SDRAM_PRIO_ADSL_MASK (1 << SDRAM_PRIO_ADSL_SHIFT) +#define SDRAM_PRIO_EN_SHIFT 31 +#define SDRAM_PRIO_EN_MASK (1 << SDRAM_PRIO_EN_SHIFT) + + +/************************************************************************* + * _REG relative to RSET_MEMC + *************************************************************************/ + +#define MEMC_CFG_REG 0x4 +#define MEMC_CFG_32B_SHIFT 1 +#define MEMC_CFG_32B_MASK (1 << MEMC_CFG_32B_SHIFT) +#define MEMC_CFG_COL_SHIFT 3 +#define MEMC_CFG_COL_MASK (0x3 << MEMC_CFG_COL_SHIFT) +#define MEMC_CFG_ROW_SHIFT 6 +#define MEMC_CFG_ROW_MASK (0x3 << MEMC_CFG_ROW_SHIFT) + + +/************************************************************************* + * _REG relative to RSET_DDR + *************************************************************************/ + +#define DDR_DMIPSPLLCFG_REG 0x18 +#define DMIPSPLLCFG_M1_SHIFT 0 +#define DMIPSPLLCFG_M1_MASK (0xff << DMIPSPLLCFG_M1_SHIFT) +#define DMIPSPLLCFG_N1_SHIFT 23 +#define DMIPSPLLCFG_N1_MASK (0x3f << DMIPSPLLCFG_N1_SHIFT) +#define DMIPSPLLCFG_N2_SHIFT 29 +#define DMIPSPLLCFG_N2_MASK (0x7 << DMIPSPLLCFG_N2_SHIFT) + +#endif /* BCM63XX_REGS_H_ */ + diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h new file mode 100644 index 00000000000..c0fce833c9e --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h @@ -0,0 +1,11 @@ +#ifndef BCM63XX_TIMER_H_ +#define BCM63XX_TIMER_H_ + +int bcm63xx_timer_register(int id, void (*callback)(void *data), void *data); +void bcm63xx_timer_unregister(int id); +int bcm63xx_timer_set(int id, int monotonic, unsigned int countdown_us); +int bcm63xx_timer_enable(int id); +int bcm63xx_timer_disable(int id); +unsigned int bcm63xx_timer_countdown(unsigned int countdown_us); + +#endif /* !BCM63XX_TIMER_H_ */ diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h new file mode 100644 index 00000000000..6479090a410 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h @@ -0,0 +1,60 @@ +#ifndef BOARD_BCM963XX_H_ +#define BOARD_BCM963XX_H_ + +#include <linux/types.h> +#include <linux/gpio.h> +#include <linux/leds.h> +#include <bcm63xx_dev_enet.h> +#include <bcm63xx_dev_dsp.h> + +/* + * flash mapping + */ +#define BCM963XX_CFE_VERSION_OFFSET 0x570 +#define BCM963XX_NVRAM_OFFSET 0x580 + +/* + * nvram structure + */ +struct bcm963xx_nvram { + u32 version; + u8 reserved1[256]; + u8 name[16]; + u32 main_tp_number; + u32 psi_size; + u32 mac_addr_count; + u8 mac_addr_base[6]; + u8 reserved2[2]; + u32 checksum_old; + u8 reserved3[720]; + u32 checksum_high; +}; + +/* + * board definition + */ +struct board_info { + u8 name[16]; + unsigned int expected_cpu_id; + + /* enabled feature/device */ + unsigned int has_enet0:1; + unsigned int has_enet1:1; + unsigned int has_pci:1; + unsigned int has_pccard:1; + unsigned int has_ohci0:1; + unsigned int has_ehci0:1; + unsigned int has_dsp:1; + + /* ethernet config */ + struct bcm63xx_enet_platform_data enet0; + struct bcm63xx_enet_platform_data enet1; + + /* DSP config */ + struct bcm63xx_dsp_platform_data dsp; + + /* GPIO LEDs */ + struct gpio_led leds[5]; +}; + +#endif /* ! BOARD_BCM963XX_H_ */ diff --git a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h new file mode 100644 index 00000000000..71742bac940 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h @@ -0,0 +1,51 @@ +#ifndef __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H +#define __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H + +#include <bcm63xx_cpu.h> + +#define cpu_has_tlb 1 +#define cpu_has_4kex 1 +#define cpu_has_4k_cache 1 +#define cpu_has_fpu 0 +#define cpu_has_32fpr 0 +#define cpu_has_counter 1 +#define cpu_has_watch 0 +#define cpu_has_divec 1 +#define cpu_has_vce 0 +#define cpu_has_cache_cdex_p 0 +#define cpu_has_cache_cdex_s 0 +#define cpu_has_prefetch 1 +#define cpu_has_mcheck 1 +#define cpu_has_ejtag 1 +#define cpu_has_llsc 1 +#define cpu_has_mips16 0 +#define cpu_has_mdmx 0 +#define cpu_has_mips3d 0 +#define cpu_has_smartmips 0 +#define cpu_has_vtag_icache 0 + +#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345)) +#define cpu_has_dc_aliases 0 +#endif + +#define cpu_has_ic_fills_f_dc 0 +#define cpu_has_pindexed_dcache 0 + +#define cpu_has_mips32r1 1 +#define cpu_has_mips32r2 0 +#define cpu_has_mips64r1 0 +#define cpu_has_mips64r2 0 + +#define cpu_has_dsp 0 +#define cpu_has_mipsmt 0 +#define cpu_has_userlocal 0 + +#define cpu_has_nofpuex 0 +#define cpu_has_64bits 0 +#define cpu_has_64bit_zero_reg 0 + +#define cpu_dcache_line_size() 16 +#define cpu_icache_line_size() 16 +#define cpu_scache_line_size() 0 + +#endif /* __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-bcm63xx/gpio.h b/arch/mips/include/asm/mach-bcm63xx/gpio.h new file mode 100644 index 00000000000..7cda8c0a397 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/gpio.h @@ -0,0 +1,15 @@ +#ifndef __ASM_MIPS_MACH_BCM63XX_GPIO_H +#define __ASM_MIPS_MACH_BCM63XX_GPIO_H + +#include <bcm63xx_gpio.h> + +#define gpio_to_irq(gpio) NULL + +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value + +#define gpio_cansleep __gpio_cansleep + +#include <asm-generic/gpio.h> + +#endif /* __ASM_MIPS_MACH_BCM63XX_GPIO_H */ diff --git a/arch/mips/include/asm/mach-bcm63xx/war.h b/arch/mips/include/asm/mach-bcm63xx/war.h new file mode 100644 index 00000000000..8e3f3fdf320 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/war.h @@ -0,0 +1,25 @@ +/* + * 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) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> + */ +#ifndef __ASM_MIPS_MACH_BCM63XX_WAR_H +#define __ASM_MIPS_MACH_BCM63XX_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 0 +#define MIPS_CACHE_SYNC_WAR 0 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define RM9000_CDEX_SMP_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 0 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif /* __ASM_MIPS_MACH_BCM63XX_WAR_H */ diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h index 3d830756b13..425e708d4fb 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h @@ -31,12 +31,16 @@ #define cpu_has_cache_cdex_s 0 #define cpu_has_prefetch 1 +#define cpu_has_llsc 1 /* - * We should disable LL/SC on non SMP systems as it is faster to - * disable interrupts for atomic access than a LL/SC. Unfortunatly we - * cannot as this breaks asm/futex.h + * We Disable LL/SC on non SMP systems as it is faster to disable + * interrupts for atomic access than a LL/SC. */ -#define cpu_has_llsc 1 +#ifdef CONFIG_SMP +# define kernel_uses_llsc 1 +#else +# define kernel_uses_llsc 0 +#endif #define cpu_has_vtag_icache 1 #define cpu_has_dc_aliases 0 #define cpu_has_ic_fills_f_dc 0 diff --git a/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h index 550a10dc9db..ce5b6e270e3 100644 --- a/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h @@ -13,8 +13,8 @@ * loongson2f user manual. */ -#ifndef __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H -#define __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H +#ifndef __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H +#define __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H #define cpu_dcache_line_size() 32 #define cpu_icache_line_size() 32 @@ -56,4 +56,4 @@ #define cpu_has_watch 1 #define cpu_icache_snoops_remote_store 1 -#endif /* __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H */ +#endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-lemote/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h index c8de5e75077..71a6851ba83 100644 --- a/arch/mips/include/asm/mach-lemote/dma-coherence.h +++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h @@ -8,8 +8,8 @@ * Author: Fuxin Zhang, zhangfx@lemote.com * */ -#ifndef __ASM_MACH_LEMOTE_DMA_COHERENCE_H -#define __ASM_MACH_LEMOTE_DMA_COHERENCE_H +#ifndef __ASM_MACH_LOONGSON_DMA_COHERENCE_H +#define __ASM_MACH_LOONGSON_DMA_COHERENCE_H struct device; @@ -65,4 +65,4 @@ static inline int plat_device_is_coherent(struct device *dev) return 0; } -#endif /* __ASM_MACH_LEMOTE_DMA_COHERENCE_H */ +#endif /* __ASM_MACH_LOONGSON_DMA_COHERENCE_H */ diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h new file mode 100644 index 00000000000..da70bcf2304 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/loongson.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin <wuzj@lemote.com> + * + * 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. + * + */ + +#ifndef __ASM_MACH_LOONGSON_LOONGSON_H +#define __ASM_MACH_LOONGSON_LOONGSON_H + +#include <linux/io.h> +#include <linux/init.h> + +/* there is an internal bonito64-compatiable northbridge in loongson2e/2f */ +#include <asm/mips-boards/bonito64.h> + +/* loongson internal northbridge initialization */ +extern void bonito_irq_init(void); + +/* machine-specific reboot/halt operation */ +extern void mach_prepare_reboot(void); +extern void mach_prepare_shutdown(void); + +/* environment arguments from bootloader */ +extern unsigned long bus_clock, cpu_clock_freq; +extern unsigned long memsize, highmemsize; + +/* loongson-specific command line, env and memory initialization */ +extern void __init prom_init_memory(void); +extern void __init prom_init_cmdline(void); +extern void __init prom_init_env(void); + +/* irq operation functions */ +extern void bonito_irqdispatch(void); +extern void __init bonito_irq_init(void); +extern void __init set_irq_trigger_mode(void); +extern void __init mach_init_irq(void); +extern void mach_irq_dispatch(unsigned int pending); + +/* PCI Configuration Registers */ +#define LOONGSON_PCI_ISR4C BONITO_PCI_REG(0x4c) + +/* PCI_Hit*_Sel_* */ + +#define LOONGSON_PCI_HIT0_SEL_L BONITO(BONITO_REGBASE + 0x50) +#define LOONGSON_PCI_HIT0_SEL_H BONITO(BONITO_REGBASE + 0x54) +#define LOONGSON_PCI_HIT1_SEL_L BONITO(BONITO_REGBASE + 0x58) +#define LOONGSON_PCI_HIT1_SEL_H BONITO(BONITO_REGBASE + 0x5c) +#define LOONGSON_PCI_HIT2_SEL_L BONITO(BONITO_REGBASE + 0x60) +#define LOONGSON_PCI_HIT2_SEL_H BONITO(BONITO_REGBASE + 0x64) + +/* PXArb Config & Status */ + +#define LOONGSON_PXARB_CFG BONITO(BONITO_REGBASE + 0x68) +#define LOONGSON_PXARB_STATUS BONITO(BONITO_REGBASE + 0x6c) + +/* loongson2-specific perf counter IRQ */ +#define LOONGSON2_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) + +#endif /* __ASM_MACH_LOONGSON_LOONGSON_H */ diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h new file mode 100644 index 00000000000..206ea206791 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/machine.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin <wuzj@lemote.com> + * + * 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. + */ + +#ifndef __ASM_MACH_LOONGSON_MACHINE_H +#define __ASM_MACH_LOONGSON_MACHINE_H + +#ifdef CONFIG_LEMOTE_FULOONG2E + +#define LOONGSON_UART_BASE (BONITO_PCIIO_BASE + 0x3f8) + +#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2E + +#endif + +#endif /* __ASM_MACH_LOONGSON_MACHINE_H */ diff --git a/arch/mips/include/asm/mach-lemote/mc146818rtc.h b/arch/mips/include/asm/mach-loongson/mc146818rtc.h index ed5147e1108..ed7fe978335 100644 --- a/arch/mips/include/asm/mach-lemote/mc146818rtc.h +++ b/arch/mips/include/asm/mach-loongson/mc146818rtc.h @@ -7,8 +7,8 @@ * * RTC routines for PC style attached Dallas chip. */ -#ifndef __ASM_MACH_LEMOTE_MC146818RTC_H -#define __ASM_MACH_LEMOTE_MC146818RTC_H +#ifndef __ASM_MACH_LOONGSON_MC146818RTC_H +#define __ASM_MACH_LOONGSON_MC146818RTC_H #include <linux/io.h> @@ -33,4 +33,4 @@ static inline void CMOS_WRITE(unsigned char data, unsigned long addr) #define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970) #endif -#endif /* __ASM_MACH_LEMOTE_MC146818RTC_H */ +#endif /* __ASM_MACH_LOONGSON_MC146818RTC_H */ diff --git a/arch/mips/include/asm/mach-loongson/mem.h b/arch/mips/include/asm/mach-loongson/mem.h new file mode 100644 index 00000000000..bd7b3cba7e3 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/mem.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin <wuzj@lemote.com> + * + * 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. + */ + +#ifndef __ASM_MACH_LOONGSON_MEM_H +#define __ASM_MACH_LOONGSON_MEM_H + +/* + * On Lemote Loongson 2e + * + * the high memory space starts from 512M. + * the peripheral registers reside between 0x1000:0000 and 0x2000:0000. + */ + +#ifdef CONFIG_LEMOTE_FULOONG2E + +#define LOONGSON_HIGHMEM_START 0x20000000 + +#define LOONGSON_MMIO_MEM_START 0x10000000 +#define LOONGSON_MMIO_MEM_END 0x20000000 + +#endif + +#endif /* __ASM_MACH_LOONGSON_MEM_H */ diff --git a/arch/mips/include/asm/mach-lemote/pci.h b/arch/mips/include/asm/mach-loongson/pci.h index ea6aa143b78..f1663ca81da 100644 --- a/arch/mips/include/asm/mach-lemote/pci.h +++ b/arch/mips/include/asm/mach-loongson/pci.h @@ -19,12 +19,19 @@ * 02139, USA. */ -#ifndef _LEMOTE_PCI_H_ -#define _LEMOTE_PCI_H_ +#ifndef __ASM_MACH_LOONGSON_PCI_H_ +#define __ASM_MACH_LOONGSON_PCI_H_ -#define LOONGSON2E_PCI_MEM_START 0x14000000UL -#define LOONGSON2E_PCI_MEM_END 0x1fffffffUL -#define LOONGSON2E_PCI_IO_START 0x00004000UL -#define LOONGSON2E_IO_PORT_BASE 0x1fd00000UL +extern struct pci_ops bonito64_pci_ops; -#endif /* !_LEMOTE_PCI_H_ */ +#ifdef CONFIG_LEMOTE_FULOONG2E + +/* this pci memory space is mapped by pcimap in pci.c */ +#define LOONGSON_PCI_MEM_START BONITO_PCILO1_BASE +#define LOONGSON_PCI_MEM_END (BONITO_PCILO1_BASE + 0x04000000 * 2) +/* this is an offset from mips_io_port_base */ +#define LOONGSON_PCI_IO_START 0x00004000UL + +#endif + +#endif /* !__ASM_MACH_LOONGSON_PCI_H_ */ diff --git a/arch/mips/include/asm/mach-lemote/war.h b/arch/mips/include/asm/mach-loongson/war.h index 05f89e0f2a1..4b971c3ffd8 100644 --- a/arch/mips/include/asm/mach-lemote/war.h +++ b/arch/mips/include/asm/mach-loongson/war.h @@ -5,8 +5,8 @@ * * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> */ -#ifndef __ASM_MIPS_MACH_LEMOTE_WAR_H -#define __ASM_MIPS_MACH_LEMOTE_WAR_H +#ifndef __ASM_MACH_LOONGSON_WAR_H +#define __ASM_MACH_LOONGSON_WAR_H #define R4600_V1_INDEX_ICACHEOP_WAR 0 #define R4600_V1_HIT_CACHEOP_WAR 0 @@ -22,4 +22,4 @@ #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 -#endif /* __ASM_MIPS_MACH_LEMOTE_WAR_H */ +#endif /* __ASM_MACH_LEMOTE_WAR_H */ diff --git a/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h b/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h index 7f3e3f9bd23..2848cea42bc 100644 --- a/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h @@ -28,11 +28,7 @@ /* #define cpu_has_prefetch ? */ #define cpu_has_mcheck 1 /* #define cpu_has_ejtag ? */ -#ifdef CONFIG_CPU_HAS_LLSC #define cpu_has_llsc 1 -#else -#define cpu_has_llsc 0 -#endif /* #define cpu_has_vtag_icache ? */ /* #define cpu_has_dc_aliases ? */ /* #define cpu_has_ic_fills_f_dc ? */ diff --git a/arch/mips/include/asm/mips-boards/bonito64.h b/arch/mips/include/asm/mips-boards/bonito64.h index a0f04bb99c9..a576ce044c3 100644 --- a/arch/mips/include/asm/mips-boards/bonito64.h +++ b/arch/mips/include/asm/mips-boards/bonito64.h @@ -26,7 +26,7 @@ /* offsets from base register */ #define BONITO(x) (x) -#elif defined(CONFIG_LEMOTE_FULONG) +#elif defined(CONFIG_LEMOTE_FULOONG2E) #define BONITO(x) (*(volatile u32 *)((char *)CKSEG1ADDR(BONITO_REG_BASE) + (x))) #define BONITO_IRQ_BASE 32 diff --git a/arch/mips/include/asm/mips-boards/generic.h b/arch/mips/include/asm/mips-boards/generic.h index c0da1a881e3..46c08563e53 100644 --- a/arch/mips/include/asm/mips-boards/generic.h +++ b/arch/mips/include/asm/mips-boards/generic.h @@ -87,8 +87,6 @@ extern int mips_revision_sconid; -extern void mips_reboot_setup(void); - #ifdef CONFIG_PCI extern void mips_pcibios_init(void); #else diff --git a/arch/mips/include/asm/octeon/cvmx-rnm-defs.h b/arch/mips/include/asm/octeon/cvmx-rnm-defs.h new file mode 100644 index 00000000000..4586958c97b --- /dev/null +++ b/arch/mips/include/asm/octeon/cvmx-rnm-defs.h @@ -0,0 +1,88 @@ +/***********************license start*************** + * Author: Cavium Networks + * + * Contact: support@caviumnetworks.com + * This file is part of the OCTEON SDK + * + * Copyright (c) 2003-2008 Cavium Networks + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * or visit http://www.gnu.org/licenses/. + * + * This file may also be available under a different license from Cavium. + * Contact Cavium Networks for more information + ***********************license end**************************************/ + +#ifndef __CVMX_RNM_DEFS_H__ +#define __CVMX_RNM_DEFS_H__ + +#include <linux/types.h> + +#define CVMX_RNM_BIST_STATUS \ + CVMX_ADD_IO_SEG(0x0001180040000008ull) +#define CVMX_RNM_CTL_STATUS \ + CVMX_ADD_IO_SEG(0x0001180040000000ull) + +union cvmx_rnm_bist_status { + uint64_t u64; + struct cvmx_rnm_bist_status_s { + uint64_t reserved_2_63:62; + uint64_t rrc:1; + uint64_t mem:1; + } s; + struct cvmx_rnm_bist_status_s cn30xx; + struct cvmx_rnm_bist_status_s cn31xx; + struct cvmx_rnm_bist_status_s cn38xx; + struct cvmx_rnm_bist_status_s cn38xxp2; + struct cvmx_rnm_bist_status_s cn50xx; + struct cvmx_rnm_bist_status_s cn52xx; + struct cvmx_rnm_bist_status_s cn52xxp1; + struct cvmx_rnm_bist_status_s cn56xx; + struct cvmx_rnm_bist_status_s cn56xxp1; + struct cvmx_rnm_bist_status_s cn58xx; + struct cvmx_rnm_bist_status_s cn58xxp1; +}; + +union cvmx_rnm_ctl_status { + uint64_t u64; + struct cvmx_rnm_ctl_status_s { + uint64_t reserved_9_63:55; + uint64_t ent_sel:4; + uint64_t exp_ent:1; + uint64_t rng_rst:1; + uint64_t rnm_rst:1; + uint64_t rng_en:1; + uint64_t ent_en:1; + } s; + struct cvmx_rnm_ctl_status_cn30xx { + uint64_t reserved_4_63:60; + uint64_t rng_rst:1; + uint64_t rnm_rst:1; + uint64_t rng_en:1; + uint64_t ent_en:1; + } cn30xx; + struct cvmx_rnm_ctl_status_cn30xx cn31xx; + struct cvmx_rnm_ctl_status_cn30xx cn38xx; + struct cvmx_rnm_ctl_status_cn30xx cn38xxp2; + struct cvmx_rnm_ctl_status_s cn50xx; + struct cvmx_rnm_ctl_status_s cn52xx; + struct cvmx_rnm_ctl_status_s cn52xxp1; + struct cvmx_rnm_ctl_status_s cn56xx; + struct cvmx_rnm_ctl_status_s cn56xxp1; + struct cvmx_rnm_ctl_status_s cn58xx; + struct cvmx_rnm_ctl_status_s cn58xxp1; +}; + +#endif diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index e31e3fe14f8..9d9381e2e3d 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h @@ -271,7 +271,7 @@ static inline void cvmx_write_csr(uint64_t csr_addr, uint64_t val) * what RSL read we do, so we choose CVMX_MIO_BOOT_BIST_STAT * because it is fast and harmless. */ - if ((csr_addr >> 40) == (0x800118)) + if (((csr_addr >> 40) & 0x7ffff) == (0x118)) cvmx_read64(CVMX_MIO_BOOT_BIST_STAT); } diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index 4320239cf4e..f266295cce5 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h @@ -10,6 +10,7 @@ #define _ASM_PAGE_H #include <spaces.h> +#include <linux/const.h> /* * PAGE_SHIFT determines the page size @@ -29,12 +30,12 @@ #ifdef CONFIG_PAGE_SIZE_64KB #define PAGE_SHIFT 16 #endif -#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) #ifdef CONFIG_HUGETLB_PAGE #define HPAGE_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3) -#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT) +#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT) #define HPAGE_MASK (~(HPAGE_SIZE - 1)) #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) #endif /* CONFIG_HUGETLB_PAGE */ diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h index 4ed9d1bba2b..9cd50899395 100644 --- a/arch/mips/include/asm/pgtable-64.h +++ b/arch/mips/include/asm/pgtable-64.h @@ -109,13 +109,13 @@ #define VMALLOC_START MAP_BASE #define VMALLOC_END \ - (VMALLOC_START + PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE) + (VMALLOC_START + \ + PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE - (1UL << 32)) #if defined(CONFIG_MODULES) && defined(KBUILD_64BIT_SYM32) && \ VMALLOC_START != CKSSEG /* Load modules into 32bit-compatible segment. */ #define MODULE_START CKSSEG #define MODULE_END (FIXADDR_START-2*PAGE_SIZE) -extern pgd_t module_pg_dir[PTRS_PER_PGD]; #endif #define pte_ERROR(e) \ @@ -188,12 +188,7 @@ static inline void pud_clear(pud_t *pudp) #define __pmd_offset(address) pmd_index(address) /* to find an entry in a kernel page-table-directory */ -#ifdef MODULE_START -#define pgd_offset_k(address) \ - ((address) >= MODULE_START ? module_pg_dir : pgd_offset(&init_mm, 0UL)) -#else -#define pgd_offset_k(address) pgd_offset(&init_mm, 0UL) -#endif +#define pgd_offset_k(address) pgd_offset(&init_mm, address) #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) diff --git a/arch/mips/include/asm/system.h b/arch/mips/include/asm/system.h index cd30f83235b..fcf5f98d90c 100644 --- a/arch/mips/include/asm/system.h +++ b/arch/mips/include/asm/system.h @@ -32,6 +32,9 @@ extern asmlinkage void *resume(void *last, void *next, void *next_ti); struct task_struct; +extern unsigned int ll_bit; +extern struct task_struct *ll_task; + #ifdef CONFIG_MIPS_MT_FPAFF /* @@ -63,11 +66,18 @@ do { \ #define __mips_mt_fpaff_switch_to(prev) do { (void) (prev); } while (0) #endif +#define __clear_software_ll_bit() \ +do { \ + if (!__builtin_constant_p(cpu_has_llsc) || !cpu_has_llsc) \ + ll_bit = 0; \ +} while (0) + #define switch_to(prev, next, last) \ do { \ __mips_mt_fpaff_switch_to(prev); \ if (cpu_has_dsp) \ __save_dsp(prev); \ + __clear_software_ll_bit(); \ (last) = resume(prev, next, task_thread_info(next)); \ } while (0) @@ -84,7 +94,7 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) { __u32 retval; - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { unsigned long dummy; __asm__ __volatile__( @@ -99,7 +109,7 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) : "=&r" (retval), "=m" (*m), "=&r" (dummy) : "R" (*m), "Jr" (val) : "memory"); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { unsigned long dummy; __asm__ __volatile__( @@ -136,7 +146,7 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) { __u64 retval; - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && R10000_LLSC_WAR) { unsigned long dummy; __asm__ __volatile__( @@ -149,7 +159,7 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) : "=&r" (retval), "=m" (*m), "=&r" (dummy) : "R" (*m), "Jr" (val) : "memory"); - } else if (cpu_has_llsc) { + } else if (kernel_uses_llsc) { unsigned long dummy; __asm__ __volatile__( diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 8d006ec6567..2c1e1d02338 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -183,9 +183,6 @@ void output_mm_defines(void) OFFSET(MM_PGD, mm_struct, pgd); OFFSET(MM_CONTEXT, mm_struct, context); BLANK(); - DEFINE(_PAGE_SIZE, PAGE_SIZE); - DEFINE(_PAGE_SHIFT, PAGE_SHIFT); - BLANK(); DEFINE(_PGD_T_SIZE, sizeof(pgd_t)); DEFINE(_PMD_T_SIZE, sizeof(pmd_t)); DEFINE(_PTE_T_SIZE, sizeof(pte_t)); diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c index 02b7713cf71..408d0a07b3a 100644 --- a/arch/mips/kernel/cpu-bugs64.c +++ b/arch/mips/kernel/cpu-bugs64.c @@ -167,7 +167,7 @@ static inline void check_mult_sh(void) panic(bug64hit, !R4000_WAR ? r4kwar : nowar); } -static volatile int daddi_ov __cpuinitdata = 0; +static volatile int daddi_ov __cpuinitdata; asmlinkage void __init do_daddi_ov(struct pt_regs *regs) { diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 1abe9905c9c..f709657e4dc 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -31,7 +31,7 @@ * The wait instruction stops the pipeline and reduces the power consumption of * the CPU very much. */ -void (*cpu_wait)(void) = NULL; +void (*cpu_wait)(void); static void r3081_wait(void) { @@ -91,16 +91,13 @@ static void rm7k_wait_irqoff(void) local_irq_enable(); } -/* The Au1xxx wait is available only if using 32khz counter or - * external timer source, but specifically not CP0 Counter. */ -int allow_au1k_wait; - +/* + * The Au1xxx wait is available only if using 32khz counter or + * external timer source, but specifically not CP0 Counter. + * alchemy/common/time.c may override cpu_wait! + */ static void au1k_wait(void) { - if (!allow_au1k_wait) - return; - - /* using the wait instruction makes CP0 counter unusable */ __asm__(" .set mips3 \n" " cache 0x14, 0(%0) \n" " cache 0x14, 32(%0) \n" @@ -115,7 +112,7 @@ static void au1k_wait(void) : : "r" (au1k_wait)); } -static int __initdata nowait = 0; +static int __initdata nowait; static int __init wait_disable(char *s) { @@ -159,6 +156,9 @@ void __init check_wait(void) case CPU_25KF: case CPU_PR4450: case CPU_BCM3302: + case CPU_BCM6338: + case CPU_BCM6348: + case CPU_BCM6358: case CPU_CAVIUM_OCTEON: cpu_wait = r4k_wait; break; @@ -857,6 +857,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) decode_configs(c); switch (c->processor_id & 0xff00) { case PRID_IMP_BCM3302: + /* same as PRID_IMP_BCM6338 */ c->cputype = CPU_BCM3302; __cpu_name[cpu] = "Broadcom BCM3302"; break; @@ -864,6 +865,25 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) c->cputype = CPU_BCM4710; __cpu_name[cpu] = "Broadcom BCM4710"; break; + case PRID_IMP_BCM6345: + c->cputype = CPU_BCM6345; + __cpu_name[cpu] = "Broadcom BCM6345"; + break; + case PRID_IMP_BCM6348: + c->cputype = CPU_BCM6348; + __cpu_name[cpu] = "Broadcom BCM6348"; + break; + case PRID_IMP_BCM4350: + switch (c->processor_id & 0xf0) { + case PRID_REV_BCM6358: + c->cputype = CPU_BCM6358; + __cpu_name[cpu] = "Broadcom BCM6358"; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + break; } } diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index fd6e5122403..f2397f00db4 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -31,7 +31,7 @@ #include <asm/rtlx.h> #include <asm/kspd.h> -static struct workqueue_struct *workqueue = NULL; +static struct workqueue_struct *workqueue; static struct work_struct work; extern unsigned long cpu_khz; @@ -58,7 +58,7 @@ struct mtsp_syscall_generic { }; static struct list_head kspd_notifylist; -static int sp_stopping = 0; +static int sp_stopping; /* these should match with those in the SDE kit */ #define MTSP_SYSCALL_BASE 0 @@ -328,7 +328,7 @@ static void sp_cleanup(void) sys_chdir("/"); } -static int channel_open = 0; +static int channel_open; /* the work handler */ static void sp_work(struct work_struct *unused) diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c index 42461310b18..cbc6182b006 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -18,7 +18,7 @@ cpumask_t mt_fpu_cpumask; static int fpaff_threshold = -1; -unsigned long mt_fpemul_threshold = 0; +unsigned long mt_fpemul_threshold; /* * Replacement functions for the sys_sched_setaffinity() and diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c index d01665a453f..b2259e7cd82 100644 --- a/arch/mips/kernel/mips-mt.c +++ b/arch/mips/kernel/mips-mt.c @@ -125,10 +125,10 @@ void mips_mt_regdump(unsigned long mvpctl) local_irq_restore(flags); } -static int mt_opt_norps = 0; +static int mt_opt_norps; static int mt_opt_rpsctl = -1; static int mt_opt_nblsu = -1; -static int mt_opt_forceconfig7 = 0; +static int mt_opt_forceconfig7; static int mt_opt_config7 = -1; static int __init rps_disable(char *s) @@ -161,8 +161,8 @@ static int __init config7_set(char *str) __setup("config7=", config7_set); /* Experimental cache flush control parameters that should go away some day */ -int mt_protiflush = 0; -int mt_protdflush = 0; +int mt_protiflush; +int mt_protdflush; int mt_n_iflushes = 1; int mt_n_dflushes = 1; @@ -194,7 +194,7 @@ static int __init ndflush(char *s) } __setup("ndflush=", ndflush); -static unsigned int itc_base = 0; +static unsigned int itc_base; static int __init set_itc_base(char *str) { diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S index d52389672b0..3952b8323ef 100644 --- a/arch/mips/kernel/octeon_switch.S +++ b/arch/mips/kernel/octeon_switch.S @@ -36,9 +36,6 @@ .align 7 LEAF(resume) .set arch=octeon -#ifndef CONFIG_CPU_HAS_LLSC - sw zero, ll_bit -#endif mfc0 t1, CP0_STATUS LONG_S t1, THREAD_STATUS(a0) cpu_save_nonscratch a0 diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 656bde2e11b..698414b7a25 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -46,9 +46,6 @@ * struct thread_info *next_ti) ) */ LEAF(resume) -#ifndef CONFIG_CPU_HAS_LLSC - sw zero, ll_bit -#endif mfc0 t1, CP0_STATUS sw t1, THREAD_STATUS(a0) cpu_save_nonscratch a0 diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index d9bfae53c43..8893ee1a236 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -45,9 +45,6 @@ */ .align 5 LEAF(resume) -#ifndef CONFIG_CPU_HAS_LLSC - sw zero, ll_bit -#endif mfc0 t1, CP0_STATUS LONG_S t1, THREAD_STATUS(a0) cpu_save_nonscratch a0 diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 4ce93aa7b37..a10ebfdc28a 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -57,7 +57,7 @@ static struct chan_waitqueues { } channel_wqs[RTLX_CHANNELS]; static struct vpe_notifications notify; -static int sp_stopping = 0; +static int sp_stopping; extern void *vpe_get_shared(int index); diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index b5708212353..7c2de4f091c 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -187,78 +187,6 @@ illegal_syscall: j o32_syscall_exit END(handle_sys) - LEAF(mips_atomic_set) - andi v0, a1, 3 # must be word aligned - bnez v0, bad_alignment - - lw v1, TI_ADDR_LIMIT($28) # in legal address range? - addiu a0, a1, 4 - or a0, a0, a1 - and a0, a0, v1 - bltz a0, bad_address - -#ifdef CONFIG_CPU_HAS_LLSC - /* Ok, this is the ll/sc case. World is sane :-) */ -1: ll v0, (a1) - move a0, a2 -2: sc a0, (a1) -#if R10000_LLSC_WAR - beqzl a0, 1b -#else - beqz a0, 1b -#endif - - .section __ex_table,"a" - PTR 1b, bad_stack - PTR 2b, bad_stack - .previous -#else - sw a1, 16(sp) - sw a2, 20(sp) - - move a0, sp - move a2, a1 - li a1, 1 - jal do_page_fault - - lw a1, 16(sp) - lw a2, 20(sp) - - /* - * At this point the page should be readable and writable unless - * there was no more memory available. - */ -1: lw v0, (a1) -2: sw a2, (a1) - - .section __ex_table,"a" - PTR 1b, no_mem - PTR 2b, no_mem - .previous -#endif - - sw zero, PT_R7(sp) # success - sw v0, PT_R2(sp) # result - - j o32_syscall_exit # continue like a normal syscall - -no_mem: li v0, -ENOMEM - jr ra - -bad_address: - li v0, -EFAULT - jr ra - -bad_alignment: - li v0, -EINVAL - jr ra - END(mips_atomic_set) - - LEAF(sys_sysmips) - beq a0, MIPS_ATOMIC_SET, mips_atomic_set - j _sys_sysmips - END(sys_sysmips) - LEAF(sys_syscall) subu t0, a0, __NR_O32_Linux # check syscall number sltiu v0, t0, __NR_O32_Linux_syscalls + 1 diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 3d866f24e06..b97b993846d 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -124,78 +124,6 @@ illegal_syscall: j n64_syscall_exit END(handle_sys64) - LEAF(mips_atomic_set) - andi v0, a1, 3 # must be word aligned - bnez v0, bad_alignment - - LONG_L v1, TI_ADDR_LIMIT($28) # in legal address range? - LONG_ADDIU a0, a1, 4 - or a0, a0, a1 - and a0, a0, v1 - bltz a0, bad_address - -#ifdef CONFIG_CPU_HAS_LLSC - /* Ok, this is the ll/sc case. World is sane :-) */ -1: ll v0, (a1) - move a0, a2 -2: sc a0, (a1) -#if R10000_LLSC_WAR - beqzl a0, 1b -#else - beqz a0, 1b -#endif - - .section __ex_table,"a" - PTR 1b, bad_stack - PTR 2b, bad_stack - .previous -#else - sw a1, 16(sp) - sw a2, 20(sp) - - move a0, sp - move a2, a1 - li a1, 1 - jal do_page_fault - - lw a1, 16(sp) - lw a2, 20(sp) - - /* - * At this point the page should be readable and writable unless - * there was no more memory available. - */ -1: lw v0, (a1) -2: sw a2, (a1) - - .section __ex_table,"a" - PTR 1b, no_mem - PTR 2b, no_mem - .previous -#endif - - sd zero, PT_R7(sp) # success - sd v0, PT_R2(sp) # result - - j n64_syscall_exit # continue like a normal syscall - -no_mem: li v0, -ENOMEM - jr ra - -bad_address: - li v0, -EFAULT - jr ra - -bad_alignment: - li v0, -EINVAL - jr ra - END(mips_atomic_set) - - LEAF(sys_sysmips) - beq a0, MIPS_ATOMIC_SET, mips_atomic_set - j _sys_sysmips - END(sys_sysmips) - .align 3 sys_call_table: PTR sys_read /* 5000 */ diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 2950b97253b..2b290d70083 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -441,7 +441,7 @@ static void __init bootmem_init(void) * initialization hook for anything else was introduced. */ -static int usermem __initdata = 0; +static int usermem __initdata; static int __init early_parse_mem(char *p) { diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index bc7d9b05e2f..64668a93248 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -32,6 +32,7 @@ #include <linux/cpumask.h> #include <linux/cpu.h> #include <linux/err.h> +#include <linux/smp.h> #include <asm/atomic.h> #include <asm/cpu.h> @@ -49,8 +50,6 @@ volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */ -extern void cpu_idle(void); - /* Number of TCs (or siblings in Intel speak) per CPU core */ int smp_num_siblings = 1; EXPORT_SYMBOL(smp_num_siblings); diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index c16bb6d6c25..1a466baf0ed 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -95,14 +95,14 @@ void init_smtc_stats(void); /* Global SMTC Status */ -unsigned int smtc_status = 0; +unsigned int smtc_status; /* Boot command line configuration overrides */ static int vpe0limit; -static int ipibuffers = 0; -static int nostlb = 0; -static int asidmask = 0; +static int ipibuffers; +static int nostlb; +static int asidmask; unsigned long smtc_asid_mask = 0xff; static int __init vpe0tcs(char *str) @@ -151,7 +151,7 @@ __setup("asidmask=", asidmask_set); #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG -static int hang_trig = 0; +static int hang_trig; static int __init hangtrig_enable(char *s) { diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 8cf38464404..3fe1fcfa2e7 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -28,7 +28,9 @@ #include <linux/compiler.h> #include <linux/module.h> #include <linux/ipc.h> +#include <linux/uaccess.h> +#include <asm/asm.h> #include <asm/branch.h> #include <asm/cachectl.h> #include <asm/cacheflush.h> @@ -290,12 +292,116 @@ SYSCALL_DEFINE1(set_thread_area, unsigned long, addr) return 0; } -asmlinkage int _sys_sysmips(long cmd, long arg1, long arg2, long arg3) +static inline int mips_atomic_set(struct pt_regs *regs, + unsigned long addr, unsigned long new) { + unsigned long old, tmp; + unsigned int err; + + if (unlikely(addr & 3)) + return -EINVAL; + + if (unlikely(!access_ok(VERIFY_WRITE, addr, 4))) + return -EINVAL; + + if (cpu_has_llsc && R10000_LLSC_WAR) { + __asm__ __volatile__ ( + " li %[err], 0 \n" + "1: ll %[old], (%[addr]) \n" + " move %[tmp], %[new] \n" + "2: sc %[tmp], (%[addr]) \n" + " beqzl %[tmp], 1b \n" + "3: \n" + " .section .fixup,\"ax\" \n" + "4: li %[err], %[efault] \n" + " j 3b \n" + " .previous \n" + " .section __ex_table,\"a\" \n" + " "STR(PTR)" 1b, 4b \n" + " "STR(PTR)" 2b, 4b \n" + " .previous \n" + : [old] "=&r" (old), + [err] "=&r" (err), + [tmp] "=&r" (tmp) + : [addr] "r" (addr), + [new] "r" (new), + [efault] "i" (-EFAULT) + : "memory"); + } else if (cpu_has_llsc) { + __asm__ __volatile__ ( + " li %[err], 0 \n" + "1: ll %[old], (%[addr]) \n" + " move %[tmp], %[new] \n" + "2: sc %[tmp], (%[addr]) \n" + " bnez %[tmp], 4f \n" + "3: \n" + " .subsection 2 \n" + "4: b 1b \n" + " .previous \n" + " \n" + " .section .fixup,\"ax\" \n" + "5: li %[err], %[efault] \n" + " j 3b \n" + " .previous \n" + " .section __ex_table,\"a\" \n" + " "STR(PTR)" 1b, 5b \n" + " "STR(PTR)" 2b, 5b \n" + " .previous \n" + : [old] "=&r" (old), + [err] "=&r" (err), + [tmp] "=&r" (tmp) + : [addr] "r" (addr), + [new] "r" (new), + [efault] "i" (-EFAULT) + : "memory"); + } else { + do { + preempt_disable(); + ll_bit = 1; + ll_task = current; + preempt_enable(); + + err = __get_user(old, (unsigned int *) addr); + err |= __put_user(new, (unsigned int *) addr); + if (err) + break; + rmb(); + } while (!ll_bit); + } + + if (unlikely(err)) + return err; + + regs->regs[2] = old; + regs->regs[7] = 0; /* No error */ + + /* + * Don't let your children do this ... + */ + __asm__ __volatile__( + " move $29, %0 \n" + " j syscall_exit \n" + : /* no outputs */ + : "r" (regs)); + + /* unreached. Honestly. */ + while (1); +} + +save_static_function(sys_sysmips); +static int __used noinline +_sys_sysmips(nabi_no_regargs struct pt_regs regs) +{ + long cmd, arg1, arg2, arg3; + + cmd = regs.regs[4]; + arg1 = regs.regs[5]; + arg2 = regs.regs[6]; + arg3 = regs.regs[7]; + switch (cmd) { case MIPS_ATOMIC_SET: - printk(KERN_CRIT "How did I get here?\n"); - return -EINVAL; + return mips_atomic_set(®s, arg1, arg2); case MIPS_FIXADE: if (arg1 & ~3) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 08f1edf355e..0a18b4c62af 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -466,9 +466,8 @@ asmlinkage void do_be(struct pt_regs *regs) * The ll_bit is cleared by r*_switch.S */ -unsigned long ll_bit; - -static struct task_struct *ll_task = NULL; +unsigned int ll_bit; +struct task_struct *ll_task; static inline int simulate_ll(struct pt_regs *regs, unsigned int opcode) { diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 1474c18fb77..2769bed3d2a 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -1,4 +1,5 @@ #include <asm/asm-offsets.h> +#include <asm/page.h> #include <asm-generic/vmlinux.lds.h> #undef mips @@ -42,13 +43,7 @@ SECTIONS } :text = 0 _etext = .; /* End of text section */ - /* Exception table */ - . = ALIGN(16); - __ex_table : { - __start___ex_table = .; - *(__ex_table) - __stop___ex_table = .; - } + EXCEPTION_TABLE(16) /* Exception table for data bus errors */ __dbe_table : { @@ -65,20 +60,10 @@ SECTIONS /* writeable */ .data : { /* Data */ . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ - /* - * This ALIGN is needed as a workaround for a bug a - * gcc bug upto 4.1 which limits the maximum alignment - * to at most 32kB and results in the following - * warning: - * - * CC arch/mips/kernel/init_task.o - * arch/mips/kernel/init_task.c:30: warning: alignment - * of ‘init_thread_union’ is greater than maximum - * object file alignment. Using 32768 - */ - . = ALIGN(_PAGE_SIZE); - *(.data.init_task) + INIT_TASK_DATA(PAGE_SIZE) + NOSAVE_DATA + CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) DATA_DATA CONSTRUCTORS } @@ -95,51 +80,13 @@ SECTIONS .sdata : { *(.sdata) } - - . = ALIGN(_PAGE_SIZE); - .data_nosave : { - __nosave_begin = .; - *(.data.nosave) - } - . = ALIGN(_PAGE_SIZE); - __nosave_end = .; - - . = ALIGN(1 << CONFIG_MIPS_L1_CACHE_SHIFT); - .data.cacheline_aligned : { - *(.data.cacheline_aligned) - } _edata = .; /* End of data section */ /* will be freed after init */ - . = ALIGN(_PAGE_SIZE); /* Init code and data */ + . = ALIGN(PAGE_SIZE); /* Init code and data */ __init_begin = .; - .init.text : { - _sinittext = .; - INIT_TEXT - _einittext = .; - } - .init.data : { - INIT_DATA - } - . = ALIGN(16); - .init.setup : { - __setup_start = .; - *(.init.setup) - __setup_end = .; - } - - .initcall.init : { - __initcall_start = .; - INITCALLS - __initcall_end = .; - } - - .con_initcall.init : { - __con_initcall_start = .; - *(.con_initcall.init) - __con_initcall_end = .; - } - SECURITY_INIT + INIT_TEXT_SECTION(PAGE_SIZE) + INIT_DATA_SECTION(16) /* .exit.text is discarded at runtime, not link time, to deal with * references from .rodata @@ -150,29 +97,13 @@ SECTIONS .exit.data : { EXIT_DATA } -#if defined(CONFIG_BLK_DEV_INITRD) - . = ALIGN(_PAGE_SIZE); - .init.ramfs : { - __initramfs_start = .; - *(.init.ramfs) - __initramfs_end = .; - } -#endif - PERCPU(_PAGE_SIZE) - . = ALIGN(_PAGE_SIZE); + + PERCPU(PAGE_SIZE) + . = ALIGN(PAGE_SIZE); __init_end = .; /* freed after init ends here */ - __bss_start = .; /* BSS */ - .sbss : { - *(.sbss) - *(.scommon) - } - .bss : { - *(.bss) - *(COMMON) - } - __bss_stop = .; + BSS_SECTION(0, 0, 0) _end = . ; diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 9a1ab7e87fd..eb6c4c5b7fb 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -74,7 +74,7 @@ static const int minor = 1; /* fixed for now */ #ifdef CONFIG_MIPS_APSP_KSPD static struct kspd_notifications kspd_events; -static int kspd_events_reqd = 0; +static int kspd_events_reqd; #endif /* grab the likely amount of memory we will need. */ diff --git a/arch/mips/lemote/lm2e/Makefile b/arch/mips/lemote/lm2e/Makefile deleted file mode 100644 index d34671d1b89..00000000000 --- a/arch/mips/lemote/lm2e/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for Lemote Fulong mini-PC board. -# - -obj-y += setup.o prom.o reset.o irq.o pci.o bonito-irq.o dbg_io.o mem.o - -EXTRA_CFLAGS += -Werror diff --git a/arch/mips/lemote/lm2e/dbg_io.c b/arch/mips/lemote/lm2e/dbg_io.c deleted file mode 100644 index 6c95da3ca76..00000000000 --- a/arch/mips/lemote/lm2e/dbg_io.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/io.h> -#include <linux/init.h> -#include <linux/types.h> - -#include <asm/serial.h> - -#define UART16550_BAUD_2400 2400 -#define UART16550_BAUD_4800 4800 -#define UART16550_BAUD_9600 9600 -#define UART16550_BAUD_19200 19200 -#define UART16550_BAUD_38400 38400 -#define UART16550_BAUD_57600 57600 -#define UART16550_BAUD_115200 115200 - -#define UART16550_PARITY_NONE 0 -#define UART16550_PARITY_ODD 0x08 -#define UART16550_PARITY_EVEN 0x18 -#define UART16550_PARITY_MARK 0x28 -#define UART16550_PARITY_SPACE 0x38 - -#define UART16550_DATA_5BIT 0x0 -#define UART16550_DATA_6BIT 0x1 -#define UART16550_DATA_7BIT 0x2 -#define UART16550_DATA_8BIT 0x3 - -#define UART16550_STOP_1BIT 0x0 -#define UART16550_STOP_2BIT 0x4 - -/* ----------------------------------------------------- */ - -/* === CONFIG === */ -#ifdef CONFIG_64BIT -#define BASE (0xffffffffbfd003f8) -#else -#define BASE (0xbfd003f8) -#endif - -#define MAX_BAUD BASE_BAUD -/* === END OF CONFIG === */ - -#define REG_OFFSET 1 - -/* register offset */ -#define OFS_RCV_BUFFER 0 -#define OFS_TRANS_HOLD 0 -#define OFS_SEND_BUFFER 0 -#define OFS_INTR_ENABLE (1*REG_OFFSET) -#define OFS_INTR_ID (2*REG_OFFSET) -#define OFS_DATA_FORMAT (3*REG_OFFSET) -#define OFS_LINE_CONTROL (3*REG_OFFSET) -#define OFS_MODEM_CONTROL (4*REG_OFFSET) -#define OFS_RS232_OUTPUT (4*REG_OFFSET) -#define OFS_LINE_STATUS (5*REG_OFFSET) -#define OFS_MODEM_STATUS (6*REG_OFFSET) -#define OFS_RS232_INPUT (6*REG_OFFSET) -#define OFS_SCRATCH_PAD (7*REG_OFFSET) - -#define OFS_DIVISOR_LSB (0*REG_OFFSET) -#define OFS_DIVISOR_MSB (1*REG_OFFSET) - -/* memory-mapped read/write of the port */ -#define UART16550_READ(y) readb((char *)BASE + (y)) -#define UART16550_WRITE(y, z) writeb(z, (char *)BASE + (y)) - -void debugInit(u32 baud, u8 data, u8 parity, u8 stop) -{ - u32 divisor; - - /* disable interrupts */ - UART16550_WRITE(OFS_INTR_ENABLE, 0); - - /* set up buad rate */ - /* set DIAB bit */ - UART16550_WRITE(OFS_LINE_CONTROL, 0x80); - - /* set divisor */ - divisor = MAX_BAUD / baud; - UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); - UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); - - /* clear DIAB bit */ - UART16550_WRITE(OFS_LINE_CONTROL, 0x0); - - /* set data format */ - UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); -} - -static int remoteDebugInitialized; - -u8 getDebugChar(void) -{ - if (!remoteDebugInitialized) { - remoteDebugInitialized = 1; - debugInit(UART16550_BAUD_115200, - UART16550_DATA_8BIT, - UART16550_PARITY_NONE, UART16550_STOP_1BIT); - } - - while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0) ; - return UART16550_READ(OFS_RCV_BUFFER); -} - -int putDebugChar(u8 byte) -{ - if (!remoteDebugInitialized) { - remoteDebugInitialized = 1; - /* - debugInit(UART16550_BAUD_115200, - UART16550_DATA_8BIT, - UART16550_PARITY_NONE, UART16550_STOP_1BIT); */ - } - - while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0) ; - UART16550_WRITE(OFS_SEND_BUFFER, byte); - return 1; -} diff --git a/arch/mips/lemote/lm2e/irq.c b/arch/mips/lemote/lm2e/irq.c deleted file mode 100644 index 1d0a09f3b83..00000000000 --- a/arch/mips/lemote/lm2e/irq.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> - -#include <asm/irq_cpu.h> -#include <asm/i8259.h> -#include <asm/mipsregs.h> -#include <asm/mips-boards/bonito64.h> - - -/* - * the first level int-handler will jump here if it is a bonito irq - */ -static void bonito_irqdispatch(void) -{ - u32 int_status; - int i; - - /* workaround the IO dma problem: let cpu looping to allow DMA finish */ - int_status = BONITO_INTISR; - if (int_status & (1 << 10)) { - while (int_status & (1 << 10)) { - udelay(1); - int_status = BONITO_INTISR; - } - } - - /* Get pending sources, masked by current enables */ - int_status = BONITO_INTISR & BONITO_INTEN; - - if (int_status != 0) { - i = __ffs(int_status); - int_status &= ~(1 << i); - do_IRQ(BONITO_IRQ_BASE + i); - } -} - -static void i8259_irqdispatch(void) -{ - int irq; - - irq = i8259_irq(); - if (irq >= 0) { - do_IRQ(irq); - } else { - spurious_interrupt(); - } - -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; - - if (pending & CAUSEF_IP7) { - do_IRQ(MIPS_CPU_IRQ_BASE + 7); - } else if (pending & CAUSEF_IP5) { - i8259_irqdispatch(); - } else if (pending & CAUSEF_IP2) { - bonito_irqdispatch(); - } else { - spurious_interrupt(); - } -} - -static struct irqaction cascade_irqaction = { - .handler = no_action, - .name = "cascade", -}; - -void __init arch_init_irq(void) -{ - extern void bonito_irq_init(void); - - /* - * Clear all of the interrupts while we change the able around a bit. - * int-handler is not on bootstrap - */ - clear_c0_status(ST0_IM | ST0_BEV); - local_irq_disable(); - - /* most bonito irq should be level triggered */ - BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR | - BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES; - BONITO_INTSTEER = 0; - - /* - * Mask out all interrupt by writing "1" to all bit position in - * the interrupt reset reg. - */ - BONITO_INTENCLR = ~0; - - /* init all controller - * 0-15 ------> i8259 interrupt - * 16-23 ------> mips cpu interrupt - * 32-63 ------> bonito irq - */ - - /* Sets the first-level interrupt dispatcher. */ - mips_cpu_irq_init(); - init_i8259_irqs(); - bonito_irq_init(); - - /* - printk("GPIODATA=%x, GPIOIE=%x\n", BONITO_GPIODATA, BONITO_GPIOIE); - printk("INTEN=%x, INTSET=%x, INTCLR=%x, INTISR=%x\n", - BONITO_INTEN, BONITO_INTENSET, - BONITO_INTENCLR, BONITO_INTISR); - */ - - /* bonito irq at IP2 */ - setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction); - /* 8259 irq at IP5 */ - setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction); - -} diff --git a/arch/mips/lemote/lm2e/pci.c b/arch/mips/lemote/lm2e/pci.c deleted file mode 100644 index 8be03a8e1ad..00000000000 --- a/arch/mips/lemote/lm2e/pci.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * pci.c - * - * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <asm/mips-boards/bonito64.h> -#include <asm/mach-lemote/pci.h> - -extern struct pci_ops bonito64_pci_ops; - -static struct resource loongson2e_pci_mem_resource = { - .name = "LOONGSON2E PCI MEM", - .start = LOONGSON2E_PCI_MEM_START, - .end = LOONGSON2E_PCI_MEM_END, - .flags = IORESOURCE_MEM, -}; - -static struct resource loongson2e_pci_io_resource = { - .name = "LOONGSON2E PCI IO MEM", - .start = LOONGSON2E_PCI_IO_START, - .end = IO_SPACE_LIMIT, - .flags = IORESOURCE_IO, -}; - -static struct pci_controller loongson2e_pci_controller = { - .pci_ops = &bonito64_pci_ops, - .io_resource = &loongson2e_pci_io_resource, - .mem_resource = &loongson2e_pci_mem_resource, - .mem_offset = 0x00000000UL, - .io_offset = 0x00000000UL, -}; - -static void __init ict_pcimap(void) -{ - /* - * local to PCI mapping: [256M,512M] -> [256M,512M]; differ from PMON - * - * CPU address space [256M,448M] is window for accessing pci space - * we set pcimap_lo[0,1,2] to map it to pci space [256M,448M] - * pcimap: bit18,pcimap_2; bit[17-12],lo2;bit[11-6],lo1;bit[5-0],lo0 - */ - /* 1,00 0110 ,0001 01,00 0000 */ - BONITO_PCIMAP = 0x46140; - - /* 1, 00 0010, 0000,01, 00 0000 */ - /* BONITO_PCIMAP = 0x42040; */ - - /* - * PCI to local mapping: [2G,2G+256M] -> [0,256M] - */ - BONITO_PCIBASE0 = 0x80000000; - BONITO_PCIBASE1 = 0x00800000; - BONITO_PCIBASE2 = 0x90000000; - -} - -static int __init pcibios_init(void) -{ - ict_pcimap(); - - loongson2e_pci_controller.io_map_base = - (unsigned long) ioremap(LOONGSON2E_IO_PORT_BASE, - loongson2e_pci_io_resource.end - - loongson2e_pci_io_resource.start + 1); - - register_pci_controller(&loongson2e_pci_controller); - - return 0; -} - -arch_initcall(pcibios_init); diff --git a/arch/mips/lemote/lm2e/prom.c b/arch/mips/lemote/lm2e/prom.c deleted file mode 100644 index 7edc15dfed6..00000000000 --- a/arch/mips/lemote/lm2e/prom.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Based on Ocelot Linux port, which is - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * Copyright 2003 ICT CAS - * Author: Michael Guo <guoyi@ict.ac.cn> - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * 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. - */ -#include <linux/init.h> -#include <linux/bootmem.h> -#include <asm/bootinfo.h> - -extern unsigned long bus_clock; -extern unsigned long cpu_clock_freq; -extern unsigned int memsize, highmemsize; -extern int putDebugChar(unsigned char byte); - -static int argc; -/* pmon passes arguments in 32bit pointers */ -static int *arg; -static int *env; - -const char *get_system_type(void) -{ - return "lemote-fulong"; -} - -void __init prom_init_cmdline(void) -{ - int i; - long l; - - /* arg[0] is "g", the rest is boot parameters */ - arcs_cmdline[0] = '\0'; - for (i = 1; i < argc; i++) { - l = (long)arg[i]; - if (strlen(arcs_cmdline) + strlen(((char *)l) + 1) - >= sizeof(arcs_cmdline)) - break; - strcat(arcs_cmdline, ((char *)l)); - strcat(arcs_cmdline, " "); - } -} - -void __init prom_init(void) -{ - long l; - argc = fw_arg0; - arg = (int *)fw_arg1; - env = (int *)fw_arg2; - - prom_init_cmdline(); - - if ((strstr(arcs_cmdline, "console=")) == NULL) - strcat(arcs_cmdline, " console=ttyS0,115200"); - if ((strstr(arcs_cmdline, "root=")) == NULL) - strcat(arcs_cmdline, " root=/dev/hda1"); - -#define parse_even_earlier(res, option, p) \ -do { \ - if (strncmp(option, (char *)p, strlen(option)) == 0) \ - res = simple_strtol((char *)p + strlen(option"="), \ - NULL, 10); \ -} while (0) - - l = (long)*env; - while (l != 0) { - parse_even_earlier(bus_clock, "busclock", l); - parse_even_earlier(cpu_clock_freq, "cpuclock", l); - parse_even_earlier(memsize, "memsize", l); - parse_even_earlier(highmemsize, "highmemsize", l); - env++; - l = (long)*env; - } - if (memsize == 0) - memsize = 256; - - pr_info("busclock=%ld, cpuclock=%ld,memsize=%d,highmemsize=%d\n", - bus_clock, cpu_clock_freq, memsize, highmemsize); -} - -void __init prom_free_prom_memory(void) -{ -} - -void prom_putchar(char c) -{ - putDebugChar(c); -} diff --git a/arch/mips/lemote/lm2e/reset.c b/arch/mips/lemote/lm2e/reset.c deleted file mode 100644 index 099387a3827..00000000000 --- a/arch/mips/lemote/lm2e/reset.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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. - * - * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - */ -#include <linux/pm.h> - -#include <asm/reboot.h> - -static void loongson2e_restart(char *command) -{ -#ifdef CONFIG_32BIT - *(unsigned long *)0xbfe00104 &= ~(1 << 2); - *(unsigned long *)0xbfe00104 |= (1 << 2); -#else - *(unsigned long *)0xffffffffbfe00104 &= ~(1 << 2); - *(unsigned long *)0xffffffffbfe00104 |= (1 << 2); -#endif - __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); -} - -static void loongson2e_halt(void) -{ - while (1) ; -} - -static void loongson2e_power_off(void) -{ - loongson2e_halt(); -} - -void mips_reboot_setup(void) -{ - _machine_restart = loongson2e_restart; - _machine_halt = loongson2e_halt; - pm_power_off = loongson2e_power_off; -} diff --git a/arch/mips/lemote/lm2e/setup.c b/arch/mips/lemote/lm2e/setup.c deleted file mode 100644 index ebd6ceaef2f..00000000000 --- a/arch/mips/lemote/lm2e/setup.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * setup.c - board dependent boot routines - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#include <linux/bootmem.h> -#include <linux/init.h> -#include <linux/irq.h> - -#include <asm/bootinfo.h> -#include <asm/mc146818-time.h> -#include <asm/time.h> -#include <asm/wbflush.h> -#include <asm/mach-lemote/pci.h> - -#ifdef CONFIG_VT -#include <linux/console.h> -#include <linux/screen_info.h> -#endif - -extern void mips_reboot_setup(void); - -unsigned long cpu_clock_freq; -unsigned long bus_clock; -unsigned int memsize; -unsigned int highmemsize = 0; - -void __init plat_time_init(void) -{ - /* setup mips r4k timer */ - mips_hpt_frequency = cpu_clock_freq / 2; -} - -unsigned long read_persistent_clock(void) -{ - return mc146818_get_cmos_time(); -} - -void (*__wbflush)(void); -EXPORT_SYMBOL(__wbflush); - -static void wbflush_loongson2e(void) -{ - asm(".set\tpush\n\t" - ".set\tnoreorder\n\t" - ".set mips3\n\t" - "sync\n\t" - "nop\n\t" - ".set\tpop\n\t" - ".set mips0\n\t"); -} - -void __init plat_mem_setup(void) -{ - set_io_port_base((unsigned long)ioremap(LOONGSON2E_IO_PORT_BASE, - IO_SPACE_LIMIT - LOONGSON2E_PCI_IO_START + 1)); - mips_reboot_setup(); - - __wbflush = wbflush_loongson2e; - - add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); -#ifdef CONFIG_64BIT - if (highmemsize > 0) { - add_memory_region(0x20000000, highmemsize << 20, BOOT_MEM_RAM); - } -#endif - -#ifdef CONFIG_VT -#if defined(CONFIG_VGA_CONSOLE) - conswitchp = &vga_con; - - screen_info = (struct screen_info) { - 0, 25, /* orig-x, orig-y */ - 0, /* unused */ - 0, /* orig-video-page */ - 0, /* orig-video-mode */ - 80, /* orig-video-cols */ - 0, 0, 0, /* ega_ax, ega_bx, ega_cx */ - 25, /* orig-video-lines */ - VIDEO_TYPE_VGAC, /* orig-video-isVGA */ - 16 /* orig-video-points */ - }; -#elif defined(CONFIG_DUMMY_CONSOLE) - conswitchp = &dummy_con; -#endif -#endif - -} diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig new file mode 100644 index 00000000000..d45092505fa --- /dev/null +++ b/arch/mips/loongson/Kconfig @@ -0,0 +1,31 @@ +choice + prompt "Machine Type" + depends on MACH_LOONGSON + +config LEMOTE_FULOONG2E + bool "Lemote Fuloong(2e) mini-PC" + select ARCH_SPARSEMEM_ENABLE + select CEVT_R4K + select CSRC_R4K + select SYS_HAS_CPU_LOONGSON2E + select DMA_NONCOHERENT + select BOOT_ELF32 + select BOARD_SCACHE + select HW_HAS_PCI + select I8259 + select ISA + select IRQ_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_HAS_EARLY_PRINTK + select GENERIC_HARDIRQS_NO__DO_IRQ + select GENERIC_ISA_DMA_SUPPORT_BROKEN + select CPU_HAS_WB + help + Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and + an FPGA northbridge + + Lemote Fuloong(2e) mini PC have a VIA686B south bridge. +endchoice diff --git a/arch/mips/loongson/Makefile b/arch/mips/loongson/Makefile new file mode 100644 index 00000000000..39048c455d7 --- /dev/null +++ b/arch/mips/loongson/Makefile @@ -0,0 +1,11 @@ +# +# Common code for all Loongson based systems +# + +obj-$(CONFIG_MACH_LOONGSON) += common/ + +# +# Lemote Fuloong mini-PC (Loongson 2E-based) +# + +obj-$(CONFIG_LEMOTE_FULOONG2E) += fuloong-2e/ diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile new file mode 100644 index 00000000000..656b3cc0a2a --- /dev/null +++ b/arch/mips/loongson/common/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for loongson based machines. +# + +obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ + pci.o bonito-irq.o mem.o machtype.o + +# +# Early printk support +# +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o diff --git a/arch/mips/lemote/lm2e/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c index 8fc3bce7075..3e31e7ad713 100644 --- a/arch/mips/lemote/lm2e/bonito-irq.c +++ b/arch/mips/loongson/common/bonito-irq.c @@ -10,32 +10,10 @@ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * */ -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/types.h> #include <linux/interrupt.h> -#include <linux/irq.h> - -#include <asm/mips-boards/bonito64.h> +#include <loongson.h> static inline void bonito_irq_enable(unsigned int irq) { @@ -66,9 +44,8 @@ void bonito_irq_init(void) { u32 i; - for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++) { + for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++) set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq); - } setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction); } diff --git a/arch/mips/loongson/common/cmdline.c b/arch/mips/loongson/common/cmdline.c new file mode 100644 index 00000000000..75f1b243ee4 --- /dev/null +++ b/arch/mips/loongson/common/cmdline.c @@ -0,0 +1,52 @@ +/* + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2003 ICT CAS + * Author: Michael Guo <guoyi@ict.ac.cn> + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ +#include <asm/bootinfo.h> + +#include <loongson.h> + +int prom_argc; +/* pmon passes arguments in 32bit pointers */ +int *_prom_argv; + +void __init prom_init_cmdline(void) +{ + int i; + long l; + + /* firmware arguments are initialized in head.S */ + prom_argc = fw_arg0; + _prom_argv = (int *)fw_arg1; + + /* arg[0] is "g", the rest is boot parameters */ + arcs_cmdline[0] = '\0'; + for (i = 1; i < prom_argc; i++) { + l = (long)_prom_argv[i]; + if (strlen(arcs_cmdline) + strlen(((char *)l) + 1) + >= sizeof(arcs_cmdline)) + break; + strcat(arcs_cmdline, ((char *)l)); + strcat(arcs_cmdline, " "); + } + + if ((strstr(arcs_cmdline, "console=")) == NULL) + strcat(arcs_cmdline, " console=ttyS0,115200"); + if ((strstr(arcs_cmdline, "root=")) == NULL) + strcat(arcs_cmdline, " root=/dev/hda1"); +} diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c new file mode 100644 index 00000000000..bc73edc0cfd --- /dev/null +++ b/arch/mips/loongson/common/early_printk.c @@ -0,0 +1,38 @@ +/* early printk support + * + * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca> + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ +#include <linux/serial_reg.h> + +#include <loongson.h> +#include <machine.h> + +#define PORT(base, offset) (u8 *)(base + offset) + +static inline unsigned int serial_in(phys_addr_t base, int offset) +{ + return readb(PORT(base, offset)); +} + +static inline void serial_out(phys_addr_t base, int offset, int value) +{ + writeb(value, PORT(base, offset)); +} + +void prom_putchar(char c) +{ + phys_addr_t uart_base = + (phys_addr_t) ioremap_nocache(LOONGSON_UART_BASE, 8); + + while ((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) + ; + + serial_out(uart_base, UART_TX, c); +} diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c new file mode 100644 index 00000000000..b9ef5038554 --- /dev/null +++ b/arch/mips/loongson/common/env.c @@ -0,0 +1,58 @@ +/* + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2003 ICT CAS + * Author: Michael Guo <guoyi@ict.ac.cn> + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ +#include <asm/bootinfo.h> + +#include <loongson.h> + +unsigned long bus_clock, cpu_clock_freq; +unsigned long memsize, highmemsize; + +/* pmon passes arguments in 32bit pointers */ +int *_prom_envp; + +#define parse_even_earlier(res, option, p) \ +do { \ + if (strncmp(option, (char *)p, strlen(option)) == 0) \ + strict_strtol((char *)p + strlen(option"="), \ + 10, &res); \ +} while (0) + +void __init prom_init_env(void) +{ + long l; + + /* firmware arguments are initialized in head.S */ + _prom_envp = (int *)fw_arg2; + + l = (long)*_prom_envp; + while (l != 0) { + parse_even_earlier(bus_clock, "busclock", l); + parse_even_earlier(cpu_clock_freq, "cpuclock", l); + parse_even_earlier(memsize, "memsize", l); + parse_even_earlier(highmemsize, "highmemsize", l); + _prom_envp++; + l = (long)*_prom_envp; + } + if (memsize == 0) + memsize = 256; + + pr_info("busclock=%ld, cpuclock=%ld, memsize=%ld, highmemsize=%ld\n", + bus_clock, cpu_clock_freq, memsize, highmemsize); +} diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c new file mode 100644 index 00000000000..3abe927422a --- /dev/null +++ b/arch/mips/loongson/common/init.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include <linux/bootmem.h> + +#include <asm/bootinfo.h> + +#include <loongson.h> + +void __init prom_init(void) +{ + /* init base address of io space */ + set_io_port_base((unsigned long) + ioremap(BONITO_PCIIO_BASE, BONITO_PCIIO_SIZE)); + + prom_init_cmdline(); + prom_init_env(); + prom_init_memory(); +} + +void __init prom_free_prom_memory(void) +{ +} diff --git a/arch/mips/loongson/common/irq.c b/arch/mips/loongson/common/irq.c new file mode 100644 index 00000000000..f368c735cbd --- /dev/null +++ b/arch/mips/loongson/common/irq.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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. + */ +#include <linux/delay.h> +#include <linux/interrupt.h> + +#include <loongson.h> +/* + * the first level int-handler will jump here if it is a bonito irq + */ +void bonito_irqdispatch(void) +{ + u32 int_status; + int i; + + /* workaround the IO dma problem: let cpu looping to allow DMA finish */ + int_status = BONITO_INTISR; + if (int_status & (1 << 10)) { + while (int_status & (1 << 10)) { + udelay(1); + int_status = BONITO_INTISR; + } + } + + /* Get pending sources, masked by current enables */ + int_status = BONITO_INTISR & BONITO_INTEN; + + if (int_status != 0) { + i = __ffs(int_status); + int_status &= ~(1 << i); + do_IRQ(BONITO_IRQ_BASE + i); + } +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending; + + pending = read_c0_cause() & read_c0_status() & ST0_IM; + + /* machine-specific plat_irq_dispatch */ + mach_irq_dispatch(pending); +} + +void __init arch_init_irq(void) +{ + /* + * Clear all of the interrupts while we change the able around a bit. + * int-handler is not on bootstrap + */ + clear_c0_status(ST0_IM | ST0_BEV); + local_irq_disable(); + + /* setting irq trigger mode */ + set_irq_trigger_mode(); + + /* no steer */ + BONITO_INTSTEER = 0; + + /* + * Mask out all interrupt by writing "1" to all bit position in + * the interrupt reset reg. + */ + BONITO_INTENCLR = ~0; + + /* machine specific irq init */ + mach_init_irq(); +} diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c new file mode 100644 index 00000000000..7b348248de7 --- /dev/null +++ b/arch/mips/loongson/common/machtype.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * Copyright (c) 2009 Zhang Le <r0bertz@gentoo.org> + * + * 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. + */ +#include <linux/errno.h> +#include <asm/bootinfo.h> + +#include <loongson.h> +#include <machine.h> + +static const char *system_types[] = { + [MACH_LOONGSON_UNKNOWN] "unknown loongson machine", + [MACH_LEMOTE_FL2E] "lemote-fuloong-2e-box", + [MACH_LEMOTE_FL2F] "lemote-fuloong-2f-box", + [MACH_LEMOTE_ML2F7] "lemote-mengloong-2f-7inches", + [MACH_LEMOTE_YL2F89] "lemote-yeeloong-2f-8.9inches", + [MACH_DEXXON_GDIUM2F10] "dexxon-gidum-2f-10inches", + [MACH_LOONGSON_END] NULL, +}; + +const char *get_system_type(void) +{ + if (mips_machtype == MACH_UNKNOWN) + mips_machtype = LOONGSON_MACHTYPE; + + return system_types[mips_machtype]; +} + +static __init int machtype_setup(char *str) +{ + int machtype = MACH_LEMOTE_FL2E; + + if (!str) + return -EINVAL; + + for (; system_types[machtype]; machtype++) + if (strstr(system_types[machtype], str)) { + mips_machtype = machtype; + break; + } + return 0; +} +__setup("machtype=", machtype_setup); diff --git a/arch/mips/lemote/lm2e/mem.c b/arch/mips/loongson/common/mem.c index 16cd21587d3..7c92f79b648 100644 --- a/arch/mips/lemote/lm2e/mem.c +++ b/arch/mips/loongson/common/mem.c @@ -8,16 +8,28 @@ #include <linux/fcntl.h> #include <linux/mm.h> +#include <asm/bootinfo.h> + +#include <loongson.h> +#include <mem.h> + +void __init prom_init_memory(void) +{ + add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); +#ifdef CONFIG_64BIT + if (highmemsize > 0) + add_memory_region(LOONGSON_HIGHMEM_START, + highmemsize << 20, BOOT_MEM_RAM); +#endif /* CONFIG_64BIT */ +} + /* override of arch/mips/mm/cache.c: __uncached_access */ int __uncached_access(struct file *file, unsigned long addr) { if (file->f_flags & O_SYNC) return 1; - /* - * On the Lemote Loongson 2e system, the peripheral registers - * reside between 0x1000:0000 and 0x2000:0000. - */ return addr >= __pa(high_memory) || - ((addr >= 0x10000000) && (addr < 0x20000000)); + ((addr >= LOONGSON_MMIO_MEM_START) && + (addr < LOONGSON_MMIO_MEM_END)); } diff --git a/arch/mips/loongson/common/pci.c b/arch/mips/loongson/common/pci.c new file mode 100644 index 00000000000..a3a4abfb6c9 --- /dev/null +++ b/arch/mips/loongson/common/pci.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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. + */ +#include <linux/pci.h> + +#include <pci.h> +#include <loongson.h> + +static struct resource loongson_pci_mem_resource = { + .name = "pci memory space", + .start = LOONGSON_PCI_MEM_START, + .end = LOONGSON_PCI_MEM_END, + .flags = IORESOURCE_MEM, +}; + +static struct resource loongson_pci_io_resource = { + .name = "pci io space", + .start = LOONGSON_PCI_IO_START, + .end = IO_SPACE_LIMIT, + .flags = IORESOURCE_IO, +}; + +static struct pci_controller loongson_pci_controller = { + .pci_ops = &bonito64_pci_ops, + .io_resource = &loongson_pci_io_resource, + .mem_resource = &loongson_pci_mem_resource, + .mem_offset = 0x00000000UL, + .io_offset = 0x00000000UL, +}; + +static void __init setup_pcimap(void) +{ + /* + * local to PCI mapping for CPU accessing PCI space + * CPU address space [256M,448M] is window for accessing pci space + * we set pcimap_lo[0,1,2] to map it to pci space[0M,64M], [320M,448M] + * + * pcimap: PCI_MAP2 PCI_Mem_Lo2 PCI_Mem_Lo1 PCI_Mem_Lo0 + * [<2G] [384M,448M] [320M,384M] [0M,64M] + */ + BONITO_PCIMAP = BONITO_PCIMAP_PCIMAP_2 | + BONITO_PCIMAP_WIN(2, BONITO_PCILO2_BASE) | + BONITO_PCIMAP_WIN(1, BONITO_PCILO1_BASE) | + BONITO_PCIMAP_WIN(0, 0); + + /* + * PCI-DMA to local mapping: [2G,2G+256M] -> [0M,256M] + */ + BONITO_PCIBASE0 = 0x80000000ul; /* base: 2G -> mmap: 0M */ + /* size: 256M, burst transmission, pre-fetch enable, 64bit */ + LOONGSON_PCI_HIT0_SEL_L = 0xc000000cul; + LOONGSON_PCI_HIT0_SEL_H = 0xfffffffful; + LOONGSON_PCI_HIT1_SEL_L = 0x00000006ul; /* set this BAR as invalid */ + LOONGSON_PCI_HIT1_SEL_H = 0x00000000ul; + LOONGSON_PCI_HIT2_SEL_L = 0x00000006ul; /* set this BAR as invalid */ + LOONGSON_PCI_HIT2_SEL_H = 0x00000000ul; + + /* avoid deadlock of PCI reading/writing lock operation */ + LOONGSON_PCI_ISR4C = 0xd2000001ul; + + /* can not change gnt to break pci transfer when device's gnt not + deassert for some broken device */ + LOONGSON_PXARB_CFG = 0x00fe0105ul; +} + +static int __init pcibios_init(void) +{ + setup_pcimap(); + + loongson_pci_controller.io_map_base = mips_io_port_base; + + register_pci_controller(&loongson_pci_controller); + + return 0; +} + +arch_initcall(pcibios_init); diff --git a/arch/mips/loongson/common/reset.c b/arch/mips/loongson/common/reset.c new file mode 100644 index 00000000000..97e918251ed --- /dev/null +++ b/arch/mips/loongson/common/reset.c @@ -0,0 +1,44 @@ +/* + * 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. + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Zhangjin Wu, wuzj@lemote.com + */ +#include <linux/init.h> +#include <linux/pm.h> + +#include <asm/reboot.h> + +#include <loongson.h> + +static void loongson_restart(char *command) +{ + /* do preparation for reboot */ + mach_prepare_reboot(); + + /* reboot via jumping to boot base address */ + ((void (*)(void))ioremap_nocache(BONITO_BOOT_BASE, 4)) (); +} + +static void loongson_halt(void) +{ + mach_prepare_shutdown(); + while (1) + ; +} + +static int __init mips_reboot_setup(void) +{ + _machine_restart = loongson_restart; + _machine_halt = loongson_halt; + pm_power_off = loongson_halt; + + return 0; +} + +arch_initcall(mips_reboot_setup); diff --git a/arch/mips/loongson/common/setup.c b/arch/mips/loongson/common/setup.c new file mode 100644 index 00000000000..4cd2aa9a342 --- /dev/null +++ b/arch/mips/loongson/common/setup.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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. + */ +#include <linux/module.h> + +#include <asm/wbflush.h> + +#include <loongson.h> + +#ifdef CONFIG_VT +#include <linux/console.h> +#include <linux/screen_info.h> +#endif + +void (*__wbflush)(void); +EXPORT_SYMBOL(__wbflush); + +static void wbflush_loongson(void) +{ + asm(".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set mips3\n\t" + "sync\n\t" + "nop\n\t" + ".set\tpop\n\t" + ".set mips0\n\t"); +} + +void __init plat_mem_setup(void) +{ + __wbflush = wbflush_loongson; + +#ifdef CONFIG_VT +#if defined(CONFIG_VGA_CONSOLE) + conswitchp = &vga_con; + + screen_info = (struct screen_info) { + 0, 25, /* orig-x, orig-y */ + 0, /* unused */ + 0, /* orig-video-page */ + 0, /* orig-video-mode */ + 80, /* orig-video-cols */ + 0, 0, 0, /* ega_ax, ega_bx, ega_cx */ + 25, /* orig-video-lines */ + VIDEO_TYPE_VGAC, /* orig-video-isVGA */ + 16 /* orig-video-points */ + }; +#elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif +#endif +} diff --git a/arch/mips/loongson/common/time.c b/arch/mips/loongson/common/time.c new file mode 100644 index 00000000000..b13d1717465 --- /dev/null +++ b/arch/mips/loongson/common/time.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ +#include <asm/mc146818-time.h> +#include <asm/time.h> + +#include <loongson.h> + +void __init plat_time_init(void) +{ + /* setup mips r4k timer */ + mips_hpt_frequency = cpu_clock_freq / 2; +} + +unsigned long read_persistent_clock(void) +{ + return mc146818_get_cmos_time(); +} diff --git a/arch/mips/loongson/fuloong-2e/Makefile b/arch/mips/loongson/fuloong-2e/Makefile new file mode 100644 index 00000000000..3aba5fcc09d --- /dev/null +++ b/arch/mips/loongson/fuloong-2e/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for Lemote Fuloong2e mini-PC board. +# + +obj-y += irq.o reset.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/loongson/fuloong-2e/irq.c b/arch/mips/loongson/fuloong-2e/irq.c new file mode 100644 index 00000000000..7888cf69424 --- /dev/null +++ b/arch/mips/loongson/fuloong-2e/irq.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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. + */ +#include <linux/interrupt.h> + +#include <asm/irq_cpu.h> +#include <asm/i8259.h> + +#include <loongson.h> + +static void i8259_irqdispatch(void) +{ + int irq; + + irq = i8259_irq(); + if (irq >= 0) + do_IRQ(irq); + else + spurious_interrupt(); +} + +asmlinkage void mach_irq_dispatch(unsigned int pending) +{ + if (pending & CAUSEF_IP7) + do_IRQ(MIPS_CPU_IRQ_BASE + 7); + else if (pending & CAUSEF_IP6) /* perf counter loverflow */ + do_IRQ(LOONGSON2_PERFCNT_IRQ); + else if (pending & CAUSEF_IP5) + i8259_irqdispatch(); + else if (pending & CAUSEF_IP2) + bonito_irqdispatch(); + else + spurious_interrupt(); +} + +static struct irqaction cascade_irqaction = { + .handler = no_action, + .name = "cascade", +}; + +void __init set_irq_trigger_mode(void) +{ + /* most bonito irq should be level triggered */ + BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR | + BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES; +} + +void __init mach_init_irq(void) +{ + /* init all controller + * 0-15 ------> i8259 interrupt + * 16-23 ------> mips cpu interrupt + * 32-63 ------> bonito irq + */ + + /* Sets the first-level interrupt dispatcher. */ + mips_cpu_irq_init(); + init_i8259_irqs(); + bonito_irq_init(); + + /* bonito irq at IP2 */ + setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction); + /* 8259 irq at IP5 */ + setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction); +} diff --git a/arch/mips/loongson/fuloong-2e/reset.c b/arch/mips/loongson/fuloong-2e/reset.c new file mode 100644 index 00000000000..677fe186db9 --- /dev/null +++ b/arch/mips/loongson/fuloong-2e/reset.c @@ -0,0 +1,23 @@ +/* Board-specific reboot/shutdown routines + * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca> + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include <loongson.h> + +void mach_prepare_reboot(void) +{ + BONITO_BONGENCFG &= ~(1 << 2); + BONITO_BONGENCFG |= (1 << 2); +} + +void mach_prepare_shutdown(void) +{ +} diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c index 7c7148ef264..2877675c5f0 100644 --- a/arch/mips/mipssim/sim_setup.c +++ b/arch/mips/mipssim/sim_setup.c @@ -37,7 +37,7 @@ static void __init serial_init(void); -unsigned int _isbonito = 0; +unsigned int _isbonito; const char *get_system_type(void) { diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index f956ecbb813..e97a7a2fb2c 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -58,11 +58,17 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, * only copy the information from the master page table, * nothing more. */ +#ifdef CONFIG_64BIT +# define VMALLOC_FAULT_TARGET no_context +#else +# define VMALLOC_FAULT_TARGET vmalloc_fault +#endif + if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END)) - goto vmalloc_fault; + goto VMALLOC_FAULT_TARGET; #ifdef MODULE_START if (unlikely(address >= MODULE_START && address < MODULE_END)) - goto vmalloc_fault; + goto VMALLOC_FAULT_TARGET; #endif /* @@ -203,6 +209,7 @@ do_sigbus: force_sig_info(SIGBUS, &info, tsk); return; +#ifndef CONFIG_64BIT vmalloc_fault: { /* @@ -241,4 +248,5 @@ vmalloc_fault: goto no_context; return; } +#endif } diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 0e820508ff2..38c79c55b06 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -475,9 +475,6 @@ unsigned long pgd_current[NR_CPUS]; */ pgd_t swapper_pg_dir[_PTRS_PER_PGD] __page_aligned(_PGD_ORDER); #ifdef CONFIG_64BIT -#ifdef MODULE_START -pgd_t module_pg_dir[PTRS_PER_PGD] __page_aligned(PGD_ORDER); -#endif pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned(PMD_ORDER); #endif pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER); diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c index e4b565aeb00..1121019fa45 100644 --- a/arch/mips/mm/pgtable-64.c +++ b/arch/mips/mm/pgtable-64.c @@ -59,9 +59,6 @@ void __init pagetable_init(void) /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); -#ifdef MODULE_START - pgd_init((unsigned long)module_pg_dir); -#endif pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); pgd_base = swapper_pg_dir; diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index cee502caf39..d73428b18b0 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -475,7 +475,7 @@ static void __cpuinit probe_tlb(unsigned long config) c->tlbsize = ((reg >> 25) & 0x3f) + 1; } -static int __cpuinitdata ntlb = 0; +static int __cpuinitdata ntlb; static int __init set_ntlb(char *str) { get_option(&str, &ntlb); diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 9a17bf8395d..bb1719a55d2 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -321,6 +321,10 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l, case CPU_BCM3302: case CPU_BCM4710: case CPU_LOONGSON2: + case CPU_BCM6338: + case CPU_BCM6345: + case CPU_BCM6348: + case CPU_BCM6358: case CPU_R5500: if (m4kc_tlbp_war()) uasm_i_nop(p); @@ -499,11 +503,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, * The vmalloc handling is not in the hotpath. */ uasm_i_dmfc0(p, tmp, C0_BADVADDR); -#ifdef MODULE_START - uasm_il_bltz(p, r, tmp, label_module_alloc); -#else uasm_il_bltz(p, r, tmp, label_vmalloc); -#endif /* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */ #ifdef CONFIG_SMP @@ -556,52 +556,7 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, { long swpd = (long)swapper_pg_dir; -#ifdef MODULE_START - long modd = (long)module_pg_dir; - - uasm_l_module_alloc(l, *p); - /* - * Assumption: - * VMALLOC_START >= 0xc000000000000000UL - * MODULE_START >= 0xe000000000000000UL - */ - UASM_i_SLL(p, ptr, bvaddr, 2); - uasm_il_bgez(p, r, ptr, label_vmalloc); - - if (uasm_in_compat_space_p(MODULE_START) && - !uasm_rel_lo(MODULE_START)) { - uasm_i_lui(p, ptr, uasm_rel_hi(MODULE_START)); /* delay slot */ - } else { - /* unlikely configuration */ - uasm_i_nop(p); /* delay slot */ - UASM_i_LA(p, ptr, MODULE_START); - } - uasm_i_dsubu(p, bvaddr, bvaddr, ptr); - - if (uasm_in_compat_space_p(modd) && !uasm_rel_lo(modd)) { - uasm_il_b(p, r, label_vmalloc_done); - uasm_i_lui(p, ptr, uasm_rel_hi(modd)); - } else { - UASM_i_LA_mostly(p, ptr, modd); - uasm_il_b(p, r, label_vmalloc_done); - if (uasm_in_compat_space_p(modd)) - uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(modd)); - else - uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(modd)); - } - uasm_l_vmalloc(l, *p); - if (uasm_in_compat_space_p(MODULE_START) && - !uasm_rel_lo(MODULE_START) && - MODULE_START << 32 == VMALLOC_START) - uasm_i_dsll32(p, ptr, ptr, 0); /* typical case */ - else - UASM_i_LA(p, ptr, VMALLOC_START); -#else - uasm_l_vmalloc(l, *p); - UASM_i_LA(p, ptr, VMALLOC_START); -#endif - uasm_i_dsubu(p, bvaddr, bvaddr, ptr); if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) { uasm_il_b(p, r, label_vmalloc_done); diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c index 27c807b67fe..f1b14c8a4a1 100644 --- a/arch/mips/mti-malta/malta-init.c +++ b/arch/mips/mti-malta/malta-init.c @@ -47,7 +47,7 @@ int *_prom_argv, *_prom_envp; */ #define prom_envp(index) ((char *)(long)_prom_envp[(index)]) -int init_debug = 0; +int init_debug; static int mips_revision_corid; int mips_revision_sconid; diff --git a/arch/mips/mti-malta/malta-reset.c b/arch/mips/mti-malta/malta-reset.c index f48d60e8429..32942053624 100644 --- a/arch/mips/mti-malta/malta-reset.c +++ b/arch/mips/mti-malta/malta-reset.c @@ -22,6 +22,7 @@ * Reset the MIPS boards. * */ +#include <linux/init.h> #include <linux/pm.h> #include <asm/io.h> @@ -45,9 +46,13 @@ static void mips_machine_halt(void) } -void mips_reboot_setup(void) +static int __init mips_reboot_setup(void) { _machine_restart = mips_machine_restart; _machine_halt = mips_machine_halt; pm_power_off = mips_machine_halt; + + return 0; } + +arch_initcall(mips_reboot_setup); diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index dc78b8983ee..b7f37d4982f 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c @@ -218,7 +218,6 @@ void __init plat_mem_setup(void) #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) screen_info_setup(); #endif - mips_reboot_setup(); board_be_init = malta_be_init; board_be_handler = malta_be_handler; diff --git a/arch/mips/nxp/pnx833x/stb22x/board.c b/arch/mips/nxp/pnx833x/stb22x/board.c index 90cc604bdad..644eb7c3210 100644 --- a/arch/mips/nxp/pnx833x/stb22x/board.c +++ b/arch/mips/nxp/pnx833x/stb22x/board.c @@ -39,7 +39,7 @@ #define PNX8335_DEBUG7 0x441c int prom_argc; -char **prom_argv = 0, **prom_envp = 0; +char **prom_argv, **prom_envp; extern void prom_init_cmdline(void); extern char *prom_getenv(char *envname); diff --git a/arch/mips/nxp/pnx8550/common/proc.c b/arch/mips/nxp/pnx8550/common/proc.c index acf1fa88944..af094cd1d85 100644 --- a/arch/mips/nxp/pnx8550/common/proc.c +++ b/arch/mips/nxp/pnx8550/common/proc.c @@ -69,9 +69,9 @@ static int pnx8550_registers_read(char* page, char** start, off_t offset, int co return len; } -static struct proc_dir_entry* pnx8550_dir = NULL; -static struct proc_dir_entry* pnx8550_timers = NULL; -static struct proc_dir_entry* pnx8550_registers = NULL; +static struct proc_dir_entry* pnx8550_dir; +static struct proc_dir_entry* pnx8550_timers; +static struct proc_dir_entry* pnx8550_registers; static int pnx8550_proc_init( void ) { diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile index bf3be6fcf7f..02cc65e52d1 100644 --- a/arch/mips/oprofile/Makefile +++ b/arch/mips/oprofile/Makefile @@ -15,3 +15,4 @@ oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o +oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index 3bf3354547f..7832ad257a1 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c @@ -16,6 +16,7 @@ extern struct op_mips_model op_model_mipsxx_ops __attribute__((weak)); extern struct op_mips_model op_model_rm9000_ops __attribute__((weak)); +extern struct op_mips_model op_model_loongson2_ops __attribute__((weak)); static struct op_mips_model *model; @@ -93,6 +94,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) case CPU_RM9000: lmodel = &op_model_rm9000_ops; break; + case CPU_LOONGSON2: + lmodel = &op_model_loongson2_ops; + break; }; if (!lmodel) diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c new file mode 100644 index 00000000000..655cb8dec34 --- /dev/null +++ b/arch/mips/oprofile/op_model_loongson2.c @@ -0,0 +1,177 @@ +/* + * Loongson2 performance counter driver for oprofile + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Yanhua <yanh@lemote.com> + * Author: Wu Zhangjin <wuzj@lemote.com> + * + * 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. + * + */ +#include <linux/init.h> +#include <linux/oprofile.h> +#include <linux/interrupt.h> + +#include <loongson.h> /* LOONGSON2_PERFCNT_IRQ */ +#include "op_impl.h" + +/* + * a patch should be sent to oprofile with the loongson-specific support. + * otherwise, the oprofile tool will not recognize this and complain about + * "cpu_type 'unset' is not valid". + */ +#define LOONGSON2_CPU_TYPE "mips/godson2" + +#define LOONGSON2_COUNTER1_EVENT(event) ((event & 0x0f) << 5) +#define LOONGSON2_COUNTER2_EVENT(event) ((event & 0x0f) << 9) + +#define LOONGSON2_PERFCNT_EXL (1UL << 0) +#define LOONGSON2_PERFCNT_KERNEL (1UL << 1) +#define LOONGSON2_PERFCNT_SUPERVISOR (1UL << 2) +#define LOONGSON2_PERFCNT_USER (1UL << 3) +#define LOONGSON2_PERFCNT_INT_EN (1UL << 4) +#define LOONGSON2_PERFCNT_OVERFLOW (1ULL << 31) + +/* Loongson2 performance counter register */ +#define read_c0_perfctrl() __read_64bit_c0_register($24, 0) +#define write_c0_perfctrl(val) __write_64bit_c0_register($24, 0, val) +#define read_c0_perfcnt() __read_64bit_c0_register($25, 0) +#define write_c0_perfcnt(val) __write_64bit_c0_register($25, 0, val) + +static struct loongson2_register_config { + unsigned int ctrl; + unsigned long long reset_counter1; + unsigned long long reset_counter2; + int cnt1_enalbed, cnt2_enalbed; +} reg; + +DEFINE_SPINLOCK(sample_lock); + +static char *oprofid = "LoongsonPerf"; +static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id); +/* Compute all of the registers in preparation for enabling profiling. */ + +static void loongson2_reg_setup(struct op_counter_config *cfg) +{ + unsigned int ctrl = 0; + + reg.reset_counter1 = 0; + reg.reset_counter2 = 0; + /* Compute the performance counter ctrl word. */ + /* For now count kernel and user mode */ + if (cfg[0].enabled) { + ctrl |= LOONGSON2_COUNTER1_EVENT(cfg[0].event); + reg.reset_counter1 = 0x80000000ULL - cfg[0].count; + } + + if (cfg[1].enabled) { + ctrl |= LOONGSON2_COUNTER2_EVENT(cfg[1].event); + reg.reset_counter2 = (0x80000000ULL - cfg[1].count); + } + + if (cfg[0].enabled || cfg[1].enabled) { + ctrl |= LOONGSON2_PERFCNT_EXL | LOONGSON2_PERFCNT_INT_EN; + if (cfg[0].kernel || cfg[1].kernel) + ctrl |= LOONGSON2_PERFCNT_KERNEL; + if (cfg[0].user || cfg[1].user) + ctrl |= LOONGSON2_PERFCNT_USER; + } + + reg.ctrl = ctrl; + + reg.cnt1_enalbed = cfg[0].enabled; + reg.cnt2_enalbed = cfg[1].enabled; + +} + +/* Program all of the registers in preparation for enabling profiling. */ + +static void loongson2_cpu_setup(void *args) +{ + uint64_t perfcount; + + perfcount = (reg.reset_counter2 << 32) | reg.reset_counter1; + write_c0_perfcnt(perfcount); +} + +static void loongson2_cpu_start(void *args) +{ + /* Start all counters on current CPU */ + if (reg.cnt1_enalbed || reg.cnt2_enalbed) + write_c0_perfctrl(reg.ctrl); +} + +static void loongson2_cpu_stop(void *args) +{ + /* Stop all counters on current CPU */ + write_c0_perfctrl(0); + memset(®, 0, sizeof(reg)); +} + +static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id) +{ + uint64_t counter, counter1, counter2; + struct pt_regs *regs = get_irq_regs(); + int enabled; + unsigned long flags; + + /* + * LOONGSON2 defines two 32-bit performance counters. + * To avoid a race updating the registers we need to stop the counters + * while we're messing with + * them ... + */ + + /* Check whether the irq belongs to me */ + enabled = reg.cnt1_enalbed | reg.cnt2_enalbed; + if (!enabled) + return IRQ_NONE; + + counter = read_c0_perfcnt(); + counter1 = counter & 0xffffffff; + counter2 = counter >> 32; + + spin_lock_irqsave(&sample_lock, flags); + + if (counter1 & LOONGSON2_PERFCNT_OVERFLOW) { + if (reg.cnt1_enalbed) + oprofile_add_sample(regs, 0); + counter1 = reg.reset_counter1; + } + if (counter2 & LOONGSON2_PERFCNT_OVERFLOW) { + if (reg.cnt2_enalbed) + oprofile_add_sample(regs, 1); + counter2 = reg.reset_counter2; + } + + spin_unlock_irqrestore(&sample_lock, flags); + + write_c0_perfcnt((counter2 << 32) | counter1); + + return IRQ_HANDLED; +} + +static int __init loongson2_init(void) +{ + return request_irq(LOONGSON2_PERFCNT_IRQ, loongson2_perfcount_handler, + IRQF_SHARED, "Perfcounter", oprofid); +} + +static void loongson2_exit(void) +{ + write_c0_perfctrl(0); + free_irq(LOONGSON2_PERFCNT_IRQ, oprofid); +} + +struct op_mips_model op_model_loongson2_ops = { + .reg_setup = loongson2_reg_setup, + .cpu_setup = loongson2_cpu_setup, + .init = loongson2_init, + .exit = loongson2_exit, + .cpu_start = loongson2_cpu_start, + .cpu_stop = loongson2_cpu_stop, + .cpu_type = LOONGSON2_CPU_TYPE, + .num_counters = 2 +}; diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 63d8a297c58..91bfe73a7f6 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -16,6 +16,8 @@ obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o obj-$(CONFIG_NEC_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o +obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ + ops-bcm63xx.o # # These are still pretty much in the old state, watch, go blind. @@ -26,7 +28,7 @@ obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o -obj-$(CONFIG_LEMOTE_FULONG) += fixup-lm2e.o ops-bonito64.o +obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-bonito64.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o diff --git a/arch/mips/pci/fixup-bcm63xx.c b/arch/mips/pci/fixup-bcm63xx.c new file mode 100644 index 00000000000..340863009da --- /dev/null +++ b/arch/mips/pci/fixup-bcm63xx.c @@ -0,0 +1,21 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + */ + +#include <linux/types.h> +#include <linux/pci.h> +#include <bcm63xx_cpu.h> + +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + return bcm63xx_get_irq_number(IRQ_PCI); +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} diff --git a/arch/mips/pci/fixup-lm2e.c b/arch/mips/pci/fixup-fuloong2e.c index e18ae4f574c..0c4c7a81213 100644 --- a/arch/mips/pci/fixup-lm2e.c +++ b/arch/mips/pci/fixup-fuloong2e.c @@ -1,6 +1,4 @@ /* - * fixup-lm2e.c - * * Copyright (C) 2004 ICT CAS * Author: Li xiaoyu, ICT CAS * lixy@ict.ac.cn @@ -12,22 +10,6 @@ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * */ #include <linux/init.h> #include <linux/pci.h> diff --git a/arch/mips/pci/ops-bcm63xx.c b/arch/mips/pci/ops-bcm63xx.c new file mode 100644 index 00000000000..822ae179bc5 --- /dev/null +++ b/arch/mips/pci/ops-bcm63xx.c @@ -0,0 +1,467 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + */ + +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/io.h> + +#include "pci-bcm63xx.h" + +/* + * swizzle 32bits data to return only the needed part + */ +static int postprocess_read(u32 data, int where, unsigned int size) +{ + u32 ret; + + ret = 0; + switch (size) { + case 1: + ret = (data >> ((where & 3) << 3)) & 0xff; + break; + case 2: + ret = (data >> ((where & 3) << 3)) & 0xffff; + break; + case 4: + ret = data; + break; + } + return ret; +} + +static int preprocess_write(u32 orig_data, u32 val, int where, + unsigned int size) +{ + u32 ret; + + ret = 0; + switch (size) { + case 1: + ret = (orig_data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + break; + case 2: + ret = (orig_data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + break; + case 4: + ret = val; + break; + } + return ret; +} + +/* + * setup hardware for a configuration cycle with given parameters + */ +static int bcm63xx_setup_cfg_access(int type, unsigned int busn, + unsigned int devfn, int where) +{ + unsigned int slot, func, reg; + u32 val; + + slot = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); + reg = where >> 2; + + /* sanity check */ + if (slot > (MPI_L2PCFG_DEVNUM_MASK >> MPI_L2PCFG_DEVNUM_SHIFT)) + return 1; + + if (func > (MPI_L2PCFG_FUNC_MASK >> MPI_L2PCFG_FUNC_SHIFT)) + return 1; + + if (reg > (MPI_L2PCFG_REG_MASK >> MPI_L2PCFG_REG_SHIFT)) + return 1; + + /* ok, setup config access */ + val = (reg << MPI_L2PCFG_REG_SHIFT); + val |= (func << MPI_L2PCFG_FUNC_SHIFT); + val |= (slot << MPI_L2PCFG_DEVNUM_SHIFT); + val |= MPI_L2PCFG_CFG_USEREG_MASK; + val |= MPI_L2PCFG_CFG_SEL_MASK; + /* type 0 cycle for local bus, type 1 cycle for anything else */ + if (type != 0) { + /* FIXME: how to specify bus ??? */ + val |= (1 << MPI_L2PCFG_CFG_TYPE_SHIFT); + } + bcm_mpi_writel(val, MPI_L2PCFG_REG); + + return 0; +} + +static int bcm63xx_do_cfg_read(int type, unsigned int busn, + unsigned int devfn, int where, int size, + u32 *val) +{ + u32 data; + + /* two phase cycle, first we write address, then read data at + * another location, caller already has a spinlock so no need + * to add one here */ + if (bcm63xx_setup_cfg_access(type, busn, devfn, where)) + return PCIBIOS_DEVICE_NOT_FOUND; + iob(); + data = le32_to_cpu(__raw_readl(pci_iospace_start)); + /* restore IO space normal behaviour */ + bcm_mpi_writel(0, MPI_L2PCFG_REG); + + *val = postprocess_read(data, where, size); + + return PCIBIOS_SUCCESSFUL; +} + +static int bcm63xx_do_cfg_write(int type, unsigned int busn, + unsigned int devfn, int where, int size, + u32 val) +{ + u32 data; + + /* two phase cycle, first we write address, then write data to + * another location, caller already has a spinlock so no need + * to add one here */ + if (bcm63xx_setup_cfg_access(type, busn, devfn, where)) + return PCIBIOS_DEVICE_NOT_FOUND; + iob(); + + data = le32_to_cpu(__raw_readl(pci_iospace_start)); + data = preprocess_write(data, val, where, size); + + __raw_writel(cpu_to_le32(data), pci_iospace_start); + wmb(); + /* no way to know the access is done, we have to wait */ + udelay(500); + /* restore IO space normal behaviour */ + bcm_mpi_writel(0, MPI_L2PCFG_REG); + + return PCIBIOS_SUCCESSFUL; +} + +static int bcm63xx_pci_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + int type; + + type = bus->parent ? 1 : 0; + + if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL) + return PCIBIOS_DEVICE_NOT_FOUND; + + return bcm63xx_do_cfg_read(type, bus->number, devfn, + where, size, val); +} + +static int bcm63xx_pci_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + int type; + + type = bus->parent ? 1 : 0; + + if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL) + return PCIBIOS_DEVICE_NOT_FOUND; + + return bcm63xx_do_cfg_write(type, bus->number, devfn, + where, size, val); +} + +struct pci_ops bcm63xx_pci_ops = { + .read = bcm63xx_pci_read, + .write = bcm63xx_pci_write +}; + +#ifdef CONFIG_CARDBUS +/* + * emulate configuration read access on a cardbus bridge + */ +#define FAKE_CB_BRIDGE_SLOT 0x1e + +static int fake_cb_bridge_bus_number = -1; + +static struct { + u16 pci_command; + u8 cb_latency; + u8 subordinate_busn; + u8 cardbus_busn; + u8 pci_busn; + int bus_assigned; + u16 bridge_control; + + u32 mem_base0; + u32 mem_limit0; + u32 mem_base1; + u32 mem_limit1; + + u32 io_base0; + u32 io_limit0; + u32 io_base1; + u32 io_limit1; +} fake_cb_bridge_regs; + +static int fake_cb_bridge_read(int where, int size, u32 *val) +{ + unsigned int reg; + u32 data; + + data = 0; + reg = where >> 2; + switch (reg) { + case (PCI_VENDOR_ID >> 2): + case (PCI_CB_SUBSYSTEM_VENDOR_ID >> 2): + /* create dummy vendor/device id from our cpu id */ + data = (bcm63xx_get_cpu_id() << 16) | PCI_VENDOR_ID_BROADCOM; + break; + + case (PCI_COMMAND >> 2): + data = (PCI_STATUS_DEVSEL_SLOW << 16); + data |= fake_cb_bridge_regs.pci_command; + break; + + case (PCI_CLASS_REVISION >> 2): + data = (PCI_CLASS_BRIDGE_CARDBUS << 16); + break; + + case (PCI_CACHE_LINE_SIZE >> 2): + data = (PCI_HEADER_TYPE_CARDBUS << 16); + break; + + case (PCI_INTERRUPT_LINE >> 2): + /* bridge control */ + data = (fake_cb_bridge_regs.bridge_control << 16); + /* pin:intA line:0xff */ + data |= (0x1 << 8) | 0xff; + break; + + case (PCI_CB_PRIMARY_BUS >> 2): + data = (fake_cb_bridge_regs.cb_latency << 24); + data |= (fake_cb_bridge_regs.subordinate_busn << 16); + data |= (fake_cb_bridge_regs.cardbus_busn << 8); + data |= fake_cb_bridge_regs.pci_busn; + break; + + case (PCI_CB_MEMORY_BASE_0 >> 2): + data = fake_cb_bridge_regs.mem_base0; + break; + + case (PCI_CB_MEMORY_LIMIT_0 >> 2): + data = fake_cb_bridge_regs.mem_limit0; + break; + + case (PCI_CB_MEMORY_BASE_1 >> 2): + data = fake_cb_bridge_regs.mem_base1; + break; + + case (PCI_CB_MEMORY_LIMIT_1 >> 2): + data = fake_cb_bridge_regs.mem_limit1; + break; + + case (PCI_CB_IO_BASE_0 >> 2): + /* | 1 for 32bits io support */ + data = fake_cb_bridge_regs.io_base0 | 0x1; + break; + + case (PCI_CB_IO_LIMIT_0 >> 2): + data = fake_cb_bridge_regs.io_limit0; + break; + + case (PCI_CB_IO_BASE_1 >> 2): + /* | 1 for 32bits io support */ + data = fake_cb_bridge_regs.io_base1 | 0x1; + break; + + case (PCI_CB_IO_LIMIT_1 >> 2): + data = fake_cb_bridge_regs.io_limit1; + break; + } + + *val = postprocess_read(data, where, size); + return PCIBIOS_SUCCESSFUL; +} + +/* + * emulate configuration write access on a cardbus bridge + */ +static int fake_cb_bridge_write(int where, int size, u32 val) +{ + unsigned int reg; + u32 data, tmp; + int ret; + + ret = fake_cb_bridge_read((where & ~0x3), 4, &data); + if (ret != PCIBIOS_SUCCESSFUL) + return ret; + + data = preprocess_write(data, val, where, size); + + reg = where >> 2; + switch (reg) { + case (PCI_COMMAND >> 2): + fake_cb_bridge_regs.pci_command = (data & 0xffff); + break; + + case (PCI_CB_PRIMARY_BUS >> 2): + fake_cb_bridge_regs.cb_latency = (data >> 24) & 0xff; + fake_cb_bridge_regs.subordinate_busn = (data >> 16) & 0xff; + fake_cb_bridge_regs.cardbus_busn = (data >> 8) & 0xff; + fake_cb_bridge_regs.pci_busn = data & 0xff; + if (fake_cb_bridge_regs.cardbus_busn) + fake_cb_bridge_regs.bus_assigned = 1; + break; + + case (PCI_INTERRUPT_LINE >> 2): + tmp = (data >> 16) & 0xffff; + /* disable memory prefetch support */ + tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM0; + tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1; + fake_cb_bridge_regs.bridge_control = tmp; + break; + + case (PCI_CB_MEMORY_BASE_0 >> 2): + fake_cb_bridge_regs.mem_base0 = data; + break; + + case (PCI_CB_MEMORY_LIMIT_0 >> 2): + fake_cb_bridge_regs.mem_limit0 = data; + break; + + case (PCI_CB_MEMORY_BASE_1 >> 2): + fake_cb_bridge_regs.mem_base1 = data; + break; + + case (PCI_CB_MEMORY_LIMIT_1 >> 2): + fake_cb_bridge_regs.mem_limit1 = data; + break; + + case (PCI_CB_IO_BASE_0 >> 2): + fake_cb_bridge_regs.io_base0 = data; + break; + + case (PCI_CB_IO_LIMIT_0 >> 2): + fake_cb_bridge_regs.io_limit0 = data; + break; + + case (PCI_CB_IO_BASE_1 >> 2): + fake_cb_bridge_regs.io_base1 = data; + break; + + case (PCI_CB_IO_LIMIT_1 >> 2): + fake_cb_bridge_regs.io_limit1 = data; + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int bcm63xx_cb_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + /* snoop access to slot 0x1e on root bus, we fake a cardbus + * bridge at this location */ + if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) { + fake_cb_bridge_bus_number = bus->number; + return fake_cb_bridge_read(where, size, val); + } + + /* a configuration cycle for the device behind the cardbus + * bridge is actually done as a type 0 cycle on the primary + * bus. This means that only one device can be on the cardbus + * bus */ + if (fake_cb_bridge_regs.bus_assigned && + bus->number == fake_cb_bridge_regs.cardbus_busn && + PCI_SLOT(devfn) == 0) + return bcm63xx_do_cfg_read(0, 0, + PCI_DEVFN(CARDBUS_PCI_IDSEL, 0), + where, size, val); + + return PCIBIOS_DEVICE_NOT_FOUND; +} + +static int bcm63xx_cb_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) { + fake_cb_bridge_bus_number = bus->number; + return fake_cb_bridge_write(where, size, val); + } + + if (fake_cb_bridge_regs.bus_assigned && + bus->number == fake_cb_bridge_regs.cardbus_busn && + PCI_SLOT(devfn) == 0) + return bcm63xx_do_cfg_write(0, 0, + PCI_DEVFN(CARDBUS_PCI_IDSEL, 0), + where, size, val); + + return PCIBIOS_DEVICE_NOT_FOUND; +} + +struct pci_ops bcm63xx_cb_ops = { + .read = bcm63xx_cb_read, + .write = bcm63xx_cb_write, +}; + +/* + * only one IO window, so it cannot be shared by PCI and cardbus, use + * fixup to choose and detect unhandled configuration + */ +static void bcm63xx_fixup(struct pci_dev *dev) +{ + static int io_window = -1; + int i, found, new_io_window; + u32 val; + + /* look for any io resource */ + found = 0; + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + if (pci_resource_flags(dev, i) & IORESOURCE_IO) { + found = 1; + break; + } + } + + if (!found) + return; + + /* skip our fake bus with only cardbus bridge on it */ + if (dev->bus->number == fake_cb_bridge_bus_number) + return; + + /* find on which bus the device is */ + if (fake_cb_bridge_regs.bus_assigned && + dev->bus->number == fake_cb_bridge_regs.cardbus_busn && + PCI_SLOT(dev->devfn) == 0) + new_io_window = 1; + else + new_io_window = 0; + + if (new_io_window == io_window) + return; + + if (io_window != -1) { + printk(KERN_ERR "bcm63xx: both PCI and cardbus devices " + "need IO, which hardware cannot do\n"); + return; + } + + printk(KERN_INFO "bcm63xx: PCI IO window assigned to %s\n", + (new_io_window == 0) ? "PCI" : "cardbus"); + + val = bcm_mpi_readl(MPI_L2PIOREMAP_REG); + if (io_window) + val |= MPI_L2PREMAP_IS_CARDBUS_MASK; + else + val &= ~MPI_L2PREMAP_IS_CARDBUS_MASK; + bcm_mpi_writel(val, MPI_L2PIOREMAP_REG); + + io_window = new_io_window; +} + +DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup); +#endif diff --git a/arch/mips/pci/ops-bonito64.c b/arch/mips/pci/ops-bonito64.c index f742c51acf0..54e55e7a243 100644 --- a/arch/mips/pci/ops-bonito64.c +++ b/arch/mips/pci/ops-bonito64.c @@ -29,7 +29,7 @@ #define PCI_ACCESS_READ 0 #define PCI_ACCESS_WRITE 1 -#ifdef CONFIG_LEMOTE_FULONG +#ifdef CONFIG_LEMOTE_FULOONG2E #define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(BONITO_PCICFG_BASE | (offset)) #define ID_SEL_BEGIN 11 #else @@ -77,7 +77,7 @@ static int bonito64_pcibios_config_access(unsigned char access_type, addrp = CFG_SPACE_REG(addr & 0xffff); if (access_type == PCI_ACCESS_WRITE) { writel(cpu_to_le32(*data), addrp); -#ifndef CONFIG_LEMOTE_FULONG +#ifndef CONFIG_LEMOTE_FULOONG2E /* Wait till done */ while (BONITO_PCIMSTAT & 0xF); #endif diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c index a9060c77184..6f5e24c6ae6 100644 --- a/arch/mips/pci/pci-bcm1480.c +++ b/arch/mips/pci/pci-bcm1480.c @@ -57,7 +57,7 @@ static void *cfg_space; #define PCI_BUS_ENABLED 1 #define PCI_DEVICE_MODE 2 -static int bcm1480_bus_status = 0; +static int bcm1480_bus_status; #define PCI_BRIDGE_DEVICE 0 diff --git a/arch/mips/pci/pci-bcm1480ht.c b/arch/mips/pci/pci-bcm1480ht.c index f54f45412b0..50cc6e9e824 100644 --- a/arch/mips/pci/pci-bcm1480ht.c +++ b/arch/mips/pci/pci-bcm1480ht.c @@ -56,7 +56,7 @@ static void *ht_cfg_space; #define PCI_BUS_ENABLED 1 #define PCI_DEVICE_MODE 2 -static int bcm1480ht_bus_status = 0; +static int bcm1480ht_bus_status; #define PCI_BRIDGE_DEVICE 0 #define HT_BRIDGE_DEVICE 1 diff --git a/arch/mips/pci/pci-bcm63xx.c b/arch/mips/pci/pci-bcm63xx.c new file mode 100644 index 00000000000..82e0fde1dba --- /dev/null +++ b/arch/mips/pci/pci-bcm63xx.c @@ -0,0 +1,224 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + */ + +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <asm/bootinfo.h> + +#include "pci-bcm63xx.h" + +/* + * Allow PCI to be disabled at runtime depending on board nvram + * configuration + */ +int bcm63xx_pci_enabled; + +static struct resource bcm_pci_mem_resource = { + .name = "bcm63xx PCI memory space", + .start = BCM_PCI_MEM_BASE_PA, + .end = BCM_PCI_MEM_END_PA, + .flags = IORESOURCE_MEM +}; + +static struct resource bcm_pci_io_resource = { + .name = "bcm63xx PCI IO space", + .start = BCM_PCI_IO_BASE_PA, +#ifdef CONFIG_CARDBUS + .end = BCM_PCI_IO_HALF_PA, +#else + .end = BCM_PCI_IO_END_PA, +#endif + .flags = IORESOURCE_IO +}; + +struct pci_controller bcm63xx_controller = { + .pci_ops = &bcm63xx_pci_ops, + .io_resource = &bcm_pci_io_resource, + .mem_resource = &bcm_pci_mem_resource, +}; + +/* + * We handle cardbus via a fake Cardbus bridge, memory and io spaces + * have to be clearly separated from PCI one since we have different + * memory decoder. + */ +#ifdef CONFIG_CARDBUS +static struct resource bcm_cb_mem_resource = { + .name = "bcm63xx Cardbus memory space", + .start = BCM_CB_MEM_BASE_PA, + .end = BCM_CB_MEM_END_PA, + .flags = IORESOURCE_MEM +}; + +static struct resource bcm_cb_io_resource = { + .name = "bcm63xx Cardbus IO space", + .start = BCM_PCI_IO_HALF_PA + 1, + .end = BCM_PCI_IO_END_PA, + .flags = IORESOURCE_IO +}; + +struct pci_controller bcm63xx_cb_controller = { + .pci_ops = &bcm63xx_cb_ops, + .io_resource = &bcm_cb_io_resource, + .mem_resource = &bcm_cb_mem_resource, +}; +#endif + +static u32 bcm63xx_int_cfg_readl(u32 reg) +{ + u32 tmp; + + tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK; + tmp |= MPI_PCICFGCTL_WRITEEN_MASK; + bcm_mpi_writel(tmp, MPI_PCICFGCTL_REG); + iob(); + return bcm_mpi_readl(MPI_PCICFGDATA_REG); +} + +static void bcm63xx_int_cfg_writel(u32 val, u32 reg) +{ + u32 tmp; + + tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK; + tmp |= MPI_PCICFGCTL_WRITEEN_MASK; + bcm_mpi_writel(tmp, MPI_PCICFGCTL_REG); + bcm_mpi_writel(val, MPI_PCICFGDATA_REG); +} + +void __iomem *pci_iospace_start; + +static int __init bcm63xx_pci_init(void) +{ + unsigned int mem_size; + u32 val; + + if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358()) + return -ENODEV; + + if (!bcm63xx_pci_enabled) + return -ENODEV; + + /* + * configuration access are done through IO space, remap 4 + * first bytes to access it from CPU. + * + * this means that no io access from CPU should happen while + * we do a configuration cycle, but there's no way we can add + * a spinlock for each io access, so this is currently kind of + * broken on SMP. + */ + pci_iospace_start = ioremap_nocache(BCM_PCI_IO_BASE_PA, 4); + if (!pci_iospace_start) + return -ENOMEM; + + /* setup local bus to PCI access (PCI memory) */ + val = BCM_PCI_MEM_BASE_PA & MPI_L2P_BASE_MASK; + bcm_mpi_writel(val, MPI_L2PMEMBASE1_REG); + bcm_mpi_writel(~(BCM_PCI_MEM_SIZE - 1), MPI_L2PMEMRANGE1_REG); + bcm_mpi_writel(val | MPI_L2PREMAP_ENABLED_MASK, MPI_L2PMEMREMAP1_REG); + + /* set Cardbus IDSEL (type 0 cfg access on primary bus for + * this IDSEL will be done on Cardbus instead) */ + val = bcm_pcmcia_readl(PCMCIA_C1_REG); + val &= ~PCMCIA_C1_CBIDSEL_MASK; + val |= (CARDBUS_PCI_IDSEL << PCMCIA_C1_CBIDSEL_SHIFT); + bcm_pcmcia_writel(val, PCMCIA_C1_REG); + +#ifdef CONFIG_CARDBUS + /* setup local bus to PCI access (Cardbus memory) */ + val = BCM_CB_MEM_BASE_PA & MPI_L2P_BASE_MASK; + bcm_mpi_writel(val, MPI_L2PMEMBASE2_REG); + bcm_mpi_writel(~(BCM_CB_MEM_SIZE - 1), MPI_L2PMEMRANGE2_REG); + val |= MPI_L2PREMAP_ENABLED_MASK | MPI_L2PREMAP_IS_CARDBUS_MASK; + bcm_mpi_writel(val, MPI_L2PMEMREMAP2_REG); +#else + /* disable second access windows */ + bcm_mpi_writel(0, MPI_L2PMEMREMAP2_REG); +#endif + + /* setup local bus to PCI access (IO memory), we have only 1 + * IO window for both PCI and cardbus, but it cannot handle + * both at the same time, assume standard PCI for now, if + * cardbus card has IO zone, PCI fixup will change window to + * cardbus */ + val = BCM_PCI_IO_BASE_PA & MPI_L2P_BASE_MASK; + bcm_mpi_writel(val, MPI_L2PIOBASE_REG); + bcm_mpi_writel(~(BCM_PCI_IO_SIZE - 1), MPI_L2PIORANGE_REG); + bcm_mpi_writel(val | MPI_L2PREMAP_ENABLED_MASK, MPI_L2PIOREMAP_REG); + + /* enable PCI related GPIO pins */ + bcm_mpi_writel(MPI_LOCBUSCTL_EN_PCI_GPIO_MASK, MPI_LOCBUSCTL_REG); + + /* setup PCI to local bus access, used by PCI device to target + * local RAM while bus mastering */ + bcm63xx_int_cfg_writel(0, PCI_BASE_ADDRESS_3); + if (BCMCPU_IS_6358()) + val = MPI_SP0_REMAP_ENABLE_MASK; + else + val = 0; + bcm_mpi_writel(val, MPI_SP0_REMAP_REG); + + bcm63xx_int_cfg_writel(0x0, PCI_BASE_ADDRESS_4); + bcm_mpi_writel(0, MPI_SP1_REMAP_REG); + + mem_size = bcm63xx_get_memory_size(); + + /* 6348 before rev b0 exposes only 16 MB of RAM memory through + * PCI, throw a warning if we have more memory */ + if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() & 0xf0) == 0xa0) { + if (mem_size > (16 * 1024 * 1024)) + printk(KERN_WARNING "bcm63xx: this CPU " + "revision cannot handle more than 16MB " + "of RAM for PCI bus mastering\n"); + } else { + /* setup sp0 range to local RAM size */ + bcm_mpi_writel(~(mem_size - 1), MPI_SP0_RANGE_REG); + bcm_mpi_writel(0, MPI_SP1_RANGE_REG); + } + + /* change host bridge retry counter to infinite number of + * retry, needed for some broadcom wifi cards with Silicon + * Backplane bus where access to srom seems very slow */ + val = bcm63xx_int_cfg_readl(BCMPCI_REG_TIMERS); + val &= ~REG_TIMER_RETRY_MASK; + bcm63xx_int_cfg_writel(val, BCMPCI_REG_TIMERS); + + /* enable memory decoder and bus mastering */ + val = bcm63xx_int_cfg_readl(PCI_COMMAND); + val |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + bcm63xx_int_cfg_writel(val, PCI_COMMAND); + + /* enable read prefetching & disable byte swapping for bus + * mastering transfers */ + val = bcm_mpi_readl(MPI_PCIMODESEL_REG); + val &= ~MPI_PCIMODESEL_BAR1_NOSWAP_MASK; + val &= ~MPI_PCIMODESEL_BAR2_NOSWAP_MASK; + val &= ~MPI_PCIMODESEL_PREFETCH_MASK; + val |= (8 << MPI_PCIMODESEL_PREFETCH_SHIFT); + bcm_mpi_writel(val, MPI_PCIMODESEL_REG); + + /* enable pci interrupt */ + val = bcm_mpi_readl(MPI_LOCINT_REG); + val |= MPI_LOCINT_MASK(MPI_LOCINT_EXT_PCI_INT); + bcm_mpi_writel(val, MPI_LOCINT_REG); + + register_pci_controller(&bcm63xx_controller); + +#ifdef CONFIG_CARDBUS + register_pci_controller(&bcm63xx_cb_controller); +#endif + + /* mark memory space used for IO mapping as reserved */ + request_mem_region(BCM_PCI_IO_BASE_PA, BCM_PCI_IO_SIZE, + "bcm63xx PCI IO space"); + return 0; +} + +arch_initcall(bcm63xx_pci_init); diff --git a/arch/mips/pci/pci-bcm63xx.h b/arch/mips/pci/pci-bcm63xx.h new file mode 100644 index 00000000000..a6e594ef3d6 --- /dev/null +++ b/arch/mips/pci/pci-bcm63xx.h @@ -0,0 +1,27 @@ +#ifndef PCI_BCM63XX_H_ +#define PCI_BCM63XX_H_ + +#include <bcm63xx_cpu.h> +#include <bcm63xx_io.h> +#include <bcm63xx_regs.h> +#include <bcm63xx_dev_pci.h> + +/* + * Cardbus shares the PCI bus, but has no IDSEL, so a special id is + * reserved for it. If you have a standard PCI device at this id, you + * need to change the following definition. + */ +#define CARDBUS_PCI_IDSEL 0x8 + +/* + * defined in ops-bcm63xx.c + */ +extern struct pci_ops bcm63xx_pci_ops; +extern struct pci_ops bcm63xx_cb_ops; + +/* + * defined in pci-bcm63xx.c + */ +extern void __iomem *pci_iospace_start; + +#endif /* ! PCI_BCM63XX_H_ */ diff --git a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c index bf639590b8b..ada24e6f951 100644 --- a/arch/mips/pci/pci-sb1250.c +++ b/arch/mips/pci/pci-sb1250.c @@ -58,7 +58,7 @@ static void *cfg_space; #define LDT_BUS_ENABLED 2 #define PCI_DEVICE_MODE 4 -static int sb1250_bus_status = 0; +static int sb1250_bus_status; #define PCI_BRIDGE_DEVICE 0 #define LDT_BRIDGE_DEVICE 1 diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index b0eb9e75c68..9a11c222689 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -31,8 +31,8 @@ unsigned int pci_probe = PCI_ASSIGN_ALL_BUSSES; static struct pci_controller *hose_head, **hose_tail = &hose_head; -unsigned long PCIBIOS_MIN_IO = 0x0000; -unsigned long PCIBIOS_MIN_MEM = 0; +unsigned long PCIBIOS_MIN_IO; +unsigned long PCIBIOS_MIN_MEM; static int pci_initialized; diff --git a/arch/mips/power/hibernate.S b/arch/mips/power/hibernate.S index 4b8174b382d..0cf86fb32ec 100644 --- a/arch/mips/power/hibernate.S +++ b/arch/mips/power/hibernate.S @@ -8,6 +8,7 @@ * Wu Zhangjin <wuzj@lemote.com> */ #include <asm/asm-offsets.h> +#include <asm/page.h> #include <asm/regdef.h> #include <asm/asm.h> @@ -34,7 +35,7 @@ LEAF(swsusp_arch_resume) 0: PTR_L t1, PBE_ADDRESS(t0) /* source */ PTR_L t2, PBE_ORIG_ADDRESS(t0) /* destination */ - PTR_ADDIU t3, t1, _PAGE_SIZE + PTR_ADDIU t3, t1, PAGE_SIZE 1: REG_L t8, (t1) REG_S t8, (t2) diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile index ef1564e40c8..416b18f9fa7 100644 --- a/arch/mips/sgi-ip22/Makefile +++ b/arch/mips/sgi-ip22/Makefile @@ -10,4 +10,4 @@ obj-$(CONFIG_SGI_IP22) += ip22-berr.o obj-$(CONFIG_SGI_IP28) += ip28-berr.o obj-$(CONFIG_EISA) += ip22-eisa.o -# EXTRA_CFLAGS += -Werror +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 7b637a7c0e6..707cfa9c547 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c @@ -341,6 +341,15 @@ static void quirk_slc90e66_ide(struct pci_dev *dev) } #endif /* CONFIG_TOSHIBA_FPCIB0 */ +static void tc35815_fixup(struct pci_dev *dev) +{ + /* This device may have PM registers but not they are not suported. */ + if (dev->pm_cap) { + dev_info(&dev->dev, "PM disabled\n"); + dev->pm_cap = 0; + } +} + static void final_fixup(struct pci_dev *dev) { unsigned char bist; @@ -374,6 +383,10 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, quirk_slc90e66_ide); #endif +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA_2, + PCI_DEVICE_ID_TOSHIBA_TC35815_NWU, tc35815_fixup); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA_2, + PCI_DEVICE_ID_TOSHIBA_TC35815_TX4939, tc35815_fixup); DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, final_fixup); DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, final_fixup); diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index a205e2ba8e7..c860810722c 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -782,7 +782,7 @@ void __init txx9_iocled_init(unsigned long baseaddr, return; iocled->mmioaddr = ioremap(baseaddr, 1); if (!iocled->mmioaddr) - return; + goto out_free; iocled->chip.get = txx9_iocled_get; iocled->chip.set = txx9_iocled_set; iocled->chip.direction_input = txx9_iocled_dir_in; @@ -791,13 +791,13 @@ void __init txx9_iocled_init(unsigned long baseaddr, iocled->chip.base = basenum; iocled->chip.ngpio = num; if (gpiochip_add(&iocled->chip)) - return; + goto out_unmap; if (basenum < 0) basenum = iocled->chip.base; pdev = platform_device_alloc("leds-gpio", basenum); if (!pdev) - return; + goto out_gpio; iocled->pdata.num_leds = num; iocled->pdata.leds = iocled->leds; for (i = 0; i < num; i++) { @@ -812,7 +812,16 @@ void __init txx9_iocled_init(unsigned long baseaddr, } pdev->dev.platform_data = &iocled->pdata; if (platform_device_add(pdev)) - platform_device_put(pdev); + goto out_pdev; + return; +out_pdev: + platform_device_put(pdev); +out_gpio: + gpio_remove(&iocled->chip); +out_unmap: + iounmap(iocled->mmioaddr); +out_free: + kfree(iocled); } #else /* CONFIG_LEDS_GPIO */ void __init txx9_iocled_init(unsigned long baseaddr, diff --git a/arch/sparc/configs/sparc32_defconfig b/arch/sparc/configs/sparc32_defconfig index a0f62a808ed..983d59824a2 100644 --- a/arch/sparc/configs/sparc32_defconfig +++ b/arch/sparc/configs/sparc32_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31-rc1 -# Tue Aug 18 23:45:52 2009 +# Linux kernel version: 2.6.31 +# Wed Sep 16 00:03:43 2009 # # CONFIG_64BIT is not set CONFIG_SPARC=y @@ -39,11 +39,12 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y # # RCU Subsystem # -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set # CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_GROUP_SCHED=y @@ -87,10 +88,12 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_HAVE_PERF_COUNTERS=y # # Performance Counters # +# CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y # CONFIG_STRIP_ASM_SYMS is not set @@ -102,6 +105,8 @@ CONFIG_SLAB=y # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_API_DEBUG=y # # GCOV-based kernel profiling @@ -169,6 +174,7 @@ CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_SUN_PM=y # CONFIG_SPARC_LED is not set CONFIG_SERIAL_CONSOLE=y +# CONFIG_SPARC_LEON is not set # # Bus options (PCI etc.) @@ -259,6 +265,7 @@ CONFIG_IPV6_TUNNEL=m # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -288,6 +295,7 @@ CONFIG_NET_PKTGEN=m # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set +CONFIG_CFG80211_DEFAULT_PS_VALUE=0 CONFIG_WIRELESS_OLD_REGULATORY=y # CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set @@ -295,7 +303,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y # # CFG80211 needs to be enabled for MAC80211 # -CONFIG_MAC80211_DEFAULT_PS_VALUE=0 # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -426,6 +433,7 @@ CONFIG_SCSI_QLOGICPTI=m # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set CONFIG_SCSI_SUNESP=y +# CONFIG_SCSI_PMCRAID is not set # CONFIG_SCSI_SRP is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -524,12 +532,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_SFC is not set # CONFIG_BE2NET is not set # CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_WLAN is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -569,11 +572,11 @@ CONFIG_INPUT_EVBUG=m # CONFIG_INPUT_KEYBOARD=y CONFIG_KEYBOARD_ATKBD=m -CONFIG_KEYBOARD_SUNKBD=m # CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_KEYBOARD_SUNKBD=m +# CONFIG_KEYBOARD_XTKBD is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=m CONFIG_MOUSE_PS2_ALPS=y @@ -581,6 +584,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y CONFIG_MOUSE_PS2_SYNAPTICS=y CONFIG_MOUSE_PS2_TRACKPOINT=y # CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set # CONFIG_MOUSE_PS2_TOUCHKIT is not set CONFIG_MOUSE_SERIAL=m # CONFIG_MOUSE_APPLETOUCH is not set @@ -708,12 +712,10 @@ CONFIG_SSB_POSSIBLE=y # # Console display driver support # -# CONFIG_PROM_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y # CONFIG_SOUND is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set # CONFIG_HID_PID is not set @@ -814,6 +816,7 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_FILE_LOCKING=y CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y @@ -877,7 +880,6 @@ CONFIG_ROMFS_BACKED_BY_BLOCK=y CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set @@ -984,14 +986,17 @@ CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_KGDB=y @@ -1014,7 +1019,6 @@ CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y @@ -1057,11 +1061,13 @@ CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_GHASH is not set CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=m diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig index fdddf7a6f72..f80b881dfea 100644 --- a/arch/sparc/configs/sparc64_defconfig +++ b/arch/sparc/configs/sparc64_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31-rc1 -# Tue Aug 18 23:56:02 2009 +# Linux kernel version: 2.6.31 +# Tue Sep 15 17:06:03 2009 # CONFIG_64BIT=y CONFIG_SPARC=y @@ -19,7 +19,7 @@ CONFIG_LOCKDEP_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_AUDIT_ARCH=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y -CONFIG_HAVE_DYNAMIC_PER_CPU_AREA=y +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_MMU=y CONFIG_ARCH_NO_VIRT_TO_BUS=y @@ -48,11 +48,12 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y # # RCU Subsystem # -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=64 +# CONFIG_RCU_FANOUT_EXACT is not set # CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=18 CONFIG_GROUP_SCHED=y @@ -96,10 +97,13 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_HAVE_PERF_COUNTERS=y # # Performance Counters # +CONFIG_PERF_COUNTERS=y +CONFIG_EVENT_PROFILE=y CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y CONFIG_SLUB_DEBUG=y @@ -119,7 +123,9 @@ CONFIG_KRETPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_HAVE_DMA_API_DEBUG=y # # GCOV-based kernel profiling @@ -317,6 +323,7 @@ CONFIG_IPV6_TUNNEL=m # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -349,6 +356,7 @@ CONFIG_NET_TCPPROBE=m # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set +CONFIG_CFG80211_DEFAULT_PS_VALUE=0 CONFIG_WIRELESS_OLD_REGULATORY=y # CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set @@ -356,7 +364,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y # # CFG80211 needs to be enabled for MAC80211 # -CONFIG_MAC80211_DEFAULT_PS_VALUE=0 # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -549,6 +556,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SUNESP is not set +# CONFIG_SCSI_PMCRAID is not set # CONFIG_SCSI_SRP is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -704,12 +712,7 @@ CONFIG_NIU=m # CONFIG_SFC is not set # CONFIG_BE2NET is not set # CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_WLAN is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -768,11 +771,11 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD=y CONFIG_KEYBOARD_ATKBD=y -CONFIG_KEYBOARD_SUNKBD=y CONFIG_KEYBOARD_LKKBD=m -# CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_KEYBOARD_SUNKBD=y +# CONFIG_KEYBOARD_XTKBD is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y CONFIG_MOUSE_PS2_ALPS=y @@ -780,6 +783,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y CONFIG_MOUSE_PS2_SYNAPTICS=y CONFIG_MOUSE_PS2_TRACKPOINT=y # CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set # CONFIG_MOUSE_PS2_TOUCHKIT is not set CONFIG_MOUSE_SERIAL=y # CONFIG_MOUSE_APPLETOUCH is not set @@ -883,7 +887,6 @@ CONFIG_I2C_ALGOBIT=y # # I2C system bus drivers (mostly embedded / system-on-chip) # -# CONFIG_I2C_DESIGNWARE is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SIMTEC is not set @@ -1102,7 +1105,6 @@ CONFIG_FB_ATY_GX=y # # Console display driver support # -# CONFIG_PROM_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y @@ -1124,6 +1126,7 @@ CONFIG_LOGO=y CONFIG_LOGO_SUN_CLUT224=y CONFIG_SOUND=m CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m @@ -1232,7 +1235,6 @@ CONFIG_SND_SUN_CS4231=m CONFIG_AC97_BUS=m CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set # @@ -1256,6 +1258,7 @@ CONFIG_HID_DRAGONRISE=y CONFIG_HID_EZKEY=y CONFIG_HID_KYE=y CONFIG_HID_GYRATION=y +CONFIG_HID_TWINHAN=y CONFIG_HID_KENSINGTON=y CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set @@ -1289,6 +1292,7 @@ CONFIG_USB=y # # Miscellaneous USB options # +# CONFIG_USB_DEVICEFS is not set # CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set @@ -1379,6 +1383,7 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set # CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set @@ -1493,6 +1498,7 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_FILE_LOCKING=y CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y @@ -1553,7 +1559,6 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set @@ -1656,12 +1661,14 @@ CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set @@ -1692,6 +1699,7 @@ CONFIG_BLK_DEV_IO_TRACE=y # CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_RING_BUFFER_BENCHMARK is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1716,7 +1724,6 @@ CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y @@ -1759,11 +1766,13 @@ CONFIG_CRYPTO_XTS=m # CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=y +# CONFIG_CRYPTO_VMAC is not set # # Digest # CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_GHASH is not set CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=m diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 16a47ffe03c..9be2af55c5c 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -268,8 +268,6 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; -#elif defined(CONFIG_PROM_CONSOLE) - conswitchp = &prom_con; #endif boot_flags_init(*cmdline_p); diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index f2bcfd2967d..21180339cb0 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -295,8 +295,6 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; -#elif defined(CONFIG_PROM_CONSOLE) - conswitchp = &prom_con; #endif idprom_init(); diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index e08ea043e08..42a3f936dad 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -1020,4 +1020,6 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip, extern int get_tsc_mode(unsigned long adr); extern int set_tsc_mode(unsigned int val); +extern int amd_get_nb_id(int cpu); + #endif /* _ASM_X86_PROCESSOR_H */ diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 22a47c82f3c..f32fa71ccf9 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -333,6 +333,16 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c) #endif } +int amd_get_nb_id(int cpu) +{ + int id = 0; +#ifdef CONFIG_SMP + id = per_cpu(cpu_llc_id, cpu); +#endif + return id; +} +EXPORT_SYMBOL_GPL(amd_get_nb_id); + static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c) { #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index ab2fa4eeb36..f2df6e2a224 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -255,6 +255,15 @@ config PATA_ARTOP If unsure, say N. +config PATA_ATP867X + tristate "ARTOP/Acard ATP867X PATA support" + depends on PCI + help + This option enables support for ARTOP/Acard ATP867X PATA + controllers. + + If unsure, say N. + config PATA_AT32 tristate "Atmel AVR32 PATA support (Experimental)" depends on AVR32 && PLATFORM_AT32AP && EXPERIMENTAL diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 463eb52236a..01e126f343b 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_SATA_FSL) += sata_fsl.o obj-$(CONFIG_PATA_ALI) += pata_ali.o obj-$(CONFIG_PATA_AMD) += pata_amd.o obj-$(CONFIG_PATA_ARTOP) += pata_artop.o +obj-$(CONFIG_PATA_ATP867X) += pata_atp867x.o obj-$(CONFIG_PATA_AT32) += pata_at32.o obj-$(CONFIG_PATA_ATIIXP) += pata_atiixp.o obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index d4cd9c20331..acd1162712b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -2930,8 +2930,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (ahci_sb600_32bit_only(pdev)) hpriv->flags |= AHCI_HFLAG_32BIT_ONLY; - if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) - pci_enable_msi(pdev); + if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) + pci_intx(pdev, 1); /* save initial config */ ahci_save_initial_config(pdev, hpriv); diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index df31deac5c8..0ddaf43d68c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5024,8 +5024,6 @@ void ata_qc_complete(struct ata_queued_cmd *qc) struct ata_device *dev = qc->dev; struct ata_eh_info *ehi = &dev->link->eh_info; - WARN_ON_ONCE(ap->pflags & ATA_PFLAG_FROZEN); - if (unlikely(qc->err_mask)) qc->flags |= ATA_QCFLAG_FAILED; @@ -5038,6 +5036,8 @@ void ata_qc_complete(struct ata_queued_cmd *qc) } } + WARN_ON_ONCE(ap->pflags & ATA_PFLAG_FROZEN); + /* read result TF if requested */ if (qc->flags & ATA_QCFLAG_RESULT_TF) fill_result_tf(qc); diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 33a74f11171..567f3f72774 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -307,6 +307,9 @@ static unsigned long nv_mode_filter(struct ata_device *dev, limit |= ATA_MASK_PIO; if (!(limit & (ATA_MASK_MWDMA | ATA_MASK_UDMA))) limit |= ATA_MASK_MWDMA | ATA_MASK_UDMA; + /* PIO4, MWDMA2, UDMA2 should always be supported regardless of + cable detection result */ + limit |= ata_pack_xfermask(ATA_PIO4, ATA_MWDMA2, ATA_UDMA2); ata_port_printk(ap, KERN_DEBUG, "nv_mode_filter: 0x%lx&0x%lx->0x%lx, " "BIOS=0x%lx (0x%x) ACPI=0x%lx%s\n", diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c new file mode 100644 index 00000000000..7990de925d2 --- /dev/null +++ b/drivers/ata/pata_atp867x.c @@ -0,0 +1,548 @@ +/* + * pata_atp867x.c - ARTOP 867X 64bit 4-channel UDMA133 ATA controller driver + * + * (C) 2009 Google Inc. John(Jung-Ik) Lee <jilee@google.com> + * + * Per Atp867 data sheet rev 1.2, Acard. + * Based in part on early ide code from + * 2003-2004 by Eric Uhrhane, Google, 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 + * + * + * TODO: + * 1. RAID features [comparison, XOR, striping, mirroring, etc.] + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/blkdev.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <scsi/scsi_host.h> +#include <linux/libata.h> + +#define DRV_NAME "pata_atp867x" +#define DRV_VERSION "0.7.5" + +/* + * IO Registers + * Note that all runtime hot priv ports are cached in ap private_data + */ + +enum { + ATP867X_IO_CHANNEL_OFFSET = 0x10, + + /* + * IO Register Bitfields + */ + + ATP867X_IO_PIOSPD_ACTIVE_SHIFT = 4, + ATP867X_IO_PIOSPD_RECOVER_SHIFT = 0, + + ATP867X_IO_DMAMODE_MSTR_SHIFT = 0, + ATP867X_IO_DMAMODE_MSTR_MASK = 0x07, + ATP867X_IO_DMAMODE_SLAVE_SHIFT = 4, + ATP867X_IO_DMAMODE_SLAVE_MASK = 0x70, + + ATP867X_IO_DMAMODE_UDMA_6 = 0x07, + ATP867X_IO_DMAMODE_UDMA_5 = 0x06, + ATP867X_IO_DMAMODE_UDMA_4 = 0x05, + ATP867X_IO_DMAMODE_UDMA_3 = 0x04, + ATP867X_IO_DMAMODE_UDMA_2 = 0x03, + ATP867X_IO_DMAMODE_UDMA_1 = 0x02, + ATP867X_IO_DMAMODE_UDMA_0 = 0x01, + ATP867X_IO_DMAMODE_DISABLE = 0x00, + + ATP867X_IO_SYS_INFO_66MHZ = 0x04, + ATP867X_IO_SYS_INFO_SLOW_UDMA5 = 0x02, + ATP867X_IO_SYS_MASK_RESERVED = (~0xf1), + + ATP867X_IO_PORTSPD_VAL = 0x1143, + ATP867X_PREREAD_VAL = 0x0200, + + ATP867X_NUM_PORTS = 4, + ATP867X_BAR_IOBASE = 0, + ATP867X_BAR_ROMBASE = 6, +}; + +#define ATP867X_IOBASE(ap) ((ap)->host->iomap[0]) +#define ATP867X_SYS_INFO(ap) (0x3F + ATP867X_IOBASE(ap)) + +#define ATP867X_IO_PORTBASE(ap, port) (0x00 + ATP867X_IOBASE(ap) + \ + (port) * ATP867X_IO_CHANNEL_OFFSET) +#define ATP867X_IO_DMABASE(ap, port) (0x40 + \ + ATP867X_IO_PORTBASE((ap), (port))) + +#define ATP867X_IO_STATUS(ap, port) (0x07 + \ + ATP867X_IO_PORTBASE((ap), (port))) +#define ATP867X_IO_ALTSTATUS(ap, port) (0x0E + \ + ATP867X_IO_PORTBASE((ap), (port))) + +/* + * hot priv ports + */ +#define ATP867X_IO_MSTRPIOSPD(ap, port) (0x08 + \ + ATP867X_IO_DMABASE((ap), (port))) +#define ATP867X_IO_SLAVPIOSPD(ap, port) (0x09 + \ + ATP867X_IO_DMABASE((ap), (port))) +#define ATP867X_IO_8BPIOSPD(ap, port) (0x0A + \ + ATP867X_IO_DMABASE((ap), (port))) +#define ATP867X_IO_DMAMODE(ap, port) (0x0B + \ + ATP867X_IO_DMABASE((ap), (port))) + +#define ATP867X_IO_PORTSPD(ap, port) (0x4A + \ + ATP867X_IO_PORTBASE((ap), (port))) +#define ATP867X_IO_PREREAD(ap, port) (0x4C + \ + ATP867X_IO_PORTBASE((ap), (port))) + +struct atp867x_priv { + void __iomem *dma_mode; + void __iomem *mstr_piospd; + void __iomem *slave_piospd; + void __iomem *eightb_piospd; + int pci66mhz; +}; + +static inline u8 atp867x_speed_to_mode(u8 speed) +{ + return speed - XFER_UDMA_0 + 1; +} + +static void atp867x_set_dmamode(struct ata_port *ap, struct ata_device *adev) +{ + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + struct atp867x_priv *dp = ap->private_data; + u8 speed = adev->dma_mode; + u8 b; + u8 mode; + + mode = atp867x_speed_to_mode(speed); + + /* + * Doc 6.6.9: decrease the udma mode value by 1 for safer UDMA speed + * on 66MHz bus + * rev-A: UDMA_1~4 (5, 6 no change) + * rev-B: all UDMA modes + * UDMA_0 stays not to disable UDMA + */ + if (dp->pci66mhz && mode > ATP867X_IO_DMAMODE_UDMA_0 && + (pdev->device == PCI_DEVICE_ID_ARTOP_ATP867B || + mode < ATP867X_IO_DMAMODE_UDMA_5)) + mode--; + + b = ioread8(dp->dma_mode); + if (adev->devno & 1) { + b = (b & ~ATP867X_IO_DMAMODE_SLAVE_MASK) | + (mode << ATP867X_IO_DMAMODE_SLAVE_SHIFT); + } else { + b = (b & ~ATP867X_IO_DMAMODE_MSTR_MASK) | + (mode << ATP867X_IO_DMAMODE_MSTR_SHIFT); + } + iowrite8(b, dp->dma_mode); +} + +static int atp867x_get_active_clocks_shifted(unsigned int clk) +{ + unsigned char clocks = clk; + + switch (clocks) { + case 0: + clocks = 1; + break; + case 1 ... 7: + break; + case 8 ... 12: + clocks = 7; + break; + default: + printk(KERN_WARNING "ATP867X: active %dclk is invalid. " + "Using default 8clk.\n", clk); + clocks = 0; /* 8 clk */ + break; + } + return clocks << ATP867X_IO_PIOSPD_ACTIVE_SHIFT; +} + +static int atp867x_get_recover_clocks_shifted(unsigned int clk) +{ + unsigned char clocks = clk; + + switch (clocks) { + case 0: + clocks = 1; + break; + case 1 ... 11: + break; + case 12: + clocks = 0; + break; + case 13: case 14: + --clocks; + break; + case 15: + break; + default: + printk(KERN_WARNING "ATP867X: recover %dclk is invalid. " + "Using default 15clk.\n", clk); + clocks = 0; /* 12 clk */ + break; + } + return clocks << ATP867X_IO_PIOSPD_RECOVER_SHIFT; +} + +static void atp867x_set_piomode(struct ata_port *ap, struct ata_device *adev) +{ + struct ata_device *peer = ata_dev_pair(adev); + struct atp867x_priv *dp = ap->private_data; + u8 speed = adev->pio_mode; + struct ata_timing t, p; + int T, UT; + u8 b; + + T = 1000000000 / 33333; + UT = T / 4; + + ata_timing_compute(adev, speed, &t, T, UT); + if (peer && peer->pio_mode) { + ata_timing_compute(peer, peer->pio_mode, &p, T, UT); + ata_timing_merge(&p, &t, &t, ATA_TIMING_8BIT); + } + + b = ioread8(dp->dma_mode); + if (adev->devno & 1) + b = (b & ~ATP867X_IO_DMAMODE_SLAVE_MASK); + else + b = (b & ~ATP867X_IO_DMAMODE_MSTR_MASK); + iowrite8(b, dp->dma_mode); + + b = atp867x_get_active_clocks_shifted(t.active) | + atp867x_get_recover_clocks_shifted(t.recover); + if (dp->pci66mhz) + b += 0x10; + + if (adev->devno & 1) + iowrite8(b, dp->slave_piospd); + else + iowrite8(b, dp->mstr_piospd); + + /* + * use the same value for comand timing as for PIO timimg + */ + iowrite8(b, dp->eightb_piospd); +} + +static int atp867x_cable_detect(struct ata_port *ap) +{ + return ATA_CBL_PATA40_SHORT; +} + +static struct scsi_host_template atp867x_sht = { + ATA_BMDMA_SHT(DRV_NAME), +}; + +static struct ata_port_operations atp867x_ops = { + .inherits = &ata_bmdma_port_ops, + .cable_detect = atp867x_cable_detect, + .set_piomode = atp867x_set_piomode, + .set_dmamode = atp867x_set_dmamode, +}; + + +#ifdef ATP867X_DEBUG +static void atp867x_check_res(struct pci_dev *pdev) +{ + int i; + unsigned long start, len; + + /* Check the PCI resources for this channel are enabled */ + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + start = pci_resource_start(pdev, i); + len = pci_resource_len(pdev, i); + printk(KERN_DEBUG "ATP867X: resource start:len=%lx:%lx\n", + start, len); + } +} + +static void atp867x_check_ports(struct ata_port *ap, int port) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + struct atp867x_priv *dp = ap->private_data; + + printk(KERN_DEBUG "ATP867X: port[%d] addresses\n" + " cmd_addr =0x%llx, 0x%llx\n" + " ctl_addr =0x%llx, 0x%llx\n" + " bmdma_addr =0x%llx, 0x%llx\n" + " data_addr =0x%llx\n" + " error_addr =0x%llx\n" + " feature_addr =0x%llx\n" + " nsect_addr =0x%llx\n" + " lbal_addr =0x%llx\n" + " lbam_addr =0x%llx\n" + " lbah_addr =0x%llx\n" + " device_addr =0x%llx\n" + " status_addr =0x%llx\n" + " command_addr =0x%llx\n" + " dp->dma_mode =0x%llx\n" + " dp->mstr_piospd =0x%llx\n" + " dp->slave_piospd =0x%llx\n" + " dp->eightb_piospd =0x%llx\n" + " dp->pci66mhz =0x%lx\n", + port, + (unsigned long long)ioaddr->cmd_addr, + (unsigned long long)ATP867X_IO_PORTBASE(ap, port), + (unsigned long long)ioaddr->ctl_addr, + (unsigned long long)ATP867X_IO_ALTSTATUS(ap, port), + (unsigned long long)ioaddr->bmdma_addr, + (unsigned long long)ATP867X_IO_DMABASE(ap, port), + (unsigned long long)ioaddr->data_addr, + (unsigned long long)ioaddr->error_addr, + (unsigned long long)ioaddr->feature_addr, + (unsigned long long)ioaddr->nsect_addr, + (unsigned long long)ioaddr->lbal_addr, + (unsigned long long)ioaddr->lbam_addr, + (unsigned long long)ioaddr->lbah_addr, + (unsigned long long)ioaddr->device_addr, + (unsigned long long)ioaddr->status_addr, + (unsigned long long)ioaddr->command_addr, + (unsigned long long)dp->dma_mode, + (unsigned long long)dp->mstr_piospd, + (unsigned long long)dp->slave_piospd, + (unsigned long long)dp->eightb_piospd, + (unsigned long)dp->pci66mhz); +} +#endif + +static int atp867x_set_priv(struct ata_port *ap) +{ + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + struct atp867x_priv *dp; + int port = ap->port_no; + + dp = ap->private_data = + devm_kzalloc(&pdev->dev, sizeof(*dp), GFP_KERNEL); + if (dp == NULL) + return -ENOMEM; + + dp->dma_mode = ATP867X_IO_DMAMODE(ap, port); + dp->mstr_piospd = ATP867X_IO_MSTRPIOSPD(ap, port); + dp->slave_piospd = ATP867X_IO_SLAVPIOSPD(ap, port); + dp->eightb_piospd = ATP867X_IO_8BPIOSPD(ap, port); + + dp->pci66mhz = + ioread8(ATP867X_SYS_INFO(ap)) & ATP867X_IO_SYS_INFO_66MHZ; + + return 0; +} + +static void atp867x_fixup(struct ata_host *host) +{ + struct pci_dev *pdev = to_pci_dev(host->dev); + struct ata_port *ap = host->ports[0]; + int i; + u8 v; + + /* + * Broken BIOS might not set latency high enough + */ + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &v); + if (v < 0x80) { + v = 0x80; + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, v); + printk(KERN_DEBUG "ATP867X: set latency timer of device %s" + " to %d\n", pci_name(pdev), v); + } + + /* + * init 8bit io ports speed(0aaarrrr) to 43h and + * init udma modes of master/slave to 0/0(11h) + */ + for (i = 0; i < ATP867X_NUM_PORTS; i++) + iowrite16(ATP867X_IO_PORTSPD_VAL, ATP867X_IO_PORTSPD(ap, i)); + + /* + * init PreREAD counts + */ + for (i = 0; i < ATP867X_NUM_PORTS; i++) + iowrite16(ATP867X_PREREAD_VAL, ATP867X_IO_PREREAD(ap, i)); + + v = ioread8(ATP867X_IOBASE(ap) + 0x28); + v &= 0xcf; /* Enable INTA#: bit4=0 means enable */ + v |= 0xc0; /* Enable PCI burst, MRM & not immediate interrupts */ + iowrite8(v, ATP867X_IOBASE(ap) + 0x28); + + /* + * Turn off the over clocked udma5 mode, only for Rev-B + */ + v = ioread8(ATP867X_SYS_INFO(ap)); + v &= ATP867X_IO_SYS_MASK_RESERVED; + if (pdev->device == PCI_DEVICE_ID_ARTOP_ATP867B) + v |= ATP867X_IO_SYS_INFO_SLOW_UDMA5; + iowrite8(v, ATP867X_SYS_INFO(ap)); +} + +static int atp867x_ata_pci_sff_init_host(struct ata_host *host) +{ + struct device *gdev = host->dev; + struct pci_dev *pdev = to_pci_dev(gdev); + unsigned int mask = 0; + int i, rc; + + /* + * do not map rombase + */ + rc = pcim_iomap_regions(pdev, 1 << ATP867X_BAR_IOBASE, DRV_NAME); + if (rc == -EBUSY) + pcim_pin_device(pdev); + if (rc) + return rc; + host->iomap = pcim_iomap_table(pdev); + +#ifdef ATP867X_DEBUG + atp867x_check_res(pdev); + + for (i = 0; i < PCI_ROM_RESOURCE; i++) + printk(KERN_DEBUG "ATP867X: iomap[%d]=0x%llx\n", i, + (unsigned long long)(host->iomap[i])); +#endif + + /* + * request, iomap BARs and init port addresses accordingly + */ + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + struct ata_ioports *ioaddr = &ap->ioaddr; + + ioaddr->cmd_addr = ATP867X_IO_PORTBASE(ap, i); + ioaddr->ctl_addr = ioaddr->altstatus_addr + = ATP867X_IO_ALTSTATUS(ap, i); + ioaddr->bmdma_addr = ATP867X_IO_DMABASE(ap, i); + + ata_sff_std_ports(ioaddr); + rc = atp867x_set_priv(ap); + if (rc) + return rc; + +#ifdef ATP867X_DEBUG + atp867x_check_ports(ap, i); +#endif + ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", + (unsigned long)ioaddr->cmd_addr, + (unsigned long)ioaddr->ctl_addr); + ata_port_desc(ap, "bmdma 0x%lx", + (unsigned long)ioaddr->bmdma_addr); + + mask |= 1 << i; + } + + if (!mask) { + dev_printk(KERN_ERR, gdev, "no available native port\n"); + return -ENODEV; + } + + atp867x_fixup(host); + + rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); + if (rc) + return rc; + + rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); + return rc; +} + +static int atp867x_init_one(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + static int printed_version; + static const struct ata_port_info info_867x = { + .flags = ATA_FLAG_SLAVE_POSS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, + .port_ops = &atp867x_ops, + }; + + struct ata_host *host; + const struct ata_port_info *ppi[] = { &info_867x, NULL }; + int rc; + + if (!printed_version++) + dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); + + rc = pcim_enable_device(pdev); + if (rc) + return rc; + + printk(KERN_INFO "ATP867X: ATP867 ATA UDMA133 controller (rev %02X)", + pdev->device); + + host = ata_host_alloc_pinfo(&pdev->dev, ppi, ATP867X_NUM_PORTS); + if (!host) { + dev_printk(KERN_ERR, &pdev->dev, + "failed to allocate ATA host\n"); + rc = -ENOMEM; + goto err_out; + } + + rc = atp867x_ata_pci_sff_init_host(host); + if (rc) { + dev_printk(KERN_ERR, &pdev->dev, "failed to init host\n"); + goto err_out; + } + + pci_set_master(pdev); + + rc = ata_host_activate(host, pdev->irq, ata_sff_interrupt, + IRQF_SHARED, &atp867x_sht); + if (rc) + dev_printk(KERN_ERR, &pdev->dev, "failed to activate host\n"); + +err_out: + return rc; +} + +static struct pci_device_id atp867x_pci_tbl[] = { + { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867A), 0 }, + { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867B), 0 }, + { }, +}; + +static struct pci_driver atp867x_driver = { + .name = DRV_NAME, + .id_table = atp867x_pci_tbl, + .probe = atp867x_init_one, + .remove = ata_pci_remove_one, +}; + +static int __init atp867x_init(void) +{ + return pci_register_driver(&atp867x_driver); +} + +static void __exit atp867x_exit(void) +{ + pci_unregister_driver(&atp867x_driver); +} + +MODULE_AUTHOR("John(Jung-Ik) Lee, Google Inc."); +MODULE_DESCRIPTION("low level driver for Artop/Acard 867x ATA controller"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(pci, atp867x_pci_tbl); +MODULE_VERSION(DRV_VERSION); + +module_init(atp867x_init); +module_exit(atp867x_exit); diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index b1fd7d62071..07d8d00b4d3 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -56,6 +56,7 @@ enum { /* host register offsets (from host->iomap[PDC_MMIO_BAR]) */ PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */ PDC_FLASH_CTL = 0x44, /* Flash control register */ + PDC_PCI_CTL = 0x48, /* PCI control/status reg */ PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */ PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */ PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */ @@ -75,7 +76,17 @@ enum { PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */ /* per-port SATA register offsets (from ap->ioaddr.scr_addr) */ + PDC_SATA_ERROR = 0x04, PDC_PHYMODE4 = 0x14, + PDC_LINK_LAYER_ERRORS = 0x6C, + PDC_FPDMA_CTLSTAT = 0xD8, + PDC_INTERNAL_DEBUG_1 = 0xF8, /* also used for PATA */ + PDC_INTERNAL_DEBUG_2 = 0xFC, /* also used for PATA */ + + /* PDC_FPDMA_CTLSTAT bit definitions */ + PDC_FPDMA_CTLSTAT_RESET = 1 << 3, + PDC_FPDMA_CTLSTAT_DMASETUP_INT_FLAG = 1 << 10, + PDC_FPDMA_CTLSTAT_SETDB_INT_FLAG = 1 << 11, /* PDC_GLOBAL_CTL bit definitions */ PDC_PH_ERR = (1 << 8), /* PCI error while loading packet */ @@ -195,9 +206,12 @@ static struct ata_port_operations pdc_sata_ops = { .hardreset = pdc_sata_hardreset, }; -/* First-generation chips need a more restrictive ->check_atapi_dma op */ +/* First-generation chips need a more restrictive ->check_atapi_dma op, + and ->freeze/thaw that ignore the hotplug controls. */ static struct ata_port_operations pdc_old_sata_ops = { .inherits = &pdc_sata_ops, + .freeze = pdc_freeze, + .thaw = pdc_thaw, .check_atapi_dma = pdc_old_sata_check_atapi_dma, }; @@ -356,12 +370,76 @@ static int pdc_sata_port_start(struct ata_port *ap) return 0; } +static void pdc_fpdma_clear_interrupt_flag(struct ata_port *ap) +{ + void __iomem *sata_mmio = ap->ioaddr.scr_addr; + u32 tmp; + + tmp = readl(sata_mmio + PDC_FPDMA_CTLSTAT); + tmp |= PDC_FPDMA_CTLSTAT_DMASETUP_INT_FLAG; + tmp |= PDC_FPDMA_CTLSTAT_SETDB_INT_FLAG; + + /* It's not allowed to write to the entire FPDMA_CTLSTAT register + when NCQ is running. So do a byte-sized write to bits 10 and 11. */ + writeb(tmp >> 8, sata_mmio + PDC_FPDMA_CTLSTAT + 1); + readb(sata_mmio + PDC_FPDMA_CTLSTAT + 1); /* flush */ +} + +static void pdc_fpdma_reset(struct ata_port *ap) +{ + void __iomem *sata_mmio = ap->ioaddr.scr_addr; + u8 tmp; + + tmp = (u8)readl(sata_mmio + PDC_FPDMA_CTLSTAT); + tmp &= 0x7F; + tmp |= PDC_FPDMA_CTLSTAT_RESET; + writeb(tmp, sata_mmio + PDC_FPDMA_CTLSTAT); + readl(sata_mmio + PDC_FPDMA_CTLSTAT); /* flush */ + udelay(100); + tmp &= ~PDC_FPDMA_CTLSTAT_RESET; + writeb(tmp, sata_mmio + PDC_FPDMA_CTLSTAT); + readl(sata_mmio + PDC_FPDMA_CTLSTAT); /* flush */ + + pdc_fpdma_clear_interrupt_flag(ap); +} + +static void pdc_not_at_command_packet_phase(struct ata_port *ap) +{ + void __iomem *sata_mmio = ap->ioaddr.scr_addr; + unsigned int i; + u32 tmp; + + /* check not at ASIC packet command phase */ + for (i = 0; i < 100; ++i) { + writel(0, sata_mmio + PDC_INTERNAL_DEBUG_1); + tmp = readl(sata_mmio + PDC_INTERNAL_DEBUG_2); + if ((tmp & 0xF) != 1) + break; + udelay(100); + } +} + +static void pdc_clear_internal_debug_record_error_register(struct ata_port *ap) +{ + void __iomem *sata_mmio = ap->ioaddr.scr_addr; + + writel(0xffffffff, sata_mmio + PDC_SATA_ERROR); + writel(0xffff0000, sata_mmio + PDC_LINK_LAYER_ERRORS); +} + static void pdc_reset_port(struct ata_port *ap) { void __iomem *ata_ctlstat_mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT; unsigned int i; u32 tmp; + if (ap->flags & PDC_FLAG_GEN_II) + pdc_not_at_command_packet_phase(ap); + + tmp = readl(ata_ctlstat_mmio); + tmp |= PDC_RESET; + writel(tmp, ata_ctlstat_mmio); + for (i = 11; i > 0; i--) { tmp = readl(ata_ctlstat_mmio); if (tmp & PDC_RESET) @@ -376,6 +454,11 @@ static void pdc_reset_port(struct ata_port *ap) tmp &= ~PDC_RESET; writel(tmp, ata_ctlstat_mmio); readl(ata_ctlstat_mmio); /* flush */ + + if (sata_scr_valid(&ap->link) && (ap->flags & PDC_FLAG_GEN_II)) { + pdc_fpdma_reset(ap); + pdc_clear_internal_debug_record_error_register(ap); + } } static int pdc_pata_cable_detect(struct ata_port *ap) @@ -626,11 +709,6 @@ static unsigned int pdc_sata_ata_port_to_ata_no(const struct ata_port *ap) return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags)); } -static unsigned int pdc_sata_hotplug_offset(const struct ata_port *ap) -{ - return (ap->flags & PDC_FLAG_GEN_II) ? PDC2_SATA_PLUG_CSR : PDC_SATA_PLUG_CSR; -} - static void pdc_freeze(struct ata_port *ap) { void __iomem *ata_mmio = ap->ioaddr.cmd_addr; @@ -647,7 +725,7 @@ static void pdc_sata_freeze(struct ata_port *ap) { struct ata_host *host = ap->host; void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR]; - unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap); + unsigned int hotplug_offset = PDC2_SATA_PLUG_CSR; unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap); u32 hotplug_status; @@ -685,7 +763,7 @@ static void pdc_sata_thaw(struct ata_port *ap) { struct ata_host *host = ap->host; void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR]; - unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap); + unsigned int hotplug_offset = PDC2_SATA_PLUG_CSR; unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap); u32 hotplug_status; @@ -708,11 +786,50 @@ static int pdc_pata_softreset(struct ata_link *link, unsigned int *class, return ata_sff_softreset(link, class, deadline); } +static unsigned int pdc_ata_port_to_ata_no(const struct ata_port *ap) +{ + void __iomem *ata_mmio = ap->ioaddr.cmd_addr; + void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR]; + + /* ata_mmio == host_mmio + 0x200 + ata_no * 0x80 */ + return (ata_mmio - host_mmio - 0x200) / 0x80; +} + +static void pdc_hard_reset_port(struct ata_port *ap) +{ + void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR]; + void __iomem *pcictl_b1_mmio = host_mmio + PDC_PCI_CTL + 1; + unsigned int ata_no = pdc_ata_port_to_ata_no(ap); + u8 tmp; + + spin_lock(&ap->host->lock); + + tmp = readb(pcictl_b1_mmio); + tmp &= ~(0x10 << ata_no); + writeb(tmp, pcictl_b1_mmio); + readb(pcictl_b1_mmio); /* flush */ + udelay(100); + tmp |= (0x10 << ata_no); + writeb(tmp, pcictl_b1_mmio); + readb(pcictl_b1_mmio); /* flush */ + + spin_unlock(&ap->host->lock); +} + static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline) { + if (link->ap->flags & PDC_FLAG_GEN_II) + pdc_not_at_command_packet_phase(link->ap); + /* hotplug IRQs should have been masked by pdc_sata_freeze() */ + pdc_hard_reset_port(link->ap); pdc_reset_port(link->ap); - return sata_sff_hardreset(link, class, deadline); + + /* sata_promise can't reliably acquire the first D2H Reg FIS + * after hardreset. Do non-waiting hardreset and request + * follow-up SRST. + */ + return sata_std_hardreset(link, class, deadline); } static void pdc_error_handler(struct ata_port *ap) @@ -832,14 +949,14 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) spin_lock(&host->lock); /* read and clear hotplug flags for all ports */ - if (host->ports[0]->flags & PDC_FLAG_GEN_II) + if (host->ports[0]->flags & PDC_FLAG_GEN_II) { hotplug_offset = PDC2_SATA_PLUG_CSR; - else - hotplug_offset = PDC_SATA_PLUG_CSR; - hotplug_status = readl(host_mmio + hotplug_offset); - if (hotplug_status & 0xff) - writel(hotplug_status | 0xff, host_mmio + hotplug_offset); - hotplug_status &= 0xff; /* clear uninteresting bits */ + hotplug_status = readl(host_mmio + hotplug_offset); + if (hotplug_status & 0xff) + writel(hotplug_status | 0xff, host_mmio + hotplug_offset); + hotplug_status &= 0xff; /* clear uninteresting bits */ + } else + hotplug_status = 0; /* reading should also clear interrupts */ mask = readl(host_mmio + PDC_INT_SEQMASK); @@ -1034,9 +1151,11 @@ static void pdc_host_init(struct ata_host *host) tmp = readl(host_mmio + hotplug_offset); writel(tmp | 0xff, host_mmio + hotplug_offset); - /* unmask plug/unplug ints */ tmp = readl(host_mmio + hotplug_offset); - writel(tmp & ~0xff0000, host_mmio + hotplug_offset); + if (is_gen2) /* unmask plug/unplug ints */ + writel(tmp & ~0xff0000, host_mmio + hotplug_offset); + else /* mask plug/unplug ints */ + writel(tmp | 0xff0000, host_mmio + hotplug_offset); /* don't initialise TBG or SLEW on 2nd generation chips */ if (is_gen2) diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index ce66a70184f..87060266ef9 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -126,6 +126,19 @@ config HW_RANDOM_OMAP If unsure, say Y. +config HW_RANDOM_OCTEON + tristate "Octeon Random Number Generator support" + depends on HW_RANDOM && CPU_CAVIUM_OCTEON + default HW_RANDOM + ---help--- + This driver provides kernel-side support for the Random Number + Generator hardware found on Octeon processors. + + To compile this driver as a module, choose M here: the + module will be called octeon-rng. + + If unsure, say Y. + config HW_RANDOM_PASEMI tristate "PA Semi HW Random Number Generator support" depends on HW_RANDOM && PPC_PASEMI diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index 676828ba812..5eeb1303f0d 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o +obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o diff --git a/drivers/char/hw_random/octeon-rng.c b/drivers/char/hw_random/octeon-rng.c new file mode 100644 index 00000000000..54b0d9ba65c --- /dev/null +++ b/drivers/char/hw_random/octeon-rng.c @@ -0,0 +1,147 @@ +/* + * Hardware Random Number Generator support for Cavium Networks + * Octeon processor family. + * + * 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) 2009 Cavium Networks + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/device.h> +#include <linux/hw_random.h> +#include <linux/io.h> + +#include <asm/octeon/octeon.h> +#include <asm/octeon/cvmx-rnm-defs.h> + +struct octeon_rng { + struct hwrng ops; + void __iomem *control_status; + void __iomem *result; +}; + +static int octeon_rng_init(struct hwrng *rng) +{ + union cvmx_rnm_ctl_status ctl; + struct octeon_rng *p = container_of(rng, struct octeon_rng, ops); + + ctl.u64 = 0; + ctl.s.ent_en = 1; /* Enable the entropy source. */ + ctl.s.rng_en = 1; /* Enable the RNG hardware. */ + cvmx_write_csr((u64)p->control_status, ctl.u64); + return 0; +} + +static void octeon_rng_cleanup(struct hwrng *rng) +{ + union cvmx_rnm_ctl_status ctl; + struct octeon_rng *p = container_of(rng, struct octeon_rng, ops); + + ctl.u64 = 0; + /* Disable everything. */ + cvmx_write_csr((u64)p->control_status, ctl.u64); +} + +static int octeon_rng_data_read(struct hwrng *rng, u32 *data) +{ + struct octeon_rng *p = container_of(rng, struct octeon_rng, ops); + + *data = cvmx_read64_uint32((u64)p->result); + return sizeof(u32); +} + +static int __devinit octeon_rng_probe(struct platform_device *pdev) +{ + struct resource *res_ports; + struct resource *res_result; + struct octeon_rng *rng; + int ret; + struct hwrng ops = { + .name = "octeon", + .init = octeon_rng_init, + .cleanup = octeon_rng_cleanup, + .data_read = octeon_rng_data_read + }; + + rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL); + if (!rng) + return -ENOMEM; + + res_ports = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res_ports) + goto err_ports; + + res_result = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res_result) + goto err_ports; + + + rng->control_status = devm_ioremap_nocache(&pdev->dev, + res_ports->start, + sizeof(u64)); + if (!rng->control_status) + goto err_ports; + + rng->result = devm_ioremap_nocache(&pdev->dev, + res_result->start, + sizeof(u64)); + if (!rng->result) + goto err_r; + + rng->ops = ops; + + dev_set_drvdata(&pdev->dev, &rng->ops); + ret = hwrng_register(&rng->ops); + if (ret) + goto err; + + dev_info(&pdev->dev, "Octeon Random Number Generator\n"); + + return 0; +err: + devm_iounmap(&pdev->dev, rng->control_status); +err_r: + devm_iounmap(&pdev->dev, rng->result); +err_ports: + devm_kfree(&pdev->dev, rng); + return -ENOENT; +} + +static int __exit octeon_rng_remove(struct platform_device *pdev) +{ + struct hwrng *rng = dev_get_drvdata(&pdev->dev); + + hwrng_unregister(rng); + + return 0; +} + +static struct platform_driver octeon_rng_driver = { + .driver = { + .name = "octeon_rng", + .owner = THIS_MODULE, + }, + .probe = octeon_rng_probe, + .remove = __exit_p(octeon_rng_remove), +}; + +static int __init octeon_rng_mod_init(void) +{ + return platform_driver_register(&octeon_rng_driver); +} + +static void __exit octeon_rng_mod_exit(void) +{ + platform_driver_unregister(&octeon_rng_driver); +} + +module_init(octeon_rng_mod_init); +module_exit(octeon_rng_mod_exit); + +MODULE_AUTHOR("David Daney"); +MODULE_LICENSE("GPL"); diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 404f4c1ee43..6aa88f50b03 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -2948,9 +2948,6 @@ int __init vty_init(const struct file_operations *console_fops) panic("Couldn't register console driver\n"); kbd_init(); console_map_init(); -#ifdef CONFIG_PROM_CONSOLE - prom_con_init(); -#endif #ifdef CONFIG_MDA_CONSOLE mda_console_init(); #endif diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 4339b1a879c..a3ca18e2d7c 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -59,7 +59,7 @@ config EDAC_MM_EDAC config EDAC_AMD64 tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h" - depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI + depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && CPU_SUP_AMD help Support for error detection and correction on the AMD 64 Families of Memory Controllers (K8, F10h and F11h) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 173dc4a8416..4e551e63b6d 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1255,7 +1255,9 @@ static int k8_dbam_map_to_pages(struct amd64_pvt *pvt, int dram_map) */ static int f10_early_channel_count(struct amd64_pvt *pvt) { + int dbams[] = { DBAM0, DBAM1 }; int err = 0, channels = 0; + int i, j; u32 dbam; err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0); @@ -1288,46 +1290,19 @@ static int f10_early_channel_count(struct amd64_pvt *pvt) * is more than just one DIMM present in unganged mode. Need to check * both controllers since DIMMs can be placed in either one. */ - channels = 0; - err = pci_read_config_dword(pvt->dram_f2_ctl, DBAM0, &dbam); - if (err) - goto err_reg; - - if (DBAM_DIMM(0, dbam) > 0) - channels++; - if (DBAM_DIMM(1, dbam) > 0) - channels++; - if (DBAM_DIMM(2, dbam) > 0) - channels++; - if (DBAM_DIMM(3, dbam) > 0) - channels++; - - /* If more than 2 DIMMs are present, then we have 2 channels */ - if (channels > 2) - channels = 2; - else if (channels == 0) { - /* No DIMMs on DCT0, so look at DCT1 */ - err = pci_read_config_dword(pvt->dram_f2_ctl, DBAM1, &dbam); + for (i = 0; i < ARRAY_SIZE(dbams); i++) { + err = pci_read_config_dword(pvt->dram_f2_ctl, dbams[i], &dbam); if (err) goto err_reg; - if (DBAM_DIMM(0, dbam) > 0) - channels++; - if (DBAM_DIMM(1, dbam) > 0) - channels++; - if (DBAM_DIMM(2, dbam) > 0) - channels++; - if (DBAM_DIMM(3, dbam) > 0) - channels++; - - if (channels > 2) - channels = 2; + for (j = 0; j < 4; j++) { + if (DBAM_DIMM(j, dbam) > 0) { + channels++; + break; + } + } } - /* If we found ALL 0 values, then assume just ONE DIMM-ONE Channel */ - if (channels == 0) - channels = 1; - debugf0("MCT channel count: %d\n", channels); return channels; @@ -2766,30 +2741,53 @@ static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt) wrmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs); } -static void check_mcg_ctl(void *ret) +/* get all cores on this DCT */ +static void get_cpus_on_this_dct_cpumask(cpumask_t *mask, int nid) { - u64 msr_val = 0; - u8 nbe; - - rdmsrl(MSR_IA32_MCG_CTL, msr_val); - nbe = msr_val & K8_MSR_MCGCTL_NBE; - - debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n", - raw_smp_processor_id(), msr_val, - (nbe ? "enabled" : "disabled")); + int cpu; - if (!nbe) - *(int *)ret = 0; + for_each_online_cpu(cpu) + if (amd_get_nb_id(cpu) == nid) + cpumask_set_cpu(cpu, mask); } /* check MCG_CTL on all the cpus on this node */ -static int amd64_mcg_ctl_enabled_on_cpus(const cpumask_t *mask) +static bool amd64_nb_mce_bank_enabled_on_node(int nid) { - int ret = 1; - preempt_disable(); - smp_call_function_many(mask, check_mcg_ctl, &ret, 1); - preempt_enable(); + cpumask_t mask; + struct msr *msrs; + int cpu, nbe, idx = 0; + bool ret = false; + cpumask_clear(&mask); + + get_cpus_on_this_dct_cpumask(&mask, nid); + + msrs = kzalloc(sizeof(struct msr) * cpumask_weight(&mask), GFP_KERNEL); + if (!msrs) { + amd64_printk(KERN_WARNING, "%s: error allocating msrs\n", + __func__); + return false; + } + + rdmsr_on_cpus(&mask, MSR_IA32_MCG_CTL, msrs); + + for_each_cpu(cpu, &mask) { + nbe = msrs[idx].l & K8_MSR_MCGCTL_NBE; + + debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n", + cpu, msrs[idx].q, + (nbe ? "enabled" : "disabled")); + + if (!nbe) + goto out; + + idx++; + } + ret = true; + +out: + kfree(msrs); return ret; } @@ -2799,71 +2797,46 @@ static int amd64_mcg_ctl_enabled_on_cpus(const cpumask_t *mask) * the memory system completely. A command line option allows to force-enable * hardware ECC later in amd64_enable_ecc_error_reporting(). */ +static const char *ecc_warning = + "WARNING: ECC is disabled by BIOS. Module will NOT be loaded.\n" + " Either Enable ECC in the BIOS, or set 'ecc_enable_override'.\n" + " Also, use of the override can cause unknown side effects.\n"; + static int amd64_check_ecc_enabled(struct amd64_pvt *pvt) { u32 value; - int err = 0, ret = 0; + int err = 0; u8 ecc_enabled = 0; + bool nb_mce_en = false; err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCFG, &value); if (err) debugf0("Reading K8_NBCTL failed\n"); ecc_enabled = !!(value & K8_NBCFG_ECC_ENABLE); + if (!ecc_enabled) + amd64_printk(KERN_WARNING, "This node reports that Memory ECC " + "is currently disabled, set F3x%x[22] (%s).\n", + K8_NBCFG, pci_name(pvt->misc_f3_ctl)); + else + amd64_printk(KERN_INFO, "ECC is enabled by BIOS.\n"); - ret = amd64_mcg_ctl_enabled_on_cpus(cpumask_of_node(pvt->mc_node_id)); - - debugf0("K8_NBCFG=0x%x, DRAM ECC is %s\n", value, - (value & K8_NBCFG_ECC_ENABLE ? "enabled" : "disabled")); - - if (!ecc_enabled || !ret) { - if (!ecc_enabled) { - amd64_printk(KERN_WARNING, "This node reports that " - "Memory ECC is currently " - "disabled.\n"); + nb_mce_en = amd64_nb_mce_bank_enabled_on_node(pvt->mc_node_id); + if (!nb_mce_en) + amd64_printk(KERN_WARNING, "NB MCE bank disabled, set MSR " + "0x%08x[4] on node %d to enable.\n", + MSR_IA32_MCG_CTL, pvt->mc_node_id); - amd64_printk(KERN_WARNING, "bit 0x%lx in register " - "F3x%x of the MISC_CONTROL device (%s) " - "should be enabled\n", K8_NBCFG_ECC_ENABLE, - K8_NBCFG, pci_name(pvt->misc_f3_ctl)); - } - if (!ret) { - amd64_printk(KERN_WARNING, "bit 0x%016lx in MSR 0x%08x " - "of node %d should be enabled\n", - K8_MSR_MCGCTL_NBE, MSR_IA32_MCG_CTL, - pvt->mc_node_id); - } + if (!ecc_enabled || !nb_mce_en) { if (!ecc_enable_override) { - amd64_printk(KERN_WARNING, "WARNING: ECC is NOT " - "currently enabled by the BIOS. Module " - "will NOT be loaded.\n" - " Either Enable ECC in the BIOS, " - "or use the 'ecc_enable_override' " - "parameter.\n" - " Might be a BIOS bug, if BIOS says " - "ECC is enabled\n" - " Use of the override can cause " - "unknown side effects.\n"); - ret = -ENODEV; - } else - /* - * enable further driver loading if ECC enable is - * overridden. - */ - ret = 0; - } else { - amd64_printk(KERN_INFO, - "ECC is enabled by BIOS, Proceeding " - "with EDAC module initialization\n"); - - /* Signal good ECC status */ - ret = 0; - + amd64_printk(KERN_WARNING, "%s", ecc_warning); + return -ENODEV; + } + } else /* CLEAR the override, since BIOS controlled it */ ecc_enable_override = 0; - } - return ret; + return 0; } struct mcidev_sysfs_attribute sysfs_attrs[ARRAY_SIZE(amd64_dbg_attrs) + diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c index c8ca7136dac..0c21c370c9d 100644 --- a/drivers/edac/edac_mce_amd.c +++ b/drivers/edac/edac_mce_amd.c @@ -405,7 +405,7 @@ void decode_mce(struct mce *m) regs.nbsh = (u32)(m->status >> 32); regs.nbeal = (u32) m->addr; regs.nbeah = (u32)(m->addr >> 32); - node = per_cpu(cpu_llc_id, m->extcpu); + node = amd_get_nb_id(m->extcpu); amd_decode_nb_mce(node, ®s, 1); break; diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 2e25b7a827d..461abb1e273 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -28,6 +28,17 @@ config HWMON_VID tristate default n +config HWMON_DEBUG_CHIP + bool "Hardware Monitoring Chip debugging messages" + default n + help + Say Y here if you want the I2C chip drivers to produce a bunch of + debug messages to the system log. Select this if you are having + a problem with I2C support and want to see more of what is going + on. + +comment "Native drivers" + config SENSORS_ABITUGURU tristate "Abit uGuru (rev 1 & 2)" depends on X86 && EXPERIMENTAL @@ -248,18 +259,6 @@ config SENSORS_ASB100 This driver can also be built as a module. If so, the module will be called asb100. -config SENSORS_ATK0110 - tristate "ASUS ATK0110 ACPI hwmon" - depends on X86 && ACPI && EXPERIMENTAL - help - If you say yes here you get support for the ACPI hardware - monitoring interface found in many ASUS motherboards. This - driver will provide readings of fans, voltages and temperatures - through the system firmware. - - This driver can also be built as a module. If so, the module - will be called asus_atk0110. - config SENSORS_ATXP1 tristate "Attansic ATXP1 VID controller" depends on I2C && EXPERIMENTAL @@ -814,6 +813,16 @@ config SENSORS_TMP401 This driver can also be built as a module. If so, the module will be called tmp401. +config SENSORS_TMP421 + tristate "Texas Instruments TMP421 and compatible" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for Texas Instruments TMP421, + TMP422 and TMP423 temperature sensor chips. + + This driver can also be built as a module. If so, the module + will be called tmp421. + config SENSORS_VIA686A tristate "VIA686A" depends on PCI @@ -964,34 +973,6 @@ config SENSORS_HDAPS Say Y here if you have an applicable laptop and want to experience the awesome power of hdaps. -config SENSORS_LIS3LV02D - tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer" - depends on ACPI && INPUT - select INPUT_POLLDEV - select NEW_LEDS - select LEDS_CLASS - default n - help - This driver provides support for the LIS3LV02Dx accelerometer. In - particular, it can be found in a number of HP laptops, which have the - "Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such - systems the driver should load automatically (via ACPI). The - accelerometer might also be found in other systems, connected via SPI - or I2C. The accelerometer data is readable via - /sys/devices/platform/lis3lv02d. - - This driver also provides an absolute input class device, allowing - the laptop to act as a pinball machine-esque joystick. On HP laptops, - if the led infrastructure is activated, support for a led indicating - disk protection will be provided as hp:red:hddprotection. - - This driver can also be built as modules. If so, the core module - will be called lis3lv02d and a specific module for HP laptops will be - called hp_accel. - - Say Y here if you have an applicable laptop and want to experience - the awesome power of lis3lv02d. - config SENSORS_LIS3_SPI tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)" depends on !ACPI && SPI_MASTER && INPUT @@ -1034,13 +1015,50 @@ config SENSORS_APPLESMC Say Y here if you have an applicable laptop and want to experience the awesome power of applesmc. -config HWMON_DEBUG_CHIP - bool "Hardware Monitoring Chip debugging messages" +if ACPI + +comment "ACPI drivers" + +config SENSORS_ATK0110 + tristate "ASUS ATK0110" + depends on X86 && EXPERIMENTAL + help + If you say yes here you get support for the ACPI hardware + monitoring interface found in many ASUS motherboards. This + driver will provide readings of fans, voltages and temperatures + through the system firmware. + + This driver can also be built as a module. If so, the module + will be called asus_atk0110. + +config SENSORS_LIS3LV02D + tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer" + depends on INPUT + select INPUT_POLLDEV + select NEW_LEDS + select LEDS_CLASS default n help - Say Y here if you want the I2C chip drivers to produce a bunch of - debug messages to the system log. Select this if you are having - a problem with I2C support and want to see more of what is going - on. + This driver provides support for the LIS3LV02Dx accelerometer. In + particular, it can be found in a number of HP laptops, which have the + "Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such + systems the driver should load automatically (via ACPI). The + accelerometer might also be found in other systems, connected via SPI + or I2C. The accelerometer data is readable via + /sys/devices/platform/lis3lv02d. + + This driver also provides an absolute input class device, allowing + the laptop to act as a pinball machine-esque joystick. On HP laptops, + if the led infrastructure is activated, support for a led indicating + disk protection will be provided as hp:red:hddprotection. + + This driver can also be built as modules. If so, the core module + will be called lis3lv02d and a specific module for HP laptops will be + called hp_accel. + + Say Y here if you have an applicable laptop and want to experience + the awesome power of lis3lv02d. + +endif # ACPI endif # HWMON diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 7f239a247c3..2e547881bc0 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -5,6 +5,10 @@ obj-$(CONFIG_HWMON) += hwmon.o obj-$(CONFIG_HWMON_VID) += hwmon-vid.o +# APCI drivers +obj-$(CONFIG_SENSORS_ATK0110) += asus_atk0110.o + +# Native drivers # asb100, then w83781d go first, as they can override other drivers' addresses. obj-$(CONFIG_SENSORS_ASB100) += asb100.o obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o @@ -29,10 +33,8 @@ obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o - obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o obj-$(CONFIG_SENSORS_AMS) += ams/ -obj-$(CONFIG_SENSORS_ATK0110) += asus_atk0110.o obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o obj-$(CONFIG_SENSORS_DME1737) += dme1737.o @@ -84,6 +86,7 @@ obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o obj-$(CONFIG_SENSORS_THMC50) += thmc50.o obj-$(CONFIG_SENSORS_TMP401) += tmp401.o +obj-$(CONFIG_SENSORS_TMP421) += tmp421.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o obj-$(CONFIG_SENSORS_VT1211) += vt1211.o obj-$(CONFIG_SENSORS_VT8231) += vt8231.o diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index 4dbdb81ea3b..03694cc17a3 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c @@ -32,7 +32,7 @@ #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> #include <linux/dmi.h> -#include <asm/io.h> +#include <linux/io.h> /* Banks */ #define ABIT_UGURU_ALARM_BANK 0x20 /* 1x 3 bytes */ diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index 7d3f15d32fd..3cf28af614b 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c @@ -34,7 +34,7 @@ #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> #include <linux/dmi.h> -#include <asm/io.h> +#include <linux/io.h> /* uGuru3 bank addresses */ #define ABIT_UGURU3_SETTINGS_BANK 0x01 @@ -117,9 +117,12 @@ struct abituguru3_sensor_info { int offset; }; +/* Avoid use of flexible array members */ +#define ABIT_UGURU3_MAX_DMI_NAMES 2 + struct abituguru3_motherboard_info { u16 id; - const char *dmi_name; + const char *dmi_name[ABIT_UGURU3_MAX_DMI_NAMES + 1]; /* + 1 -> end of sensors indicated by a sensor with name == NULL */ struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1]; }; @@ -164,7 +167,7 @@ struct abituguru3_data { /* Constants */ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { - { 0x000C, NULL /* Unknown, need DMI string */, { + { 0x000C, { NULL } /* Unknown, need DMI string */, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR", 1, 0, 10, 1, 0 }, { "DDR VTT", 2, 0, 10, 1, 0 }, @@ -186,7 +189,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX1 Fan", 35, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x000D, NULL /* Abit AW8, need DMI string */, { + { 0x000D, { NULL } /* Abit AW8, need DMI string */, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR", 1, 0, 10, 1, 0 }, { "DDR VTT", 2, 0, 10, 1, 0 }, @@ -215,7 +218,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX5 Fan", 39, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x000E, NULL /* AL-8, need DMI string */, { + { 0x000E, { NULL } /* AL-8, need DMI string */, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR", 1, 0, 10, 1, 0 }, { "DDR VTT", 2, 0, 10, 1, 0 }, @@ -236,7 +239,8 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "SYS Fan", 34, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x000F, NULL /* Unknown, need DMI string */, { + { 0x000F, { NULL } /* Unknown, need DMI string */, { + { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR", 1, 0, 10, 1, 0 }, { "DDR VTT", 2, 0, 10, 1, 0 }, @@ -257,7 +261,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "SYS Fan", 34, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0010, NULL /* Abit NI8 SLI GR, need DMI string */, { + { 0x0010, { NULL } /* Abit NI8 SLI GR, need DMI string */, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR", 1, 0, 10, 1, 0 }, { "DDR VTT", 2, 0, 10, 1, 0 }, @@ -279,7 +283,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "OTES1 Fan", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0011, "AT8 32X", { + { 0x0011, { "AT8 32X", NULL }, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR", 1, 0, 20, 1, 0 }, { "DDR VTT", 2, 0, 10, 1, 0 }, @@ -306,7 +310,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX3 Fan", 37, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0012, NULL /* Abit AN8 32X, need DMI string */, { + { 0x0012, { NULL } /* Abit AN8 32X, need DMI string */, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR", 1, 0, 20, 1, 0 }, { "DDR VTT", 2, 0, 10, 1, 0 }, @@ -328,7 +332,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX1 Fan", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0013, NULL /* Abit AW8D, need DMI string */, { + { 0x0013, { NULL } /* Abit AW8D, need DMI string */, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR", 1, 0, 10, 1, 0 }, { "DDR VTT", 2, 0, 10, 1, 0 }, @@ -357,7 +361,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX5 Fan", 39, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0014, "AB9", /* + AB9 Pro */ { + { 0x0014, { "AB9", "AB9 Pro", NULL }, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR", 1, 0, 10, 1, 0 }, { "DDR VTT", 2, 0, 10, 1, 0 }, @@ -378,7 +382,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "SYS Fan", 34, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0015, NULL /* Unknown, need DMI string */, { + { 0x0015, { NULL } /* Unknown, need DMI string */, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR", 1, 0, 20, 1, 0 }, { "DDR VTT", 2, 0, 10, 1, 0 }, @@ -402,7 +406,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX3 Fan", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0016, "AW9D-MAX", { + { 0x0016, { "AW9D-MAX", NULL }, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR2", 1, 0, 20, 1, 0 }, { "DDR2 VTT", 2, 0, 10, 1, 0 }, @@ -430,7 +434,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "OTES1 Fan", 38, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0017, NULL /* Unknown, need DMI string */, { + { 0x0017, { NULL } /* Unknown, need DMI string */, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR2", 1, 0, 20, 1, 0 }, { "DDR2 VTT", 2, 0, 10, 1, 0 }, @@ -455,7 +459,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX3 FAN", 37, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0018, "AB9 QuadGT", { + { 0x0018, { "AB9 QuadGT", NULL }, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR2", 1, 0, 20, 1, 0 }, { "DDR2 VTT", 2, 0, 10, 1, 0 }, @@ -482,7 +486,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX3 Fan", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0019, "IN9 32X MAX", { + { 0x0019, { "IN9 32X MAX", NULL }, { { "CPU Core", 7, 0, 10, 1, 0 }, { "DDR2", 13, 0, 20, 1, 0 }, { "DDR2 VTT", 14, 0, 10, 1, 0 }, @@ -509,7 +513,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX3 FAN", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x001A, "IP35 Pro", { + { 0x001A, { "IP35 Pro", "IP35 Pro XE", NULL }, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR2", 1, 0, 20, 1, 0 }, { "DDR2 VTT", 2, 0, 10, 1, 0 }, @@ -537,7 +541,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX4 Fan", 37, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x001B, NULL /* Unknown, need DMI string */, { + { 0x001B, { NULL } /* Unknown, need DMI string */, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR3", 1, 0, 20, 1, 0 }, { "DDR3 VTT", 2, 0, 10, 1, 0 }, @@ -564,7 +568,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX3 Fan", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x001C, "IX38 QuadGT", { + { 0x001C, { "IX38 QuadGT", NULL }, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR2", 1, 0, 20, 1, 0 }, { "DDR2 VTT", 2, 0, 10, 1, 0 }, @@ -591,7 +595,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX3 Fan", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0000, NULL, { { NULL, 0, 0, 0, 0, 0 } } } + { 0x0000, { NULL }, { { NULL, 0, 0, 0, 0, 0 } } } }; @@ -946,15 +950,6 @@ static int __devinit abituguru3_probe(struct platform_device *pdev) printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard " "ID: %04X\n", (unsigned int)id); -#ifdef CONFIG_DMI - if (!abituguru3_motherboards[i].dmi_name) { - printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was " - "not detected using DMI. Please send the output of " - "\"dmidecode\" to the abituguru3 maintainer " - "(see MAINTAINERS)\n"); - } -#endif - /* Fill the sysfs attr array */ sysfs_attr_i = 0; sysfs_filename = data->sysfs_names; @@ -1131,6 +1126,7 @@ static int __init abituguru3_dmi_detect(void) { const char *board_vendor, *board_name; int i, err = (force) ? 1 : -ENODEV; + const char *const *dmi_name; size_t sublen; board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); @@ -1151,17 +1147,17 @@ static int __init abituguru3_dmi_detect(void) sublen--; for (i = 0; abituguru3_motherboards[i].id; i++) { - const char *dmi_name = abituguru3_motherboards[i].dmi_name; - if (!dmi_name || strlen(dmi_name) != sublen) - continue; - if (!strncasecmp(board_name, dmi_name, sublen)) - break; + dmi_name = abituguru3_motherboards[i].dmi_name; + for ( ; *dmi_name; dmi_name++) { + if (strlen(*dmi_name) != sublen) + continue; + if (!strncasecmp(board_name, *dmi_name, sublen)) + return 0; + } } - if (!abituguru3_motherboards[i].id) - return 1; - - return 0; + /* No match found */ + return 1; } #else /* !CONFIG_DMI */ @@ -1221,6 +1217,13 @@ static int __init abituguru3_init(void) err = abituguru3_detect(); if (err) return err; + +#ifdef CONFIG_DMI + printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was " + "not detected using DMI. Please send the output of " + "\"dmidecode\" to the abituguru3 maintainer " + "(see MAINTAINERS)\n"); +#endif } err = platform_driver_register(&abituguru3_driver); diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 678e34b01e5..753b34885f9 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -35,7 +35,7 @@ #include <linux/dmi.h> #include <linux/mutex.h> #include <linux/hwmon-sysfs.h> -#include <asm/io.h> +#include <linux/io.h> #include <linux/leds.h> #include <linux/hwmon.h> #include <linux/workqueue.h> diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index 3df202a9ad7..9814d51b3af 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c @@ -35,7 +35,7 @@ #include <linux/err.h> #include <linux/mutex.h> #include <linux/acpi.h> -#include <asm/io.h> +#include <linux/io.h> /* ISA device, if found */ static struct platform_device *pdev; diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index 89987657925..525a00bd70b 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c @@ -40,7 +40,7 @@ #include <linux/sysfs.h> #include <linux/ioport.h> #include <linux/acpi.h> -#include <asm/io.h> +#include <linux/io.h> static unsigned short force_id; module_param(force_id, ushort, 0); diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index d3612a1f198..be2d131e405 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c @@ -35,8 +35,7 @@ #include <linux/timer.h> #include <linux/dmi.h> #include <linux/jiffies.h> - -#include <asm/io.h> +#include <linux/io.h> #define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */ #define HDAPS_NR_PORTS 0x30 /* number of ports: 0x1600 - 0x162f */ diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index bfc296145bb..bf0862a803c 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c @@ -179,8 +179,14 @@ struct vrm_model { static struct vrm_model vrm_models[] = { {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ {X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24}, /* Athlon 64, Opteron */ - {X86_VENDOR_AMD, 0xF, ANY, ANY, 25}, /* NPT family 0Fh */ + /* In theory, all NPT family 0Fh processors have 6 VID pins and should + thus use vrm 25, however in practice not all mainboards route the + 6th VID pin because it is never needed. So we use the 5 VID pin + variant (vrm 24) for the models which exist today. */ + {X86_VENDOR_AMD, 0xF, 0x7F, ANY, 24}, /* NPT family 0Fh */ + {X86_VENDOR_AMD, 0xF, ANY, ANY, 25}, /* future fam. 0Fh */ {X86_VENDOR_AMD, 0x10, ANY, ANY, 25}, /* NPT family 10h */ + {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */ @@ -191,12 +197,14 @@ static struct vrm_model vrm_models[] = { {X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90}, /* P4 Willamette */ {X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90}, /* P4 Northwood */ {X86_VENDOR_INTEL, 0xF, ANY, ANY, 100}, /* Prescott and above assume VRD 10 */ + {X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85}, /* Eden ESP/Ezra */ {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85}, /* Ezra T */ {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nemiah */ {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M, Eden-N */ {X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0}, /* No information */ {X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7, Esther */ + {X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */ }; diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 9157247fed8..ffeb2a10e1a 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -50,7 +50,7 @@ #include <linux/string.h> #include <linux/dmi.h> #include <linux/acpi.h> -#include <asm/io.h> +#include <linux/io.h> #define DRVNAME "it87" diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index a1787fdf5b9..f7e70163e01 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -31,7 +31,7 @@ #include <linux/hwmon-sysfs.h> #include <linux/err.h> #include <linux/mutex.h> -#include <asm/io.h> +#include <linux/io.h> /* ISA device, if found */ static struct platform_device *pdev; diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index b251d8674b4..6c53d987de1 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -75,6 +75,8 @@ I2C_CLIENT_INSMOD_7(lm85b, lm85c, adm1027, adt7463, adt7468, emc6d100, #define LM85_VERSTEP_GENERIC2 0x70 #define LM85_VERSTEP_LM85C 0x60 #define LM85_VERSTEP_LM85B 0x62 +#define LM85_VERSTEP_LM96000_1 0x68 +#define LM85_VERSTEP_LM96000_2 0x69 #define LM85_VERSTEP_ADM1027 0x60 #define LM85_VERSTEP_ADT7463 0x62 #define LM85_VERSTEP_ADT7463C 0x6A @@ -1133,6 +1135,26 @@ static void lm85_init_client(struct i2c_client *client) dev_warn(&client->dev, "Device is not ready\n"); } +static int lm85_is_fake(struct i2c_client *client) +{ + /* + * Differenciate between real LM96000 and Winbond WPCD377I. The latter + * emulate the former except that it has no hardware monitoring function + * so the readings are always 0. + */ + int i; + u8 in_temp, fan; + + for (i = 0; i < 8; i++) { + in_temp = i2c_smbus_read_byte_data(client, 0x20 + i); + fan = i2c_smbus_read_byte_data(client, 0x28 + i); + if (in_temp != 0x00 || fan != 0xff) + return 0; + } + + return 1; +} + /* Return 0 if detection is successful, -ENODEV otherwise */ static int lm85_detect(struct i2c_client *client, int kind, struct i2c_board_info *info) @@ -1173,6 +1195,16 @@ static int lm85_detect(struct i2c_client *client, int kind, case LM85_VERSTEP_LM85B: kind = lm85b; break; + case LM85_VERSTEP_LM96000_1: + case LM85_VERSTEP_LM96000_2: + /* Check for Winbond WPCD377I */ + if (lm85_is_fake(client)) { + dev_dbg(&adapter->dev, + "Found Winbond WPCD377I, " + "ignoring\n"); + return -ENODEV; + } + break; } } else if (company == LM85_COMPANY_ANALOG_DEV) { switch (verstep) { diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index fb052fea374..4a64b85d4ec 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c @@ -44,7 +44,7 @@ #include <linux/err.h> #include <linux/mutex.h> #include <linux/acpi.h> -#include <asm/io.h> +#include <linux/io.h> static u8 devid; static struct platform_device *pdev; diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index 3a8a0f7a773..3170b26d244 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c @@ -33,7 +33,7 @@ #include <linux/sysfs.h> #include <linux/ioport.h> #include <linux/acpi.h> -#include <asm/io.h> +#include <linux/io.h> static unsigned short force_id; module_param(force_id, ushort, 0); @@ -435,7 +435,7 @@ static int __devinit pc87427_probe(struct platform_device *pdev) /* This will need to be revisited when we add support for temperature and voltage monitoring. */ res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) { + if (!request_region(res->start, resource_size(res), DRVNAME)) { err = -EBUSY; dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n", (unsigned long)res->start, (unsigned long)res->end); @@ -475,7 +475,7 @@ exit_remove_files: sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]); } exit_release_region: - release_region(res->start, res->end - res->start + 1); + release_region(res->start, resource_size(res)); exit_kfree: platform_set_drvdata(pdev, NULL); kfree(data); @@ -500,7 +500,7 @@ static int __devexit pc87427_remove(struct platform_device *pdev) kfree(data); res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start, res->end - res->start + 1); + release_region(res->start, resource_size(res)); return 0; } diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index aa2e8318f16..12f2e708656 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c @@ -63,7 +63,7 @@ #include <linux/mutex.h> #include <linux/sysfs.h> #include <linux/acpi.h> -#include <asm/io.h> +#include <linux/io.h> /* If force_addr is set to anything different from 0, we forcibly enable diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 6f6d52b4fb6..f46d936c12d 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c @@ -37,7 +37,7 @@ #include <linux/init.h> #include <linux/mutex.h> #include <linux/acpi.h> -#include <asm/io.h> +#include <linux/io.h> static unsigned short force_id; module_param(force_id, ushort, 0); diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index ba75bfcf14c..8ad50fdba00 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -38,7 +38,7 @@ #include <linux/mutex.h> #include <linux/sysfs.h> #include <linux/acpi.h> -#include <asm/io.h> +#include <linux/io.h> static unsigned short force_id; module_param(force_id, ushort, 0); diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c new file mode 100644 index 00000000000..20924343431 --- /dev/null +++ b/drivers/hwmon/tmp421.c @@ -0,0 +1,347 @@ +/* tmp421.c + * + * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de> + * Preliminary support by: + * Melvin Rook, Raymond Ng + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Driver for the Texas Instruments TMP421 SMBus temperature sensor IC. + * Supported models: TMP421, TMP422, TMP423 + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/jiffies.h> +#include <linux/i2c.h> +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> +#include <linux/err.h> +#include <linux/mutex.h> +#include <linux/sysfs.h> + +/* Addresses to scan */ +static unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f, + I2C_CLIENT_END }; + +/* Insmod parameters */ +I2C_CLIENT_INSMOD_3(tmp421, tmp422, tmp423); + +/* The TMP421 registers */ +#define TMP421_CONFIG_REG_1 0x09 +#define TMP421_CONVERSION_RATE_REG 0x0B +#define TMP421_MANUFACTURER_ID_REG 0xFE +#define TMP421_DEVICE_ID_REG 0xFF + +static const u8 TMP421_TEMP_MSB[4] = { 0x00, 0x01, 0x02, 0x03 }; +static const u8 TMP421_TEMP_LSB[4] = { 0x10, 0x11, 0x12, 0x13 }; + +/* Flags */ +#define TMP421_CONFIG_SHUTDOWN 0x40 +#define TMP421_CONFIG_RANGE 0x04 + +/* Manufacturer / Device ID's */ +#define TMP421_MANUFACTURER_ID 0x55 +#define TMP421_DEVICE_ID 0x21 +#define TMP422_DEVICE_ID 0x22 +#define TMP423_DEVICE_ID 0x23 + +static const struct i2c_device_id tmp421_id[] = { + { "tmp421", tmp421 }, + { "tmp422", tmp422 }, + { "tmp423", tmp423 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tmp421_id); + +struct tmp421_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; + int kind; + u8 config; + s16 temp[4]; +}; + +static int temp_from_s16(s16 reg) +{ + int temp = reg; + + return (temp * 1000 + 128) / 256; +} + +static int temp_from_u16(u16 reg) +{ + int temp = reg; + + /* Add offset for extended temperature range. */ + temp -= 64 * 256; + + return (temp * 1000 + 128) / 256; +} + +static struct tmp421_data *tmp421_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct tmp421_data *data = i2c_get_clientdata(client); + int i; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { + data->config = i2c_smbus_read_byte_data(client, + TMP421_CONFIG_REG_1); + + for (i = 0; i <= data->kind; i++) { + data->temp[i] = i2c_smbus_read_byte_data(client, + TMP421_TEMP_MSB[i]) << 8; + data->temp[i] |= i2c_smbus_read_byte_data(client, + TMP421_TEMP_LSB[i]); + } + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static ssize_t show_temp_value(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct tmp421_data *data = tmp421_update_device(dev); + int temp; + + mutex_lock(&data->update_lock); + if (data->config & TMP421_CONFIG_RANGE) + temp = temp_from_u16(data->temp[index]); + else + temp = temp_from_s16(data->temp[index]); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", temp); +} + +static ssize_t show_fault(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct tmp421_data *data = tmp421_update_device(dev); + + /* + * The OPEN bit signals a fault. This is bit 0 of the temperature + * register (low byte). + */ + if (data->temp[index] & 0x01) + return sprintf(buf, "1\n"); + else + return sprintf(buf, "0\n"); +} + +static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a, + int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct tmp421_data *data = dev_get_drvdata(dev); + struct device_attribute *devattr; + unsigned int index; + + devattr = container_of(a, struct device_attribute, attr); + index = to_sensor_dev_attr(devattr)->index; + + if (data->kind > index) + return a->mode; + + return 0; +} + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1); +static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_value, NULL, 2); +static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_value, NULL, 3); +static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3); + +static struct attribute *tmp421_attr[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_fault.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp4_fault.dev_attr.attr, + NULL +}; + +static const struct attribute_group tmp421_group = { + .attrs = tmp421_attr, + .is_visible = tmp421_is_visible, +}; + +static int tmp421_init_client(struct i2c_client *client) +{ + int config, config_orig; + + /* Set the conversion rate to 2 Hz */ + i2c_smbus_write_byte_data(client, TMP421_CONVERSION_RATE_REG, 0x05); + + /* Start conversions (disable shutdown if necessary) */ + config = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1); + if (config < 0) { + dev_err(&client->dev, "Could not read configuration" + " register (%d)\n", config); + return -ENODEV; + } + + config_orig = config; + config &= ~TMP421_CONFIG_SHUTDOWN; + + if (config != config_orig) { + dev_info(&client->dev, "Enable monitoring chip\n"); + i2c_smbus_write_byte_data(client, TMP421_CONFIG_REG_1, config); + } + + return 0; +} + +static int tmp421_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + const char *names[] = { "TMP421", "TMP422", "TMP423" }; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + if (kind <= 0) { + u8 reg; + + reg = i2c_smbus_read_byte_data(client, + TMP421_MANUFACTURER_ID_REG); + if (reg != TMP421_MANUFACTURER_ID) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, + TMP421_DEVICE_ID_REG); + switch (reg) { + case TMP421_DEVICE_ID: + kind = tmp421; + break; + case TMP422_DEVICE_ID: + kind = tmp422; + break; + case TMP423_DEVICE_ID: + kind = tmp423; + break; + default: + return -ENODEV; + } + } + strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE); + dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n", + names[kind - 1], client->addr); + + return 0; +} + +static int tmp421_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tmp421_data *data; + int err; + + data = kzalloc(sizeof(struct tmp421_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->kind = id->driver_data; + + err = tmp421_init_client(client); + if (err) + goto exit_free; + + err = sysfs_create_group(&client->dev.kobj, &tmp421_group); + if (err) + goto exit_free; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + data->hwmon_dev = NULL; + goto exit_remove; + } + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &tmp421_group); + +exit_free: + i2c_set_clientdata(client, NULL); + kfree(data); + + return err; +} + +static int tmp421_remove(struct i2c_client *client) +{ + struct tmp421_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &tmp421_group); + + i2c_set_clientdata(client, NULL); + kfree(data); + + return 0; +} + +static struct i2c_driver tmp421_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "tmp421", + }, + .probe = tmp421_probe, + .remove = tmp421_remove, + .id_table = tmp421_id, + .detect = tmp421_detect, + .address_data = &addr_data, +}; + +static int __init tmp421_init(void) +{ + return i2c_add_driver(&tmp421_driver); +} + +static void __exit tmp421_exit(void) +{ + i2c_del_driver(&tmp421_driver); +} + +MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>"); +MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor" + " driver"); +MODULE_LICENSE("GPL"); + +module_init(tmp421_init); +module_exit(tmp421_exit); diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index a022aedcaac..39e82a492f2 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -42,7 +42,7 @@ #include <linux/mutex.h> #include <linux/sysfs.h> #include <linux/acpi.h> -#include <asm/io.h> +#include <linux/io.h> /* If force_addr is set to anything different from 0, we forcibly enable diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c index 73f77a9b8b1..ae33bbb577c 100644 --- a/drivers/hwmon/vt1211.c +++ b/drivers/hwmon/vt1211.c @@ -33,7 +33,7 @@ #include <linux/mutex.h> #include <linux/ioport.h> #include <linux/acpi.h> -#include <asm/io.h> +#include <linux/io.h> static int uch_config = -1; module_param(uch_config, int, 0); @@ -1136,7 +1136,7 @@ static int __devinit vt1211_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) { + if (!request_region(res->start, resource_size(res), DRVNAME)) { err = -EBUSY; dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", (unsigned long)res->start, (unsigned long)res->end); @@ -1209,7 +1209,7 @@ EXIT_DEV_REMOVE: dev_err(dev, "Sysfs interface creation failed (%d)\n", err); EXIT_DEV_REMOVE_SILENT: vt1211_remove_sysfs(pdev); - release_region(res->start, res->end - res->start + 1); + release_region(res->start, resource_size(res)); EXIT_KFREE: platform_set_drvdata(pdev, NULL); kfree(data); @@ -1228,7 +1228,7 @@ static int __devexit vt1211_remove(struct platform_device *pdev) kfree(data); res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start, res->end - res->start + 1); + release_region(res->start, resource_size(res)); return 0; } diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 9982b45fbb1..470a1226ba2 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -36,7 +36,7 @@ #include <linux/err.h> #include <linux/mutex.h> #include <linux/acpi.h> -#include <asm/io.h> +#include <linux/io.h> static int force_addr; module_param(force_addr, int, 0); diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 0e9746913d2..bb5e7874878 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -51,7 +51,7 @@ #include <linux/err.h> #include <linux/mutex.h> #include <linux/acpi.h> -#include <asm/io.h> +#include <linux/io.h> #include "lm75.h" enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg }; diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 389150ba30d..2be28ac4ede 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -51,7 +51,7 @@ #include <linux/mutex.h> #include <linux/ioport.h> #include <linux/acpi.h> -#include <asm/io.h> +#include <linux/io.h> #include "lm75.h" static struct platform_device *pdev; diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 0bdab959b73..d27ed1bac00 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -48,7 +48,7 @@ #ifdef CONFIG_ISA #include <linux/platform_device.h> #include <linux/ioport.h> -#include <asm/io.h> +#include <linux/io.h> #endif #include "lm75.h" diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 507569a4f23..ed5741b2e70 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1934,6 +1934,15 @@ config XILINX_EMACLITE help This driver supports the 10/100 Ethernet Lite from Xilinx. +config BCM63XX_ENET + tristate "Broadcom 63xx internal mac support" + depends on BCM63XX + select MII + select PHYLIB + help + This driver supports the ethernet MACs in the Broadcom 63xx + MIPS chipset family (BCM63XX). + source "drivers/net/fs_enet/Kconfig" endif # NET_ETHERNET diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 99ae6d7fe6a..ae8cd30f13d 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -137,6 +137,7 @@ obj-$(CONFIG_B44) += b44.o obj-$(CONFIG_FORCEDETH) += forcedeth.o obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o obj-$(CONFIG_AX88796) += ax88796.o +obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h index ba48220df16..490d3b38e0c 100644 --- a/drivers/net/atl1e/atl1e.h +++ b/drivers/net/atl1e/atl1e.h @@ -377,10 +377,19 @@ struct atl1e_hw { */ struct atl1e_tx_buffer { struct sk_buff *skb; + u16 flags; +#define ATL1E_TX_PCIMAP_SINGLE 0x0001 +#define ATL1E_TX_PCIMAP_PAGE 0x0002 +#define ATL1E_TX_PCIMAP_TYPE_MASK 0x0003 u16 length; dma_addr_t dma; }; +#define ATL1E_SET_PCIMAP_TYPE(tx_buff, type) do { \ + ((tx_buff)->flags) &= ~ATL1E_TX_PCIMAP_TYPE_MASK; \ + ((tx_buff)->flags) |= (type); \ + } while (0) + struct atl1e_rx_page { dma_addr_t dma; /* receive rage DMA address */ u8 *addr; /* receive rage virtual address */ diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 69b830f4b68..955da733c2a 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -635,7 +635,11 @@ static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter) for (index = 0; index < ring_count; index++) { tx_buffer = &tx_ring->tx_buffer[index]; if (tx_buffer->dma) { - pci_unmap_page(pdev, tx_buffer->dma, + if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE) + pci_unmap_single(pdev, tx_buffer->dma, + tx_buffer->length, PCI_DMA_TODEVICE); + else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE) + pci_unmap_page(pdev, tx_buffer->dma, tx_buffer->length, PCI_DMA_TODEVICE); tx_buffer->dma = 0; } @@ -1220,7 +1224,11 @@ static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter) while (next_to_clean != hw_next_to_clean) { tx_buffer = &tx_ring->tx_buffer[next_to_clean]; if (tx_buffer->dma) { - pci_unmap_page(adapter->pdev, tx_buffer->dma, + if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE) + pci_unmap_single(adapter->pdev, tx_buffer->dma, + tx_buffer->length, PCI_DMA_TODEVICE); + else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE) + pci_unmap_page(adapter->pdev, tx_buffer->dma, tx_buffer->length, PCI_DMA_TODEVICE); tx_buffer->dma = 0; } @@ -1741,6 +1749,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, tx_buffer->length = map_len; tx_buffer->dma = pci_map_single(adapter->pdev, skb->data, hdr_len, PCI_DMA_TODEVICE); + ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE); mapped_len += map_len; use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) | @@ -1766,6 +1775,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, tx_buffer->dma = pci_map_single(adapter->pdev, skb->data + mapped_len, map_len, PCI_DMA_TODEVICE); + ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE); mapped_len += map_len; use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) | @@ -1801,6 +1811,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, (i * MAX_TX_BUF_LEN), tx_buffer->length, PCI_DMA_TODEVICE); + ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE); use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) | ((cpu_to_le32(tx_buffer->length) & diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 0189dcd36f3..e046943ef29 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -847,23 +847,22 @@ static int b44_poll(struct napi_struct *napi, int budget) { struct b44 *bp = container_of(napi, struct b44, napi); int work_done; + unsigned long flags; - spin_lock_irq(&bp->lock); + spin_lock_irqsave(&bp->lock, flags); if (bp->istat & (ISTAT_TX | ISTAT_TO)) { /* spin_lock(&bp->tx_lock); */ b44_tx(bp); /* spin_unlock(&bp->tx_lock); */ } - spin_unlock_irq(&bp->lock); + spin_unlock_irqrestore(&bp->lock, flags); work_done = 0; if (bp->istat & ISTAT_RX) work_done += b44_rx(bp, budget); if (bp->istat & ISTAT_ERRORS) { - unsigned long flags; - spin_lock_irqsave(&bp->lock, flags); b44_halt(bp); b44_init_rings(bp); diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c new file mode 100644 index 00000000000..09d270913c5 --- /dev/null +++ b/drivers/net/bcm63xx_enet.c @@ -0,0 +1,1971 @@ +/* + * Driver for BCM963xx builtin Ethernet mac + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/clk.h> +#include <linux/etherdevice.h> +#include <linux/delay.h> +#include <linux/ethtool.h> +#include <linux/crc32.h> +#include <linux/err.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/if_vlan.h> + +#include <bcm63xx_dev_enet.h> +#include "bcm63xx_enet.h" + +static char bcm_enet_driver_name[] = "bcm63xx_enet"; +static char bcm_enet_driver_version[] = "1.0"; + +static int copybreak __read_mostly = 128; +module_param(copybreak, int, 0); +MODULE_PARM_DESC(copybreak, "Receive copy threshold"); + +/* io memory shared between all devices */ +static void __iomem *bcm_enet_shared_base; + +/* + * io helpers to access mac registers + */ +static inline u32 enet_readl(struct bcm_enet_priv *priv, u32 off) +{ + return bcm_readl(priv->base + off); +} + +static inline void enet_writel(struct bcm_enet_priv *priv, + u32 val, u32 off) +{ + bcm_writel(val, priv->base + off); +} + +/* + * io helpers to access shared registers + */ +static inline u32 enet_dma_readl(struct bcm_enet_priv *priv, u32 off) +{ + return bcm_readl(bcm_enet_shared_base + off); +} + +static inline void enet_dma_writel(struct bcm_enet_priv *priv, + u32 val, u32 off) +{ + bcm_writel(val, bcm_enet_shared_base + off); +} + +/* + * write given data into mii register and wait for transfer to end + * with timeout (average measured transfer time is 25us) + */ +static int do_mdio_op(struct bcm_enet_priv *priv, unsigned int data) +{ + int limit; + + /* make sure mii interrupt status is cleared */ + enet_writel(priv, ENET_IR_MII, ENET_IR_REG); + + enet_writel(priv, data, ENET_MIIDATA_REG); + wmb(); + + /* busy wait on mii interrupt bit, with timeout */ + limit = 1000; + do { + if (enet_readl(priv, ENET_IR_REG) & ENET_IR_MII) + break; + udelay(1); + } while (limit-- >= 0); + + return (limit < 0) ? 1 : 0; +} + +/* + * MII internal read callback + */ +static int bcm_enet_mdio_read(struct bcm_enet_priv *priv, int mii_id, + int regnum) +{ + u32 tmp, val; + + tmp = regnum << ENET_MIIDATA_REG_SHIFT; + tmp |= 0x2 << ENET_MIIDATA_TA_SHIFT; + tmp |= mii_id << ENET_MIIDATA_PHYID_SHIFT; + tmp |= ENET_MIIDATA_OP_READ_MASK; + + if (do_mdio_op(priv, tmp)) + return -1; + + val = enet_readl(priv, ENET_MIIDATA_REG); + val &= 0xffff; + return val; +} + +/* + * MII internal write callback + */ +static int bcm_enet_mdio_write(struct bcm_enet_priv *priv, int mii_id, + int regnum, u16 value) +{ + u32 tmp; + + tmp = (value & 0xffff) << ENET_MIIDATA_DATA_SHIFT; + tmp |= 0x2 << ENET_MIIDATA_TA_SHIFT; + tmp |= regnum << ENET_MIIDATA_REG_SHIFT; + tmp |= mii_id << ENET_MIIDATA_PHYID_SHIFT; + tmp |= ENET_MIIDATA_OP_WRITE_MASK; + + (void)do_mdio_op(priv, tmp); + return 0; +} + +/* + * MII read callback from phylib + */ +static int bcm_enet_mdio_read_phylib(struct mii_bus *bus, int mii_id, + int regnum) +{ + return bcm_enet_mdio_read(bus->priv, mii_id, regnum); +} + +/* + * MII write callback from phylib + */ +static int bcm_enet_mdio_write_phylib(struct mii_bus *bus, int mii_id, + int regnum, u16 value) +{ + return bcm_enet_mdio_write(bus->priv, mii_id, regnum, value); +} + +/* + * MII read callback from mii core + */ +static int bcm_enet_mdio_read_mii(struct net_device *dev, int mii_id, + int regnum) +{ + return bcm_enet_mdio_read(netdev_priv(dev), mii_id, regnum); +} + +/* + * MII write callback from mii core + */ +static void bcm_enet_mdio_write_mii(struct net_device *dev, int mii_id, + int regnum, int value) +{ + bcm_enet_mdio_write(netdev_priv(dev), mii_id, regnum, value); +} + +/* + * refill rx queue + */ +static int bcm_enet_refill_rx(struct net_device *dev) +{ + struct bcm_enet_priv *priv; + + priv = netdev_priv(dev); + + while (priv->rx_desc_count < priv->rx_ring_size) { + struct bcm_enet_desc *desc; + struct sk_buff *skb; + dma_addr_t p; + int desc_idx; + u32 len_stat; + + desc_idx = priv->rx_dirty_desc; + desc = &priv->rx_desc_cpu[desc_idx]; + + if (!priv->rx_skb[desc_idx]) { + skb = netdev_alloc_skb(dev, priv->rx_skb_size); + if (!skb) + break; + priv->rx_skb[desc_idx] = skb; + + p = dma_map_single(&priv->pdev->dev, skb->data, + priv->rx_skb_size, + DMA_FROM_DEVICE); + desc->address = p; + } + + len_stat = priv->rx_skb_size << DMADESC_LENGTH_SHIFT; + len_stat |= DMADESC_OWNER_MASK; + if (priv->rx_dirty_desc == priv->rx_ring_size - 1) { + len_stat |= DMADESC_WRAP_MASK; + priv->rx_dirty_desc = 0; + } else { + priv->rx_dirty_desc++; + } + wmb(); + desc->len_stat = len_stat; + + priv->rx_desc_count++; + + /* tell dma engine we allocated one buffer */ + enet_dma_writel(priv, 1, ENETDMA_BUFALLOC_REG(priv->rx_chan)); + } + + /* If rx ring is still empty, set a timer to try allocating + * again at a later time. */ + if (priv->rx_desc_count == 0 && netif_running(dev)) { + dev_warn(&priv->pdev->dev, "unable to refill rx ring\n"); + priv->rx_timeout.expires = jiffies + HZ; + add_timer(&priv->rx_timeout); + } + + return 0; +} + +/* + * timer callback to defer refill rx queue in case we're OOM + */ +static void bcm_enet_refill_rx_timer(unsigned long data) +{ + struct net_device *dev; + struct bcm_enet_priv *priv; + + dev = (struct net_device *)data; + priv = netdev_priv(dev); + + spin_lock(&priv->rx_lock); + bcm_enet_refill_rx((struct net_device *)data); + spin_unlock(&priv->rx_lock); +} + +/* + * extract packet from rx queue + */ +static int bcm_enet_receive_queue(struct net_device *dev, int budget) +{ + struct bcm_enet_priv *priv; + struct device *kdev; + int processed; + + priv = netdev_priv(dev); + kdev = &priv->pdev->dev; + processed = 0; + + /* don't scan ring further than number of refilled + * descriptor */ + if (budget > priv->rx_desc_count) + budget = priv->rx_desc_count; + + do { + struct bcm_enet_desc *desc; + struct sk_buff *skb; + int desc_idx; + u32 len_stat; + unsigned int len; + + desc_idx = priv->rx_curr_desc; + desc = &priv->rx_desc_cpu[desc_idx]; + + /* make sure we actually read the descriptor status at + * each loop */ + rmb(); + + len_stat = desc->len_stat; + + /* break if dma ownership belongs to hw */ + if (len_stat & DMADESC_OWNER_MASK) + break; + + processed++; + priv->rx_curr_desc++; + if (priv->rx_curr_desc == priv->rx_ring_size) + priv->rx_curr_desc = 0; + priv->rx_desc_count--; + + /* if the packet does not have start of packet _and_ + * end of packet flag set, then just recycle it */ + if ((len_stat & DMADESC_ESOP_MASK) != DMADESC_ESOP_MASK) { + priv->stats.rx_dropped++; + continue; + } + + /* recycle packet if it's marked as bad */ + if (unlikely(len_stat & DMADESC_ERR_MASK)) { + priv->stats.rx_errors++; + + if (len_stat & DMADESC_OVSIZE_MASK) + priv->stats.rx_length_errors++; + if (len_stat & DMADESC_CRC_MASK) + priv->stats.rx_crc_errors++; + if (len_stat & DMADESC_UNDER_MASK) + priv->stats.rx_frame_errors++; + if (len_stat & DMADESC_OV_MASK) + priv->stats.rx_fifo_errors++; + continue; + } + + /* valid packet */ + skb = priv->rx_skb[desc_idx]; + len = (len_stat & DMADESC_LENGTH_MASK) >> DMADESC_LENGTH_SHIFT; + /* don't include FCS */ + len -= 4; + + if (len < copybreak) { + struct sk_buff *nskb; + + nskb = netdev_alloc_skb(dev, len + NET_IP_ALIGN); + if (!nskb) { + /* forget packet, just rearm desc */ + priv->stats.rx_dropped++; + continue; + } + + /* since we're copying the data, we can align + * them properly */ + skb_reserve(nskb, NET_IP_ALIGN); + dma_sync_single_for_cpu(kdev, desc->address, + len, DMA_FROM_DEVICE); + memcpy(nskb->data, skb->data, len); + dma_sync_single_for_device(kdev, desc->address, + len, DMA_FROM_DEVICE); + skb = nskb; + } else { + dma_unmap_single(&priv->pdev->dev, desc->address, + priv->rx_skb_size, DMA_FROM_DEVICE); + priv->rx_skb[desc_idx] = NULL; + } + + skb_put(skb, len); + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); + priv->stats.rx_packets++; + priv->stats.rx_bytes += len; + dev->last_rx = jiffies; + netif_receive_skb(skb); + + } while (--budget > 0); + + if (processed || !priv->rx_desc_count) { + bcm_enet_refill_rx(dev); + + /* kick rx dma */ + enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK, + ENETDMA_CHANCFG_REG(priv->rx_chan)); + } + + return processed; +} + + +/* + * try to or force reclaim of transmitted buffers + */ +static int bcm_enet_tx_reclaim(struct net_device *dev, int force) +{ + struct bcm_enet_priv *priv; + int released; + + priv = netdev_priv(dev); + released = 0; + + while (priv->tx_desc_count < priv->tx_ring_size) { + struct bcm_enet_desc *desc; + struct sk_buff *skb; + + /* We run in a bh and fight against start_xmit, which + * is called with bh disabled */ + spin_lock(&priv->tx_lock); + + desc = &priv->tx_desc_cpu[priv->tx_dirty_desc]; + + if (!force && (desc->len_stat & DMADESC_OWNER_MASK)) { + spin_unlock(&priv->tx_lock); + break; + } + + /* ensure other field of the descriptor were not read + * before we checked ownership */ + rmb(); + + skb = priv->tx_skb[priv->tx_dirty_desc]; + priv->tx_skb[priv->tx_dirty_desc] = NULL; + dma_unmap_single(&priv->pdev->dev, desc->address, skb->len, + DMA_TO_DEVICE); + + priv->tx_dirty_desc++; + if (priv->tx_dirty_desc == priv->tx_ring_size) + priv->tx_dirty_desc = 0; + priv->tx_desc_count++; + + spin_unlock(&priv->tx_lock); + + if (desc->len_stat & DMADESC_UNDER_MASK) + priv->stats.tx_errors++; + + dev_kfree_skb(skb); + released++; + } + + if (netif_queue_stopped(dev) && released) + netif_wake_queue(dev); + + return released; +} + +/* + * poll func, called by network core + */ +static int bcm_enet_poll(struct napi_struct *napi, int budget) +{ + struct bcm_enet_priv *priv; + struct net_device *dev; + int tx_work_done, rx_work_done; + + priv = container_of(napi, struct bcm_enet_priv, napi); + dev = priv->net_dev; + + /* ack interrupts */ + enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, + ENETDMA_IR_REG(priv->rx_chan)); + enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, + ENETDMA_IR_REG(priv->tx_chan)); + + /* reclaim sent skb */ + tx_work_done = bcm_enet_tx_reclaim(dev, 0); + + spin_lock(&priv->rx_lock); + rx_work_done = bcm_enet_receive_queue(dev, budget); + spin_unlock(&priv->rx_lock); + + if (rx_work_done >= budget || tx_work_done > 0) { + /* rx/tx queue is not yet empty/clean */ + return rx_work_done; + } + + /* no more packet in rx/tx queue, remove device from poll + * queue */ + napi_complete(napi); + + /* restore rx/tx interrupt */ + enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, + ENETDMA_IRMASK_REG(priv->rx_chan)); + enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, + ENETDMA_IRMASK_REG(priv->tx_chan)); + + return rx_work_done; +} + +/* + * mac interrupt handler + */ +static irqreturn_t bcm_enet_isr_mac(int irq, void *dev_id) +{ + struct net_device *dev; + struct bcm_enet_priv *priv; + u32 stat; + + dev = dev_id; + priv = netdev_priv(dev); + + stat = enet_readl(priv, ENET_IR_REG); + if (!(stat & ENET_IR_MIB)) + return IRQ_NONE; + + /* clear & mask interrupt */ + enet_writel(priv, ENET_IR_MIB, ENET_IR_REG); + enet_writel(priv, 0, ENET_IRMASK_REG); + + /* read mib registers in workqueue */ + schedule_work(&priv->mib_update_task); + + return IRQ_HANDLED; +} + +/* + * rx/tx dma interrupt handler + */ +static irqreturn_t bcm_enet_isr_dma(int irq, void *dev_id) +{ + struct net_device *dev; + struct bcm_enet_priv *priv; + + dev = dev_id; + priv = netdev_priv(dev); + + /* mask rx/tx interrupts */ + enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan)); + enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan)); + + napi_schedule(&priv->napi); + + return IRQ_HANDLED; +} + +/* + * tx request callback + */ +static int bcm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct bcm_enet_priv *priv; + struct bcm_enet_desc *desc; + u32 len_stat; + int ret; + + priv = netdev_priv(dev); + + /* lock against tx reclaim */ + spin_lock(&priv->tx_lock); + + /* make sure the tx hw queue is not full, should not happen + * since we stop queue before it's the case */ + if (unlikely(!priv->tx_desc_count)) { + netif_stop_queue(dev); + dev_err(&priv->pdev->dev, "xmit called with no tx desc " + "available?\n"); + ret = NETDEV_TX_BUSY; + goto out_unlock; + } + + /* point to the next available desc */ + desc = &priv->tx_desc_cpu[priv->tx_curr_desc]; + priv->tx_skb[priv->tx_curr_desc] = skb; + + /* fill descriptor */ + desc->address = dma_map_single(&priv->pdev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + + len_stat = (skb->len << DMADESC_LENGTH_SHIFT) & DMADESC_LENGTH_MASK; + len_stat |= DMADESC_ESOP_MASK | + DMADESC_APPEND_CRC | + DMADESC_OWNER_MASK; + + priv->tx_curr_desc++; + if (priv->tx_curr_desc == priv->tx_ring_size) { + priv->tx_curr_desc = 0; + len_stat |= DMADESC_WRAP_MASK; + } + priv->tx_desc_count--; + + /* dma might be already polling, make sure we update desc + * fields in correct order */ + wmb(); + desc->len_stat = len_stat; + wmb(); + + /* kick tx dma */ + enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK, + ENETDMA_CHANCFG_REG(priv->tx_chan)); + + /* stop queue if no more desc available */ + if (!priv->tx_desc_count) + netif_stop_queue(dev); + + priv->stats.tx_bytes += skb->len; + priv->stats.tx_packets++; + dev->trans_start = jiffies; + ret = NETDEV_TX_OK; + +out_unlock: + spin_unlock(&priv->tx_lock); + return ret; +} + +/* + * Change the interface's mac address. + */ +static int bcm_enet_set_mac_address(struct net_device *dev, void *p) +{ + struct bcm_enet_priv *priv; + struct sockaddr *addr = p; + u32 val; + + priv = netdev_priv(dev); + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); + + /* use perfect match register 0 to store my mac address */ + val = (dev->dev_addr[2] << 24) | (dev->dev_addr[3] << 16) | + (dev->dev_addr[4] << 8) | dev->dev_addr[5]; + enet_writel(priv, val, ENET_PML_REG(0)); + + val = (dev->dev_addr[0] << 8 | dev->dev_addr[1]); + val |= ENET_PMH_DATAVALID_MASK; + enet_writel(priv, val, ENET_PMH_REG(0)); + + return 0; +} + +/* + * Change rx mode (promiscous/allmulti) and update multicast list + */ +static void bcm_enet_set_multicast_list(struct net_device *dev) +{ + struct bcm_enet_priv *priv; + struct dev_mc_list *mc_list; + u32 val; + int i; + + priv = netdev_priv(dev); + + val = enet_readl(priv, ENET_RXCFG_REG); + + if (dev->flags & IFF_PROMISC) + val |= ENET_RXCFG_PROMISC_MASK; + else + val &= ~ENET_RXCFG_PROMISC_MASK; + + /* only 3 perfect match registers left, first one is used for + * own mac address */ + if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 3) + val |= ENET_RXCFG_ALLMCAST_MASK; + else + val &= ~ENET_RXCFG_ALLMCAST_MASK; + + /* no need to set perfect match registers if we catch all + * multicast */ + if (val & ENET_RXCFG_ALLMCAST_MASK) { + enet_writel(priv, val, ENET_RXCFG_REG); + return; + } + + for (i = 0, mc_list = dev->mc_list; + (mc_list != NULL) && (i < dev->mc_count) && (i < 3); + i++, mc_list = mc_list->next) { + u8 *dmi_addr; + u32 tmp; + + /* filter non ethernet address */ + if (mc_list->dmi_addrlen != 6) + continue; + + /* update perfect match registers */ + dmi_addr = mc_list->dmi_addr; + tmp = (dmi_addr[2] << 24) | (dmi_addr[3] << 16) | + (dmi_addr[4] << 8) | dmi_addr[5]; + enet_writel(priv, tmp, ENET_PML_REG(i + 1)); + + tmp = (dmi_addr[0] << 8 | dmi_addr[1]); + tmp |= ENET_PMH_DATAVALID_MASK; + enet_writel(priv, tmp, ENET_PMH_REG(i + 1)); + } + + for (; i < 3; i++) { + enet_writel(priv, 0, ENET_PML_REG(i + 1)); + enet_writel(priv, 0, ENET_PMH_REG(i + 1)); + } + + enet_writel(priv, val, ENET_RXCFG_REG); +} + +/* + * set mac duplex parameters + */ +static void bcm_enet_set_duplex(struct bcm_enet_priv *priv, int fullduplex) +{ + u32 val; + + val = enet_readl(priv, ENET_TXCTL_REG); + if (fullduplex) + val |= ENET_TXCTL_FD_MASK; + else + val &= ~ENET_TXCTL_FD_MASK; + enet_writel(priv, val, ENET_TXCTL_REG); +} + +/* + * set mac flow control parameters + */ +static void bcm_enet_set_flow(struct bcm_enet_priv *priv, int rx_en, int tx_en) +{ + u32 val; + + /* rx flow control (pause frame handling) */ + val = enet_readl(priv, ENET_RXCFG_REG); + if (rx_en) + val |= ENET_RXCFG_ENFLOW_MASK; + else + val &= ~ENET_RXCFG_ENFLOW_MASK; + enet_writel(priv, val, ENET_RXCFG_REG); + + /* tx flow control (pause frame generation) */ + val = enet_dma_readl(priv, ENETDMA_CFG_REG); + if (tx_en) + val |= ENETDMA_CFG_FLOWCH_MASK(priv->rx_chan); + else + val &= ~ENETDMA_CFG_FLOWCH_MASK(priv->rx_chan); + enet_dma_writel(priv, val, ENETDMA_CFG_REG); +} + +/* + * link changed callback (from phylib) + */ +static void bcm_enet_adjust_phy_link(struct net_device *dev) +{ + struct bcm_enet_priv *priv; + struct phy_device *phydev; + int status_changed; + + priv = netdev_priv(dev); + phydev = priv->phydev; + status_changed = 0; + + if (priv->old_link != phydev->link) { + status_changed = 1; + priv->old_link = phydev->link; + } + + /* reflect duplex change in mac configuration */ + if (phydev->link && phydev->duplex != priv->old_duplex) { + bcm_enet_set_duplex(priv, + (phydev->duplex == DUPLEX_FULL) ? 1 : 0); + status_changed = 1; + priv->old_duplex = phydev->duplex; + } + + /* enable flow control if remote advertise it (trust phylib to + * check that duplex is full */ + if (phydev->link && phydev->pause != priv->old_pause) { + int rx_pause_en, tx_pause_en; + + if (phydev->pause) { + /* pause was advertised by lpa and us */ + rx_pause_en = 1; + tx_pause_en = 1; + } else if (!priv->pause_auto) { + /* pause setting overrided by user */ + rx_pause_en = priv->pause_rx; + tx_pause_en = priv->pause_tx; + } else { + rx_pause_en = 0; + tx_pause_en = 0; + } + + bcm_enet_set_flow(priv, rx_pause_en, tx_pause_en); + status_changed = 1; + priv->old_pause = phydev->pause; + } + + if (status_changed) { + pr_info("%s: link %s", dev->name, phydev->link ? + "UP" : "DOWN"); + if (phydev->link) + pr_cont(" - %d/%s - flow control %s", phydev->speed, + DUPLEX_FULL == phydev->duplex ? "full" : "half", + phydev->pause == 1 ? "rx&tx" : "off"); + + pr_cont("\n"); + } +} + +/* + * link changed callback (if phylib is not used) + */ +static void bcm_enet_adjust_link(struct net_device *dev) +{ + struct bcm_enet_priv *priv; + + priv = netdev_priv(dev); + bcm_enet_set_duplex(priv, priv->force_duplex_full); + bcm_enet_set_flow(priv, priv->pause_rx, priv->pause_tx); + netif_carrier_on(dev); + + pr_info("%s: link forced UP - %d/%s - flow control %s/%s\n", + dev->name, + priv->force_speed_100 ? 100 : 10, + priv->force_duplex_full ? "full" : "half", + priv->pause_rx ? "rx" : "off", + priv->pause_tx ? "tx" : "off"); +} + +/* + * open callback, allocate dma rings & buffers and start rx operation + */ +static int bcm_enet_open(struct net_device *dev) +{ + struct bcm_enet_priv *priv; + struct sockaddr addr; + struct device *kdev; + struct phy_device *phydev; + int i, ret; + unsigned int size; + char phy_id[MII_BUS_ID_SIZE + 3]; + void *p; + u32 val; + + priv = netdev_priv(dev); + kdev = &priv->pdev->dev; + + if (priv->has_phy) { + /* connect to PHY */ + snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, + priv->mac_id ? "1" : "0", priv->phy_id); + + phydev = phy_connect(dev, phy_id, &bcm_enet_adjust_phy_link, 0, + PHY_INTERFACE_MODE_MII); + + if (IS_ERR(phydev)) { + dev_err(kdev, "could not attach to PHY\n"); + return PTR_ERR(phydev); + } + + /* mask with MAC supported features */ + phydev->supported &= (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_MII); + phydev->advertising = phydev->supported; + + if (priv->pause_auto && priv->pause_rx && priv->pause_tx) + phydev->advertising |= SUPPORTED_Pause; + else + phydev->advertising &= ~SUPPORTED_Pause; + + dev_info(kdev, "attached PHY at address %d [%s]\n", + phydev->addr, phydev->drv->name); + + priv->old_link = 0; + priv->old_duplex = -1; + priv->old_pause = -1; + priv->phydev = phydev; + } + + /* mask all interrupts and request them */ + enet_writel(priv, 0, ENET_IRMASK_REG); + enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan)); + enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan)); + + ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev); + if (ret) + goto out_phy_disconnect; + + ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, + IRQF_SAMPLE_RANDOM | IRQF_DISABLED, dev->name, dev); + if (ret) + goto out_freeirq; + + ret = request_irq(priv->irq_tx, bcm_enet_isr_dma, + IRQF_DISABLED, dev->name, dev); + if (ret) + goto out_freeirq_rx; + + /* initialize perfect match registers */ + for (i = 0; i < 4; i++) { + enet_writel(priv, 0, ENET_PML_REG(i)); + enet_writel(priv, 0, ENET_PMH_REG(i)); + } + + /* write device mac address */ + memcpy(addr.sa_data, dev->dev_addr, ETH_ALEN); + bcm_enet_set_mac_address(dev, &addr); + + /* allocate rx dma ring */ + size = priv->rx_ring_size * sizeof(struct bcm_enet_desc); + p = dma_alloc_coherent(kdev, size, &priv->rx_desc_dma, GFP_KERNEL); + if (!p) { + dev_err(kdev, "cannot allocate rx ring %u\n", size); + ret = -ENOMEM; + goto out_freeirq_tx; + } + + memset(p, 0, size); + priv->rx_desc_alloc_size = size; + priv->rx_desc_cpu = p; + + /* allocate tx dma ring */ + size = priv->tx_ring_size * sizeof(struct bcm_enet_desc); + p = dma_alloc_coherent(kdev, size, &priv->tx_desc_dma, GFP_KERNEL); + if (!p) { + dev_err(kdev, "cannot allocate tx ring\n"); + ret = -ENOMEM; + goto out_free_rx_ring; + } + + memset(p, 0, size); + priv->tx_desc_alloc_size = size; + priv->tx_desc_cpu = p; + + priv->tx_skb = kzalloc(sizeof(struct sk_buff *) * priv->tx_ring_size, + GFP_KERNEL); + if (!priv->tx_skb) { + dev_err(kdev, "cannot allocate rx skb queue\n"); + ret = -ENOMEM; + goto out_free_tx_ring; + } + + priv->tx_desc_count = priv->tx_ring_size; + priv->tx_dirty_desc = 0; + priv->tx_curr_desc = 0; + spin_lock_init(&priv->tx_lock); + + /* init & fill rx ring with skbs */ + priv->rx_skb = kzalloc(sizeof(struct sk_buff *) * priv->rx_ring_size, + GFP_KERNEL); + if (!priv->rx_skb) { + dev_err(kdev, "cannot allocate rx skb queue\n"); + ret = -ENOMEM; + goto out_free_tx_skb; + } + + priv->rx_desc_count = 0; + priv->rx_dirty_desc = 0; + priv->rx_curr_desc = 0; + + /* initialize flow control buffer allocation */ + enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0, + ENETDMA_BUFALLOC_REG(priv->rx_chan)); + + if (bcm_enet_refill_rx(dev)) { + dev_err(kdev, "cannot allocate rx skb queue\n"); + ret = -ENOMEM; + goto out; + } + + /* write rx & tx ring addresses */ + enet_dma_writel(priv, priv->rx_desc_dma, + ENETDMA_RSTART_REG(priv->rx_chan)); + enet_dma_writel(priv, priv->tx_desc_dma, + ENETDMA_RSTART_REG(priv->tx_chan)); + + /* clear remaining state ram for rx & tx channel */ + enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->rx_chan)); + enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->tx_chan)); + enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->rx_chan)); + enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->tx_chan)); + enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->rx_chan)); + enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->tx_chan)); + + /* set max rx/tx length */ + enet_writel(priv, priv->hw_mtu, ENET_RXMAXLEN_REG); + enet_writel(priv, priv->hw_mtu, ENET_TXMAXLEN_REG); + + /* set dma maximum burst len */ + enet_dma_writel(priv, BCMENET_DMA_MAXBURST, + ENETDMA_MAXBURST_REG(priv->rx_chan)); + enet_dma_writel(priv, BCMENET_DMA_MAXBURST, + ENETDMA_MAXBURST_REG(priv->tx_chan)); + + /* set correct transmit fifo watermark */ + enet_writel(priv, BCMENET_TX_FIFO_TRESH, ENET_TXWMARK_REG); + + /* set flow control low/high threshold to 1/3 / 2/3 */ + val = priv->rx_ring_size / 3; + enet_dma_writel(priv, val, ENETDMA_FLOWCL_REG(priv->rx_chan)); + val = (priv->rx_ring_size * 2) / 3; + enet_dma_writel(priv, val, ENETDMA_FLOWCH_REG(priv->rx_chan)); + + /* all set, enable mac and interrupts, start dma engine and + * kick rx dma channel */ + wmb(); + enet_writel(priv, ENET_CTL_ENABLE_MASK, ENET_CTL_REG); + enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG); + enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK, + ENETDMA_CHANCFG_REG(priv->rx_chan)); + + /* watch "mib counters about to overflow" interrupt */ + enet_writel(priv, ENET_IR_MIB, ENET_IR_REG); + enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG); + + /* watch "packet transferred" interrupt in rx and tx */ + enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, + ENETDMA_IR_REG(priv->rx_chan)); + enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, + ENETDMA_IR_REG(priv->tx_chan)); + + /* make sure we enable napi before rx interrupt */ + napi_enable(&priv->napi); + + enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, + ENETDMA_IRMASK_REG(priv->rx_chan)); + enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, + ENETDMA_IRMASK_REG(priv->tx_chan)); + + if (priv->has_phy) + phy_start(priv->phydev); + else + bcm_enet_adjust_link(dev); + + netif_start_queue(dev); + return 0; + +out: + for (i = 0; i < priv->rx_ring_size; i++) { + struct bcm_enet_desc *desc; + + if (!priv->rx_skb[i]) + continue; + + desc = &priv->rx_desc_cpu[i]; + dma_unmap_single(kdev, desc->address, priv->rx_skb_size, + DMA_FROM_DEVICE); + kfree_skb(priv->rx_skb[i]); + } + kfree(priv->rx_skb); + +out_free_tx_skb: + kfree(priv->tx_skb); + +out_free_tx_ring: + dma_free_coherent(kdev, priv->tx_desc_alloc_size, + priv->tx_desc_cpu, priv->tx_desc_dma); + +out_free_rx_ring: + dma_free_coherent(kdev, priv->rx_desc_alloc_size, + priv->rx_desc_cpu, priv->rx_desc_dma); + +out_freeirq_tx: + free_irq(priv->irq_tx, dev); + +out_freeirq_rx: + free_irq(priv->irq_rx, dev); + +out_freeirq: + free_irq(dev->irq, dev); + +out_phy_disconnect: + phy_disconnect(priv->phydev); + + return ret; +} + +/* + * disable mac + */ +static void bcm_enet_disable_mac(struct bcm_enet_priv *priv) +{ + int limit; + u32 val; + + val = enet_readl(priv, ENET_CTL_REG); + val |= ENET_CTL_DISABLE_MASK; + enet_writel(priv, val, ENET_CTL_REG); + + limit = 1000; + do { + u32 val; + + val = enet_readl(priv, ENET_CTL_REG); + if (!(val & ENET_CTL_DISABLE_MASK)) + break; + udelay(1); + } while (limit--); +} + +/* + * disable dma in given channel + */ +static void bcm_enet_disable_dma(struct bcm_enet_priv *priv, int chan) +{ + int limit; + + enet_dma_writel(priv, 0, ENETDMA_CHANCFG_REG(chan)); + + limit = 1000; + do { + u32 val; + + val = enet_dma_readl(priv, ENETDMA_CHANCFG_REG(chan)); + if (!(val & ENETDMA_CHANCFG_EN_MASK)) + break; + udelay(1); + } while (limit--); +} + +/* + * stop callback + */ +static int bcm_enet_stop(struct net_device *dev) +{ + struct bcm_enet_priv *priv; + struct device *kdev; + int i; + + priv = netdev_priv(dev); + kdev = &priv->pdev->dev; + + netif_stop_queue(dev); + napi_disable(&priv->napi); + if (priv->has_phy) + phy_stop(priv->phydev); + del_timer_sync(&priv->rx_timeout); + + /* mask all interrupts */ + enet_writel(priv, 0, ENET_IRMASK_REG); + enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan)); + enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan)); + + /* make sure no mib update is scheduled */ + flush_scheduled_work(); + + /* disable dma & mac */ + bcm_enet_disable_dma(priv, priv->tx_chan); + bcm_enet_disable_dma(priv, priv->rx_chan); + bcm_enet_disable_mac(priv); + + /* force reclaim of all tx buffers */ + bcm_enet_tx_reclaim(dev, 1); + + /* free the rx skb ring */ + for (i = 0; i < priv->rx_ring_size; i++) { + struct bcm_enet_desc *desc; + + if (!priv->rx_skb[i]) + continue; + + desc = &priv->rx_desc_cpu[i]; + dma_unmap_single(kdev, desc->address, priv->rx_skb_size, + DMA_FROM_DEVICE); + kfree_skb(priv->rx_skb[i]); + } + + /* free remaining allocated memory */ + kfree(priv->rx_skb); + kfree(priv->tx_skb); + dma_free_coherent(kdev, priv->rx_desc_alloc_size, + priv->rx_desc_cpu, priv->rx_desc_dma); + dma_free_coherent(kdev, priv->tx_desc_alloc_size, + priv->tx_desc_cpu, priv->tx_desc_dma); + free_irq(priv->irq_tx, dev); + free_irq(priv->irq_rx, dev); + free_irq(dev->irq, dev); + + /* release phy */ + if (priv->has_phy) { + phy_disconnect(priv->phydev); + priv->phydev = NULL; + } + + return 0; +} + +/* + * core request to return device rx/tx stats + */ +static struct net_device_stats *bcm_enet_get_stats(struct net_device *dev) +{ + struct bcm_enet_priv *priv; + + priv = netdev_priv(dev); + return &priv->stats; +} + +/* + * ethtool callbacks + */ +struct bcm_enet_stats { + char stat_string[ETH_GSTRING_LEN]; + int sizeof_stat; + int stat_offset; + int mib_reg; +}; + +#define GEN_STAT(m) sizeof(((struct bcm_enet_priv *)0)->m), \ + offsetof(struct bcm_enet_priv, m) + +static const struct bcm_enet_stats bcm_enet_gstrings_stats[] = { + { "rx_packets", GEN_STAT(stats.rx_packets), -1 }, + { "tx_packets", GEN_STAT(stats.tx_packets), -1 }, + { "rx_bytes", GEN_STAT(stats.rx_bytes), -1 }, + { "tx_bytes", GEN_STAT(stats.tx_bytes), -1 }, + { "rx_errors", GEN_STAT(stats.rx_errors), -1 }, + { "tx_errors", GEN_STAT(stats.tx_errors), -1 }, + { "rx_dropped", GEN_STAT(stats.rx_dropped), -1 }, + { "tx_dropped", GEN_STAT(stats.tx_dropped), -1 }, + + { "rx_good_octets", GEN_STAT(mib.rx_gd_octets), ETH_MIB_RX_GD_OCTETS}, + { "rx_good_pkts", GEN_STAT(mib.rx_gd_pkts), ETH_MIB_RX_GD_PKTS }, + { "rx_broadcast", GEN_STAT(mib.rx_brdcast), ETH_MIB_RX_BRDCAST }, + { "rx_multicast", GEN_STAT(mib.rx_mult), ETH_MIB_RX_MULT }, + { "rx_64_octets", GEN_STAT(mib.rx_64), ETH_MIB_RX_64 }, + { "rx_65_127_oct", GEN_STAT(mib.rx_65_127), ETH_MIB_RX_65_127 }, + { "rx_128_255_oct", GEN_STAT(mib.rx_128_255), ETH_MIB_RX_128_255 }, + { "rx_256_511_oct", GEN_STAT(mib.rx_256_511), ETH_MIB_RX_256_511 }, + { "rx_512_1023_oct", GEN_STAT(mib.rx_512_1023), ETH_MIB_RX_512_1023 }, + { "rx_1024_max_oct", GEN_STAT(mib.rx_1024_max), ETH_MIB_RX_1024_MAX }, + { "rx_jabber", GEN_STAT(mib.rx_jab), ETH_MIB_RX_JAB }, + { "rx_oversize", GEN_STAT(mib.rx_ovr), ETH_MIB_RX_OVR }, + { "rx_fragment", GEN_STAT(mib.rx_frag), ETH_MIB_RX_FRAG }, + { "rx_dropped", GEN_STAT(mib.rx_drop), ETH_MIB_RX_DROP }, + { "rx_crc_align", GEN_STAT(mib.rx_crc_align), ETH_MIB_RX_CRC_ALIGN }, + { "rx_undersize", GEN_STAT(mib.rx_und), ETH_MIB_RX_UND }, + { "rx_crc", GEN_STAT(mib.rx_crc), ETH_MIB_RX_CRC }, + { "rx_align", GEN_STAT(mib.rx_align), ETH_MIB_RX_ALIGN }, + { "rx_symbol_error", GEN_STAT(mib.rx_sym), ETH_MIB_RX_SYM }, + { "rx_pause", GEN_STAT(mib.rx_pause), ETH_MIB_RX_PAUSE }, + { "rx_control", GEN_STAT(mib.rx_cntrl), ETH_MIB_RX_CNTRL }, + + { "tx_good_octets", GEN_STAT(mib.tx_gd_octets), ETH_MIB_TX_GD_OCTETS }, + { "tx_good_pkts", GEN_STAT(mib.tx_gd_pkts), ETH_MIB_TX_GD_PKTS }, + { "tx_broadcast", GEN_STAT(mib.tx_brdcast), ETH_MIB_TX_BRDCAST }, + { "tx_multicast", GEN_STAT(mib.tx_mult), ETH_MIB_TX_MULT }, + { "tx_64_oct", GEN_STAT(mib.tx_64), ETH_MIB_TX_64 }, + { "tx_65_127_oct", GEN_STAT(mib.tx_65_127), ETH_MIB_TX_65_127 }, + { "tx_128_255_oct", GEN_STAT(mib.tx_128_255), ETH_MIB_TX_128_255 }, + { "tx_256_511_oct", GEN_STAT(mib.tx_256_511), ETH_MIB_TX_256_511 }, + { "tx_512_1023_oct", GEN_STAT(mib.tx_512_1023), ETH_MIB_TX_512_1023}, + { "tx_1024_max_oct", GEN_STAT(mib.tx_1024_max), ETH_MIB_TX_1024_MAX }, + { "tx_jabber", GEN_STAT(mib.tx_jab), ETH_MIB_TX_JAB }, + { "tx_oversize", GEN_STAT(mib.tx_ovr), ETH_MIB_TX_OVR }, + { "tx_fragment", GEN_STAT(mib.tx_frag), ETH_MIB_TX_FRAG }, + { "tx_underrun", GEN_STAT(mib.tx_underrun), ETH_MIB_TX_UNDERRUN }, + { "tx_collisions", GEN_STAT(mib.tx_col), ETH_MIB_TX_COL }, + { "tx_single_collision", GEN_STAT(mib.tx_1_col), ETH_MIB_TX_1_COL }, + { "tx_multiple_collision", GEN_STAT(mib.tx_m_col), ETH_MIB_TX_M_COL }, + { "tx_excess_collision", GEN_STAT(mib.tx_ex_col), ETH_MIB_TX_EX_COL }, + { "tx_late_collision", GEN_STAT(mib.tx_late), ETH_MIB_TX_LATE }, + { "tx_deferred", GEN_STAT(mib.tx_def), ETH_MIB_TX_DEF }, + { "tx_carrier_sense", GEN_STAT(mib.tx_crs), ETH_MIB_TX_CRS }, + { "tx_pause", GEN_STAT(mib.tx_pause), ETH_MIB_TX_PAUSE }, + +}; + +#define BCM_ENET_STATS_LEN \ + (sizeof(bcm_enet_gstrings_stats) / sizeof(struct bcm_enet_stats)) + +static const u32 unused_mib_regs[] = { + ETH_MIB_TX_ALL_OCTETS, + ETH_MIB_TX_ALL_PKTS, + ETH_MIB_RX_ALL_OCTETS, + ETH_MIB_RX_ALL_PKTS, +}; + + +static void bcm_enet_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *drvinfo) +{ + strncpy(drvinfo->driver, bcm_enet_driver_name, 32); + strncpy(drvinfo->version, bcm_enet_driver_version, 32); + strncpy(drvinfo->fw_version, "N/A", 32); + strncpy(drvinfo->bus_info, "bcm63xx", 32); + drvinfo->n_stats = BCM_ENET_STATS_LEN; +} + +static int bcm_enet_get_stats_count(struct net_device *netdev) +{ + return BCM_ENET_STATS_LEN; +} + +static void bcm_enet_get_strings(struct net_device *netdev, + u32 stringset, u8 *data) +{ + int i; + + switch (stringset) { + case ETH_SS_STATS: + for (i = 0; i < BCM_ENET_STATS_LEN; i++) { + memcpy(data + i * ETH_GSTRING_LEN, + bcm_enet_gstrings_stats[i].stat_string, + ETH_GSTRING_LEN); + } + break; + } +} + +static void update_mib_counters(struct bcm_enet_priv *priv) +{ + int i; + + for (i = 0; i < BCM_ENET_STATS_LEN; i++) { + const struct bcm_enet_stats *s; + u32 val; + char *p; + + s = &bcm_enet_gstrings_stats[i]; + if (s->mib_reg == -1) + continue; + + val = enet_readl(priv, ENET_MIB_REG(s->mib_reg)); + p = (char *)priv + s->stat_offset; + + if (s->sizeof_stat == sizeof(u64)) + *(u64 *)p += val; + else + *(u32 *)p += val; + } + + /* also empty unused mib counters to make sure mib counter + * overflow interrupt is cleared */ + for (i = 0; i < ARRAY_SIZE(unused_mib_regs); i++) + (void)enet_readl(priv, ENET_MIB_REG(unused_mib_regs[i])); +} + +static void bcm_enet_update_mib_counters_defer(struct work_struct *t) +{ + struct bcm_enet_priv *priv; + + priv = container_of(t, struct bcm_enet_priv, mib_update_task); + mutex_lock(&priv->mib_update_lock); + update_mib_counters(priv); + mutex_unlock(&priv->mib_update_lock); + + /* reenable mib interrupt */ + if (netif_running(priv->net_dev)) + enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG); +} + +static void bcm_enet_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats *stats, + u64 *data) +{ + struct bcm_enet_priv *priv; + int i; + + priv = netdev_priv(netdev); + + mutex_lock(&priv->mib_update_lock); + update_mib_counters(priv); + + for (i = 0; i < BCM_ENET_STATS_LEN; i++) { + const struct bcm_enet_stats *s; + char *p; + + s = &bcm_enet_gstrings_stats[i]; + p = (char *)priv + s->stat_offset; + data[i] = (s->sizeof_stat == sizeof(u64)) ? + *(u64 *)p : *(u32 *)p; + } + mutex_unlock(&priv->mib_update_lock); +} + +static int bcm_enet_get_settings(struct net_device *dev, + struct ethtool_cmd *cmd) +{ + struct bcm_enet_priv *priv; + + priv = netdev_priv(dev); + + cmd->maxrxpkt = 0; + cmd->maxtxpkt = 0; + + if (priv->has_phy) { + if (!priv->phydev) + return -ENODEV; + return phy_ethtool_gset(priv->phydev, cmd); + } else { + cmd->autoneg = 0; + cmd->speed = (priv->force_speed_100) ? SPEED_100 : SPEED_10; + cmd->duplex = (priv->force_duplex_full) ? + DUPLEX_FULL : DUPLEX_HALF; + cmd->supported = ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full; + cmd->advertising = 0; + cmd->port = PORT_MII; + cmd->transceiver = XCVR_EXTERNAL; + } + return 0; +} + +static int bcm_enet_set_settings(struct net_device *dev, + struct ethtool_cmd *cmd) +{ + struct bcm_enet_priv *priv; + + priv = netdev_priv(dev); + if (priv->has_phy) { + if (!priv->phydev) + return -ENODEV; + return phy_ethtool_sset(priv->phydev, cmd); + } else { + + if (cmd->autoneg || + (cmd->speed != SPEED_100 && cmd->speed != SPEED_10) || + cmd->port != PORT_MII) + return -EINVAL; + + priv->force_speed_100 = (cmd->speed == SPEED_100) ? 1 : 0; + priv->force_duplex_full = (cmd->duplex == DUPLEX_FULL) ? 1 : 0; + + if (netif_running(dev)) + bcm_enet_adjust_link(dev); + return 0; + } +} + +static void bcm_enet_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *ering) +{ + struct bcm_enet_priv *priv; + + priv = netdev_priv(dev); + + /* rx/tx ring is actually only limited by memory */ + ering->rx_max_pending = 8192; + ering->tx_max_pending = 8192; + ering->rx_mini_max_pending = 0; + ering->rx_jumbo_max_pending = 0; + ering->rx_pending = priv->rx_ring_size; + ering->tx_pending = priv->tx_ring_size; +} + +static int bcm_enet_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *ering) +{ + struct bcm_enet_priv *priv; + int was_running; + + priv = netdev_priv(dev); + + was_running = 0; + if (netif_running(dev)) { + bcm_enet_stop(dev); + was_running = 1; + } + + priv->rx_ring_size = ering->rx_pending; + priv->tx_ring_size = ering->tx_pending; + + if (was_running) { + int err; + + err = bcm_enet_open(dev); + if (err) + dev_close(dev); + else + bcm_enet_set_multicast_list(dev); + } + return 0; +} + +static void bcm_enet_get_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *ecmd) +{ + struct bcm_enet_priv *priv; + + priv = netdev_priv(dev); + ecmd->autoneg = priv->pause_auto; + ecmd->rx_pause = priv->pause_rx; + ecmd->tx_pause = priv->pause_tx; +} + +static int bcm_enet_set_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *ecmd) +{ + struct bcm_enet_priv *priv; + + priv = netdev_priv(dev); + + if (priv->has_phy) { + if (ecmd->autoneg && (ecmd->rx_pause != ecmd->tx_pause)) { + /* asymetric pause mode not supported, + * actually possible but integrated PHY has RO + * asym_pause bit */ + return -EINVAL; + } + } else { + /* no pause autoneg on direct mii connection */ + if (ecmd->autoneg) + return -EINVAL; + } + + priv->pause_auto = ecmd->autoneg; + priv->pause_rx = ecmd->rx_pause; + priv->pause_tx = ecmd->tx_pause; + + return 0; +} + +static struct ethtool_ops bcm_enet_ethtool_ops = { + .get_strings = bcm_enet_get_strings, + .get_stats_count = bcm_enet_get_stats_count, + .get_ethtool_stats = bcm_enet_get_ethtool_stats, + .get_settings = bcm_enet_get_settings, + .set_settings = bcm_enet_set_settings, + .get_drvinfo = bcm_enet_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_ringparam = bcm_enet_get_ringparam, + .set_ringparam = bcm_enet_set_ringparam, + .get_pauseparam = bcm_enet_get_pauseparam, + .set_pauseparam = bcm_enet_set_pauseparam, +}; + +static int bcm_enet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct bcm_enet_priv *priv; + + priv = netdev_priv(dev); + if (priv->has_phy) { + if (!priv->phydev) + return -ENODEV; + return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd); + } else { + struct mii_if_info mii; + + mii.dev = dev; + mii.mdio_read = bcm_enet_mdio_read_mii; + mii.mdio_write = bcm_enet_mdio_write_mii; + mii.phy_id = 0; + mii.phy_id_mask = 0x3f; + mii.reg_num_mask = 0x1f; + return generic_mii_ioctl(&mii, if_mii(rq), cmd, NULL); + } +} + +/* + * calculate actual hardware mtu + */ +static int compute_hw_mtu(struct bcm_enet_priv *priv, int mtu) +{ + int actual_mtu; + + actual_mtu = mtu; + + /* add ethernet header + vlan tag size */ + actual_mtu += VLAN_ETH_HLEN; + + if (actual_mtu < 64 || actual_mtu > BCMENET_MAX_MTU) + return -EINVAL; + + /* + * setup maximum size before we get overflow mark in + * descriptor, note that this will not prevent reception of + * big frames, they will be split into multiple buffers + * anyway + */ + priv->hw_mtu = actual_mtu; + + /* + * align rx buffer size to dma burst len, account FCS since + * it's appended + */ + priv->rx_skb_size = ALIGN(actual_mtu + ETH_FCS_LEN, + BCMENET_DMA_MAXBURST * 4); + return 0; +} + +/* + * adjust mtu, can't be called while device is running + */ +static int bcm_enet_change_mtu(struct net_device *dev, int new_mtu) +{ + int ret; + + if (netif_running(dev)) + return -EBUSY; + + ret = compute_hw_mtu(netdev_priv(dev), new_mtu); + if (ret) + return ret; + dev->mtu = new_mtu; + return 0; +} + +/* + * preinit hardware to allow mii operation while device is down + */ +static void bcm_enet_hw_preinit(struct bcm_enet_priv *priv) +{ + u32 val; + int limit; + + /* make sure mac is disabled */ + bcm_enet_disable_mac(priv); + + /* soft reset mac */ + val = ENET_CTL_SRESET_MASK; + enet_writel(priv, val, ENET_CTL_REG); + wmb(); + + limit = 1000; + do { + val = enet_readl(priv, ENET_CTL_REG); + if (!(val & ENET_CTL_SRESET_MASK)) + break; + udelay(1); + } while (limit--); + + /* select correct mii interface */ + val = enet_readl(priv, ENET_CTL_REG); + if (priv->use_external_mii) + val |= ENET_CTL_EPHYSEL_MASK; + else + val &= ~ENET_CTL_EPHYSEL_MASK; + enet_writel(priv, val, ENET_CTL_REG); + + /* turn on mdc clock */ + enet_writel(priv, (0x1f << ENET_MIISC_MDCFREQDIV_SHIFT) | + ENET_MIISC_PREAMBLEEN_MASK, ENET_MIISC_REG); + + /* set mib counters to self-clear when read */ + val = enet_readl(priv, ENET_MIBCTL_REG); + val |= ENET_MIBCTL_RDCLEAR_MASK; + enet_writel(priv, val, ENET_MIBCTL_REG); +} + +static const struct net_device_ops bcm_enet_ops = { + .ndo_open = bcm_enet_open, + .ndo_stop = bcm_enet_stop, + .ndo_start_xmit = bcm_enet_start_xmit, + .ndo_get_stats = bcm_enet_get_stats, + .ndo_set_mac_address = bcm_enet_set_mac_address, + .ndo_set_multicast_list = bcm_enet_set_multicast_list, + .ndo_do_ioctl = bcm_enet_ioctl, + .ndo_change_mtu = bcm_enet_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = bcm_enet_netpoll, +#endif +}; + +/* + * allocate netdevice, request register memory and register device. + */ +static int __devinit bcm_enet_probe(struct platform_device *pdev) +{ + struct bcm_enet_priv *priv; + struct net_device *dev; + struct bcm63xx_enet_platform_data *pd; + struct resource *res_mem, *res_irq, *res_irq_rx, *res_irq_tx; + struct mii_bus *bus; + const char *clk_name; + unsigned int iomem_size; + int i, ret; + + /* stop if shared driver failed, assume driver->probe will be + * called in the same order we register devices (correct ?) */ + if (!bcm_enet_shared_base) + return -ENODEV; + + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + res_irq_rx = platform_get_resource(pdev, IORESOURCE_IRQ, 1); + res_irq_tx = platform_get_resource(pdev, IORESOURCE_IRQ, 2); + if (!res_mem || !res_irq || !res_irq_rx || !res_irq_tx) + return -ENODEV; + + ret = 0; + dev = alloc_etherdev(sizeof(*priv)); + if (!dev) + return -ENOMEM; + priv = netdev_priv(dev); + memset(priv, 0, sizeof(*priv)); + + ret = compute_hw_mtu(priv, dev->mtu); + if (ret) + goto out; + + iomem_size = res_mem->end - res_mem->start + 1; + if (!request_mem_region(res_mem->start, iomem_size, "bcm63xx_enet")) { + ret = -EBUSY; + goto out; + } + + priv->base = ioremap(res_mem->start, iomem_size); + if (priv->base == NULL) { + ret = -ENOMEM; + goto out_release_mem; + } + dev->irq = priv->irq = res_irq->start; + priv->irq_rx = res_irq_rx->start; + priv->irq_tx = res_irq_tx->start; + priv->mac_id = pdev->id; + + /* get rx & tx dma channel id for this mac */ + if (priv->mac_id == 0) { + priv->rx_chan = 0; + priv->tx_chan = 1; + clk_name = "enet0"; + } else { + priv->rx_chan = 2; + priv->tx_chan = 3; + clk_name = "enet1"; + } + + priv->mac_clk = clk_get(&pdev->dev, clk_name); + if (IS_ERR(priv->mac_clk)) { + ret = PTR_ERR(priv->mac_clk); + goto out_unmap; + } + clk_enable(priv->mac_clk); + + /* initialize default and fetch platform data */ + priv->rx_ring_size = BCMENET_DEF_RX_DESC; + priv->tx_ring_size = BCMENET_DEF_TX_DESC; + + pd = pdev->dev.platform_data; + if (pd) { + memcpy(dev->dev_addr, pd->mac_addr, ETH_ALEN); + priv->has_phy = pd->has_phy; + priv->phy_id = pd->phy_id; + priv->has_phy_interrupt = pd->has_phy_interrupt; + priv->phy_interrupt = pd->phy_interrupt; + priv->use_external_mii = !pd->use_internal_phy; + priv->pause_auto = pd->pause_auto; + priv->pause_rx = pd->pause_rx; + priv->pause_tx = pd->pause_tx; + priv->force_duplex_full = pd->force_duplex_full; + priv->force_speed_100 = pd->force_speed_100; + } + + if (priv->mac_id == 0 && priv->has_phy && !priv->use_external_mii) { + /* using internal PHY, enable clock */ + priv->phy_clk = clk_get(&pdev->dev, "ephy"); + if (IS_ERR(priv->phy_clk)) { + ret = PTR_ERR(priv->phy_clk); + priv->phy_clk = NULL; + goto out_put_clk_mac; + } + clk_enable(priv->phy_clk); + } + + /* do minimal hardware init to be able to probe mii bus */ + bcm_enet_hw_preinit(priv); + + /* MII bus registration */ + if (priv->has_phy) { + + priv->mii_bus = mdiobus_alloc(); + if (!priv->mii_bus) { + ret = -ENOMEM; + goto out_uninit_hw; + } + + bus = priv->mii_bus; + bus->name = "bcm63xx_enet MII bus"; + bus->parent = &pdev->dev; + bus->priv = priv; + bus->read = bcm_enet_mdio_read_phylib; + bus->write = bcm_enet_mdio_write_phylib; + sprintf(bus->id, "%d", priv->mac_id); + + /* only probe bus where we think the PHY is, because + * the mdio read operation return 0 instead of 0xffff + * if a slave is not present on hw */ + bus->phy_mask = ~(1 << priv->phy_id); + + bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); + if (!bus->irq) { + ret = -ENOMEM; + goto out_free_mdio; + } + + if (priv->has_phy_interrupt) + bus->irq[priv->phy_id] = priv->phy_interrupt; + else + bus->irq[priv->phy_id] = PHY_POLL; + + ret = mdiobus_register(bus); + if (ret) { + dev_err(&pdev->dev, "unable to register mdio bus\n"); + goto out_free_mdio; + } + } else { + + /* run platform code to initialize PHY device */ + if (pd->mii_config && + pd->mii_config(dev, 1, bcm_enet_mdio_read_mii, + bcm_enet_mdio_write_mii)) { + dev_err(&pdev->dev, "unable to configure mdio bus\n"); + goto out_uninit_hw; + } + } + + spin_lock_init(&priv->rx_lock); + + /* init rx timeout (used for oom) */ + init_timer(&priv->rx_timeout); + priv->rx_timeout.function = bcm_enet_refill_rx_timer; + priv->rx_timeout.data = (unsigned long)dev; + + /* init the mib update lock&work */ + mutex_init(&priv->mib_update_lock); + INIT_WORK(&priv->mib_update_task, bcm_enet_update_mib_counters_defer); + + /* zero mib counters */ + for (i = 0; i < ENET_MIB_REG_COUNT; i++) + enet_writel(priv, 0, ENET_MIB_REG(i)); + + /* register netdevice */ + dev->netdev_ops = &bcm_enet_ops; + netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16); + + SET_ETHTOOL_OPS(dev, &bcm_enet_ethtool_ops); + SET_NETDEV_DEV(dev, &pdev->dev); + + ret = register_netdev(dev); + if (ret) + goto out_unregister_mdio; + + netif_carrier_off(dev); + platform_set_drvdata(pdev, dev); + priv->pdev = pdev; + priv->net_dev = dev; + + return 0; + +out_unregister_mdio: + if (priv->mii_bus) { + mdiobus_unregister(priv->mii_bus); + kfree(priv->mii_bus->irq); + } + +out_free_mdio: + if (priv->mii_bus) + mdiobus_free(priv->mii_bus); + +out_uninit_hw: + /* turn off mdc clock */ + enet_writel(priv, 0, ENET_MIISC_REG); + if (priv->phy_clk) { + clk_disable(priv->phy_clk); + clk_put(priv->phy_clk); + } + +out_put_clk_mac: + clk_disable(priv->mac_clk); + clk_put(priv->mac_clk); + +out_unmap: + iounmap(priv->base); + +out_release_mem: + release_mem_region(res_mem->start, iomem_size); +out: + free_netdev(dev); + return ret; +} + + +/* + * exit func, stops hardware and unregisters netdevice + */ +static int __devexit bcm_enet_remove(struct platform_device *pdev) +{ + struct bcm_enet_priv *priv; + struct net_device *dev; + struct resource *res; + + /* stop netdevice */ + dev = platform_get_drvdata(pdev); + priv = netdev_priv(dev); + unregister_netdev(dev); + + /* turn off mdc clock */ + enet_writel(priv, 0, ENET_MIISC_REG); + + if (priv->has_phy) { + mdiobus_unregister(priv->mii_bus); + kfree(priv->mii_bus->irq); + mdiobus_free(priv->mii_bus); + } else { + struct bcm63xx_enet_platform_data *pd; + + pd = pdev->dev.platform_data; + if (pd && pd->mii_config) + pd->mii_config(dev, 0, bcm_enet_mdio_read_mii, + bcm_enet_mdio_write_mii); + } + + /* release device resources */ + iounmap(priv->base); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, res->end - res->start + 1); + + /* disable hw block clocks */ + if (priv->phy_clk) { + clk_disable(priv->phy_clk); + clk_put(priv->phy_clk); + } + clk_disable(priv->mac_clk); + clk_put(priv->mac_clk); + + platform_set_drvdata(pdev, NULL); + free_netdev(dev); + return 0; +} + +struct platform_driver bcm63xx_enet_driver = { + .probe = bcm_enet_probe, + .remove = __devexit_p(bcm_enet_remove), + .driver = { + .name = "bcm63xx_enet", + .owner = THIS_MODULE, + }, +}; + +/* + * reserve & remap memory space shared between all macs + */ +static int __devinit bcm_enet_shared_probe(struct platform_device *pdev) +{ + struct resource *res; + unsigned int iomem_size; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + iomem_size = res->end - res->start + 1; + if (!request_mem_region(res->start, iomem_size, "bcm63xx_enet_dma")) + return -EBUSY; + + bcm_enet_shared_base = ioremap(res->start, iomem_size); + if (!bcm_enet_shared_base) { + release_mem_region(res->start, iomem_size); + return -ENOMEM; + } + return 0; +} + +static int __devexit bcm_enet_shared_remove(struct platform_device *pdev) +{ + struct resource *res; + + iounmap(bcm_enet_shared_base); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, res->end - res->start + 1); + return 0; +} + +/* + * this "shared" driver is needed because both macs share a single + * address space + */ +struct platform_driver bcm63xx_enet_shared_driver = { + .probe = bcm_enet_shared_probe, + .remove = __devexit_p(bcm_enet_shared_remove), + .driver = { + .name = "bcm63xx_enet_shared", + .owner = THIS_MODULE, + }, +}; + +/* + * entry point + */ +static int __init bcm_enet_init(void) +{ + int ret; + + ret = platform_driver_register(&bcm63xx_enet_shared_driver); + if (ret) + return ret; + + ret = platform_driver_register(&bcm63xx_enet_driver); + if (ret) + platform_driver_unregister(&bcm63xx_enet_shared_driver); + + return ret; +} + +static void __exit bcm_enet_exit(void) +{ + platform_driver_unregister(&bcm63xx_enet_driver); + platform_driver_unregister(&bcm63xx_enet_shared_driver); +} + + +module_init(bcm_enet_init); +module_exit(bcm_enet_exit); + +MODULE_DESCRIPTION("BCM63xx internal ethernet mac driver"); +MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/bcm63xx_enet.h b/drivers/net/bcm63xx_enet.h new file mode 100644 index 00000000000..bd3684d42d7 --- /dev/null +++ b/drivers/net/bcm63xx_enet.h @@ -0,0 +1,303 @@ +#ifndef BCM63XX_ENET_H_ +#define BCM63XX_ENET_H_ + +#include <linux/types.h> +#include <linux/mii.h> +#include <linux/mutex.h> +#include <linux/phy.h> +#include <linux/platform_device.h> + +#include <bcm63xx_regs.h> +#include <bcm63xx_irq.h> +#include <bcm63xx_io.h> + +/* default number of descriptor */ +#define BCMENET_DEF_RX_DESC 64 +#define BCMENET_DEF_TX_DESC 32 + +/* maximum burst len for dma (4 bytes unit) */ +#define BCMENET_DMA_MAXBURST 16 + +/* tx transmit threshold (4 bytes unit), fifo is 256 bytes, the value + * must be low enough so that a DMA transfer of above burst length can + * not overflow the fifo */ +#define BCMENET_TX_FIFO_TRESH 32 + +/* + * hardware maximum rx/tx packet size including FCS, max mtu is + * actually 2047, but if we set max rx size register to 2047 we won't + * get overflow information if packet size is 2048 or above + */ +#define BCMENET_MAX_MTU 2046 + +/* + * rx/tx dma descriptor + */ +struct bcm_enet_desc { + u32 len_stat; + u32 address; +}; + +#define DMADESC_LENGTH_SHIFT 16 +#define DMADESC_LENGTH_MASK (0xfff << DMADESC_LENGTH_SHIFT) +#define DMADESC_OWNER_MASK (1 << 15) +#define DMADESC_EOP_MASK (1 << 14) +#define DMADESC_SOP_MASK (1 << 13) +#define DMADESC_ESOP_MASK (DMADESC_EOP_MASK | DMADESC_SOP_MASK) +#define DMADESC_WRAP_MASK (1 << 12) + +#define DMADESC_UNDER_MASK (1 << 9) +#define DMADESC_APPEND_CRC (1 << 8) +#define DMADESC_OVSIZE_MASK (1 << 4) +#define DMADESC_RXER_MASK (1 << 2) +#define DMADESC_CRC_MASK (1 << 1) +#define DMADESC_OV_MASK (1 << 0) +#define DMADESC_ERR_MASK (DMADESC_UNDER_MASK | \ + DMADESC_OVSIZE_MASK | \ + DMADESC_RXER_MASK | \ + DMADESC_CRC_MASK | \ + DMADESC_OV_MASK) + + +/* + * MIB Counters register definitions +*/ +#define ETH_MIB_TX_GD_OCTETS 0 +#define ETH_MIB_TX_GD_PKTS 1 +#define ETH_MIB_TX_ALL_OCTETS 2 +#define ETH_MIB_TX_ALL_PKTS 3 +#define ETH_MIB_TX_BRDCAST 4 +#define ETH_MIB_TX_MULT 5 +#define ETH_MIB_TX_64 6 +#define ETH_MIB_TX_65_127 7 +#define ETH_MIB_TX_128_255 8 +#define ETH_MIB_TX_256_511 9 +#define ETH_MIB_TX_512_1023 10 +#define ETH_MIB_TX_1024_MAX 11 +#define ETH_MIB_TX_JAB 12 +#define ETH_MIB_TX_OVR 13 +#define ETH_MIB_TX_FRAG 14 +#define ETH_MIB_TX_UNDERRUN 15 +#define ETH_MIB_TX_COL 16 +#define ETH_MIB_TX_1_COL 17 +#define ETH_MIB_TX_M_COL 18 +#define ETH_MIB_TX_EX_COL 19 +#define ETH_MIB_TX_LATE 20 +#define ETH_MIB_TX_DEF 21 +#define ETH_MIB_TX_CRS 22 +#define ETH_MIB_TX_PAUSE 23 + +#define ETH_MIB_RX_GD_OCTETS 32 +#define ETH_MIB_RX_GD_PKTS 33 +#define ETH_MIB_RX_ALL_OCTETS 34 +#define ETH_MIB_RX_ALL_PKTS 35 +#define ETH_MIB_RX_BRDCAST 36 +#define ETH_MIB_RX_MULT 37 +#define ETH_MIB_RX_64 38 +#define ETH_MIB_RX_65_127 39 +#define ETH_MIB_RX_128_255 40 +#define ETH_MIB_RX_256_511 41 +#define ETH_MIB_RX_512_1023 42 +#define ETH_MIB_RX_1024_MAX 43 +#define ETH_MIB_RX_JAB 44 +#define ETH_MIB_RX_OVR 45 +#define ETH_MIB_RX_FRAG 46 +#define ETH_MIB_RX_DROP 47 +#define ETH_MIB_RX_CRC_ALIGN 48 +#define ETH_MIB_RX_UND 49 +#define ETH_MIB_RX_CRC 50 +#define ETH_MIB_RX_ALIGN 51 +#define ETH_MIB_RX_SYM 52 +#define ETH_MIB_RX_PAUSE 53 +#define ETH_MIB_RX_CNTRL 54 + + +struct bcm_enet_mib_counters { + u64 tx_gd_octets; + u32 tx_gd_pkts; + u32 tx_all_octets; + u32 tx_all_pkts; + u32 tx_brdcast; + u32 tx_mult; + u32 tx_64; + u32 tx_65_127; + u32 tx_128_255; + u32 tx_256_511; + u32 tx_512_1023; + u32 tx_1024_max; + u32 tx_jab; + u32 tx_ovr; + u32 tx_frag; + u32 tx_underrun; + u32 tx_col; + u32 tx_1_col; + u32 tx_m_col; + u32 tx_ex_col; + u32 tx_late; + u32 tx_def; + u32 tx_crs; + u32 tx_pause; + u64 rx_gd_octets; + u32 rx_gd_pkts; + u32 rx_all_octets; + u32 rx_all_pkts; + u32 rx_brdcast; + u32 rx_mult; + u32 rx_64; + u32 rx_65_127; + u32 rx_128_255; + u32 rx_256_511; + u32 rx_512_1023; + u32 rx_1024_max; + u32 rx_jab; + u32 rx_ovr; + u32 rx_frag; + u32 rx_drop; + u32 rx_crc_align; + u32 rx_und; + u32 rx_crc; + u32 rx_align; + u32 rx_sym; + u32 rx_pause; + u32 rx_cntrl; +}; + + +struct bcm_enet_priv { + + /* mac id (from platform device id) */ + int mac_id; + + /* base remapped address of device */ + void __iomem *base; + + /* mac irq, rx_dma irq, tx_dma irq */ + int irq; + int irq_rx; + int irq_tx; + + /* hw view of rx & tx dma ring */ + dma_addr_t rx_desc_dma; + dma_addr_t tx_desc_dma; + + /* allocated size (in bytes) for rx & tx dma ring */ + unsigned int rx_desc_alloc_size; + unsigned int tx_desc_alloc_size; + + + struct napi_struct napi; + + /* dma channel id for rx */ + int rx_chan; + + /* number of dma desc in rx ring */ + int rx_ring_size; + + /* cpu view of rx dma ring */ + struct bcm_enet_desc *rx_desc_cpu; + + /* current number of armed descriptor given to hardware for rx */ + int rx_desc_count; + + /* next rx descriptor to fetch from hardware */ + int rx_curr_desc; + + /* next dirty rx descriptor to refill */ + int rx_dirty_desc; + + /* size of allocated rx skbs */ + unsigned int rx_skb_size; + + /* list of skb given to hw for rx */ + struct sk_buff **rx_skb; + + /* used when rx skb allocation failed, so we defer rx queue + * refill */ + struct timer_list rx_timeout; + + /* lock rx_timeout against rx normal operation */ + spinlock_t rx_lock; + + + /* dma channel id for tx */ + int tx_chan; + + /* number of dma desc in tx ring */ + int tx_ring_size; + + /* cpu view of rx dma ring */ + struct bcm_enet_desc *tx_desc_cpu; + + /* number of available descriptor for tx */ + int tx_desc_count; + + /* next tx descriptor avaiable */ + int tx_curr_desc; + + /* next dirty tx descriptor to reclaim */ + int tx_dirty_desc; + + /* list of skb given to hw for tx */ + struct sk_buff **tx_skb; + + /* lock used by tx reclaim and xmit */ + spinlock_t tx_lock; + + + /* set if internal phy is ignored and external mii interface + * is selected */ + int use_external_mii; + + /* set if a phy is connected, phy address must be known, + * probing is not possible */ + int has_phy; + int phy_id; + + /* set if connected phy has an associated irq */ + int has_phy_interrupt; + int phy_interrupt; + + /* used when a phy is connected (phylib used) */ + struct mii_bus *mii_bus; + struct phy_device *phydev; + int old_link; + int old_duplex; + int old_pause; + + /* used when no phy is connected */ + int force_speed_100; + int force_duplex_full; + + /* pause parameters */ + int pause_auto; + int pause_rx; + int pause_tx; + + /* stats */ + struct net_device_stats stats; + struct bcm_enet_mib_counters mib; + + /* after mib interrupt, mib registers update is done in this + * work queue */ + struct work_struct mib_update_task; + + /* lock mib update between userspace request and workqueue */ + struct mutex mib_update_lock; + + /* mac clock */ + struct clk *mac_clk; + + /* phy clock if internal phy is used */ + struct clk *phy_clk; + + /* network device reference */ + struct net_device *net_dev; + + /* platform device reference */ + struct platform_device *pdev; + + /* maximum hardware transmit/receive size */ + unsigned int hw_mtu; +}; + +#endif /* ! BCM63XX_ENET_H_ */ diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 13b72ce870d..684c6fe24c8 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -362,5 +362,6 @@ static inline u8 is_udp_pkt(struct sk_buff *skb) extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped); extern void be_link_status_update(struct be_adapter *adapter, bool link_up); +extern void netdev_stats_update(struct be_adapter *adapter); extern int be_load_fw(struct be_adapter *adapter, u8 *func); #endif /* BE_H */ diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 1db09249830..3dd76c4170b 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -59,15 +59,22 @@ static int be_mcc_compl_process(struct be_adapter *adapter, compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) & CQE_STATUS_COMPL_MASK; - if (compl_status != MCC_STATUS_SUCCESS) { + if (compl_status == MCC_STATUS_SUCCESS) { + if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) { + struct be_cmd_resp_get_stats *resp = + adapter->stats.cmd.va; + be_dws_le_to_cpu(&resp->hw_stats, + sizeof(resp->hw_stats)); + netdev_stats_update(adapter); + } + } else if (compl_status != MCC_STATUS_NOT_SUPPORTED) { extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) & CQE_STATUS_EXTD_MASK; dev_warn(&adapter->pdev->dev, "Error in cmd completion: status(compl/extd)=%d/%d\n", compl_status, extd_status); - return -1; } - return 0; + return compl_status; } /* Link state evt is a string of bytes; no need for endian swapping */ @@ -97,10 +104,10 @@ static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter) return NULL; } -void be_process_mcc(struct be_adapter *adapter) +int be_process_mcc(struct be_adapter *adapter) { struct be_mcc_compl *compl; - int num = 0; + int num = 0, status = 0; spin_lock_bh(&adapter->mcc_cq_lock); while ((compl = be_mcc_compl_get(adapter))) { @@ -111,38 +118,47 @@ void be_process_mcc(struct be_adapter *adapter) /* Interpret compl as a async link evt */ be_async_link_state_process(adapter, (struct be_async_event_link_state *) compl); - } else { - be_mcc_compl_process(adapter, compl); - atomic_dec(&adapter->mcc_obj.q.used); + } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { + status = be_mcc_compl_process(adapter, compl); + atomic_dec(&adapter->mcc_obj.q.used); } be_mcc_compl_use(compl); num++; } + if (num) be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, num); + spin_unlock_bh(&adapter->mcc_cq_lock); + return status; } /* Wait till no more pending mcc requests are present */ -static void be_mcc_wait_compl(struct be_adapter *adapter) +static int be_mcc_wait_compl(struct be_adapter *adapter) { -#define mcc_timeout 50000 /* 5s timeout */ - int i; +#define mcc_timeout 120000 /* 12s timeout */ + int i, status; for (i = 0; i < mcc_timeout; i++) { - be_process_mcc(adapter); + status = be_process_mcc(adapter); + if (status) + return status; + if (atomic_read(&adapter->mcc_obj.q.used) == 0) break; udelay(100); } - if (i == mcc_timeout) + if (i == mcc_timeout) { dev_err(&adapter->pdev->dev, "mccq poll timed out\n"); + return -1; + } + return 0; } /* Notify MCC requests and wait for completion */ -static void be_mcc_notify_wait(struct be_adapter *adapter) +static int be_mcc_notify_wait(struct be_adapter *adapter) { be_mcc_notify(adapter); - be_mcc_wait_compl(adapter); + return be_mcc_wait_compl(adapter); } static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db) @@ -173,7 +189,7 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db) * Insert the mailbox address into the doorbell in two steps * Polls on the mbox doorbell till a command completion (or a timeout) occurs */ -static int be_mbox_notify(struct be_adapter *adapter) +static int be_mbox_notify_wait(struct be_adapter *adapter) { int status; u32 val = 0; @@ -182,8 +198,6 @@ static int be_mbox_notify(struct be_adapter *adapter) struct be_mcc_mailbox *mbox = mbox_mem->va; struct be_mcc_compl *compl = &mbox->compl; - memset(compl, 0, sizeof(*compl)); - val |= MPU_MAILBOX_DB_HI_MASK; /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */ val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2; @@ -310,34 +324,40 @@ static u32 eq_delay_to_mult(u32 usec_delay) return multiplier; } -static inline struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem) +static inline struct be_mcc_wrb *wrb_from_mbox(struct be_adapter *adapter) { - return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb; + struct be_dma_mem *mbox_mem = &adapter->mbox_mem; + struct be_mcc_wrb *wrb + = &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb; + memset(wrb, 0, sizeof(*wrb)); + return wrb; } -static inline struct be_mcc_wrb *wrb_from_mcc(struct be_queue_info *mccq) +static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter) { - struct be_mcc_wrb *wrb = NULL; - if (atomic_read(&mccq->used) < mccq->len) { - wrb = queue_head_node(mccq); - queue_head_inc(mccq); - atomic_inc(&mccq->used); - memset(wrb, 0, sizeof(*wrb)); - } + struct be_queue_info *mccq = &adapter->mcc_obj.q; + struct be_mcc_wrb *wrb; + + BUG_ON(atomic_read(&mccq->used) >= mccq->len); + wrb = queue_head_node(mccq); + queue_head_inc(mccq); + atomic_inc(&mccq->used); + memset(wrb, 0, sizeof(*wrb)); return wrb; } int be_cmd_eq_create(struct be_adapter *adapter, struct be_queue_info *eq, int eq_delay) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_eq_create *req = embedded_payload(wrb); - struct be_cmd_resp_eq_create *resp = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_eq_create *req; struct be_dma_mem *q_mem = &eq->dma_mem; int status; spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -359,25 +379,29 @@ int be_cmd_eq_create(struct be_adapter *adapter, be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); - status = be_mbox_notify(adapter); + status = be_mbox_notify_wait(adapter); if (!status) { + struct be_cmd_resp_eq_create *resp = embedded_payload(wrb); eq->id = le16_to_cpu(resp->eq_id); eq->created = true; } + spin_unlock(&adapter->mbox_lock); return status; } +/* Uses mbox */ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, u8 type, bool permanent, u32 if_handle) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_mac_query *req = embedded_payload(wrb); - struct be_cmd_resp_mac_query *resp = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_mac_query *req; int status; spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -388,27 +412,32 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, if (permanent) { req->permanent = 1; } else { - req->if_id = cpu_to_le16((u16)if_handle); + req->if_id = cpu_to_le16((u16) if_handle); req->permanent = 0; } - status = be_mbox_notify(adapter); - if (!status) + status = be_mbox_notify_wait(adapter); + if (!status) { + struct be_cmd_resp_mac_query *resp = embedded_payload(wrb); memcpy(mac_addr, resp->mac.addr, ETH_ALEN); + } spin_unlock(&adapter->mbox_lock); return status; } +/* Uses synchronous MCCQ */ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, u32 if_id, u32 *pmac_id) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_pmac_add *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_pmac_add *req; int status; - spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -418,24 +447,27 @@ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, req->if_id = cpu_to_le32(if_id); memcpy(req->mac_address, mac_addr, ETH_ALEN); - status = be_mbox_notify(adapter); + status = be_mcc_notify_wait(adapter); if (!status) { struct be_cmd_resp_pmac_add *resp = embedded_payload(wrb); *pmac_id = le32_to_cpu(resp->pmac_id); } - spin_unlock(&adapter->mbox_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } +/* Uses synchronous MCCQ */ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_pmac_del *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_pmac_del *req; int status; - spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -445,25 +477,29 @@ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id) req->if_id = cpu_to_le32(if_id); req->pmac_id = cpu_to_le32(pmac_id); - status = be_mbox_notify(adapter); - spin_unlock(&adapter->mbox_lock); + status = be_mcc_notify_wait(adapter); + + spin_unlock_bh(&adapter->mcc_lock); return status; } +/* Uses Mbox */ int be_cmd_cq_create(struct be_adapter *adapter, struct be_queue_info *cq, struct be_queue_info *eq, bool sol_evts, bool no_delay, int coalesce_wm) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_cq_create *req = embedded_payload(wrb); - struct be_cmd_resp_cq_create *resp = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_cq_create *req; struct be_dma_mem *q_mem = &cq->dma_mem; - void *ctxt = &req->context; + void *ctxt; int status; spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); + ctxt = &req->context; be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -486,11 +522,13 @@ int be_cmd_cq_create(struct be_adapter *adapter, be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); - status = be_mbox_notify(adapter); + status = be_mbox_notify_wait(adapter); if (!status) { + struct be_cmd_resp_cq_create *resp = embedded_payload(wrb); cq->id = le16_to_cpu(resp->cq_id); cq->created = true; } + spin_unlock(&adapter->mbox_lock); return status; @@ -508,14 +546,17 @@ int be_cmd_mccq_create(struct be_adapter *adapter, struct be_queue_info *mccq, struct be_queue_info *cq) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_mcc_create *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_mcc_create *req; struct be_dma_mem *q_mem = &mccq->dma_mem; - void *ctxt = &req->context; + void *ctxt; int status; spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); + ctxt = &req->context; be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -534,7 +575,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter, be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); - status = be_mbox_notify(adapter); + status = be_mbox_notify_wait(adapter); if (!status) { struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb); mccq->id = le16_to_cpu(resp->id); @@ -549,15 +590,17 @@ int be_cmd_txq_create(struct be_adapter *adapter, struct be_queue_info *txq, struct be_queue_info *cq) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_eth_tx_create *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_eth_tx_create *req; struct be_dma_mem *q_mem = &txq->dma_mem; - void *ctxt = &req->context; + void *ctxt; int status; - u32 len_encoded; spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); + ctxt = &req->context; be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -568,10 +611,8 @@ int be_cmd_txq_create(struct be_adapter *adapter, req->ulp_num = BE_ULP1_NUM; req->type = BE_ETH_TX_RING_TYPE_STANDARD; - len_encoded = fls(txq->len); /* log2(len) + 1 */ - if (len_encoded == 16) - len_encoded = 0; - AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, len_encoded); + AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, + be_encoded_q_len(txq->len)); AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt, be_pci_func(adapter)); AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1); @@ -581,28 +622,32 @@ int be_cmd_txq_create(struct be_adapter *adapter, be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); - status = be_mbox_notify(adapter); + status = be_mbox_notify_wait(adapter); if (!status) { struct be_cmd_resp_eth_tx_create *resp = embedded_payload(wrb); txq->id = le16_to_cpu(resp->cid); txq->created = true; } + spin_unlock(&adapter->mbox_lock); return status; } +/* Uses mbox */ int be_cmd_rxq_create(struct be_adapter *adapter, struct be_queue_info *rxq, u16 cq_id, u16 frag_size, u16 max_frame_size, u32 if_id, u32 rss) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_eth_rx_create *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_eth_rx_create *req; struct be_dma_mem *q_mem = &rxq->dma_mem; int status; spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -617,29 +662,34 @@ int be_cmd_rxq_create(struct be_adapter *adapter, req->max_frame_size = cpu_to_le16(max_frame_size); req->rss_queue = cpu_to_le32(rss); - status = be_mbox_notify(adapter); + status = be_mbox_notify_wait(adapter); if (!status) { struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb); rxq->id = le16_to_cpu(resp->id); rxq->created = true; } + spin_unlock(&adapter->mbox_lock); return status; } -/* Generic destroyer function for all types of queues */ +/* Generic destroyer function for all types of queues + * Uses Mbox + */ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, int queue_type) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_q_destroy *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_q_destroy *req; u8 subsys = 0, opcode = 0; int status; spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); switch (queue_type) { @@ -669,23 +719,27 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req)); req->id = cpu_to_le16(q->id); - status = be_mbox_notify(adapter); + status = be_mbox_notify_wait(adapter); spin_unlock(&adapter->mbox_lock); return status; } -/* Create an rx filtering policy configuration on an i/f */ +/* Create an rx filtering policy configuration on an i/f + * Uses mbox + */ int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_if_create *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_if_create *req; int status; spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -694,10 +748,11 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac, req->capability_flags = cpu_to_le32(flags); req->enable_flags = cpu_to_le32(flags); + req->pmac_invalid = pmac_invalid; if (!pmac_invalid) memcpy(req->mac_addr, mac, ETH_ALEN); - status = be_mbox_notify(adapter); + status = be_mbox_notify_wait(adapter); if (!status) { struct be_cmd_resp_if_create *resp = embedded_payload(wrb); *if_handle = le32_to_cpu(resp->interface_id); @@ -709,14 +764,17 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac, return status; } +/* Uses mbox */ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_if_destroy *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_if_destroy *req; int status; spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -724,7 +782,8 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) OPCODE_COMMON_NTWK_INTERFACE_DESTROY, sizeof(*req)); req->interface_id = cpu_to_le32(interface_id); - status = be_mbox_notify(adapter); + + status = be_mbox_notify_wait(adapter); spin_unlock(&adapter->mbox_lock); @@ -733,20 +792,22 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) /* Get stats is a non embedded command: the request is not embedded inside * WRB but is a separate dma memory block + * Uses asynchronous MCC */ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_get_stats *req = nonemb_cmd->va; - struct be_sge *sge = nonembedded_sgl(wrb); - int status; + struct be_mcc_wrb *wrb; + struct be_cmd_req_get_stats *req; + struct be_sge *sge; - spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + spin_lock_bh(&adapter->mcc_lock); - memset(req, 0, sizeof(*req)); + wrb = wrb_from_mccq(adapter); + req = nonemb_cmd->va; + sge = nonembedded_sgl(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); + wrb->tag0 = OPCODE_ETH_GET_STATISTICS; be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_GET_STATISTICS, sizeof(*req)); @@ -754,59 +815,61 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); sge->len = cpu_to_le32(nonemb_cmd->size); - status = be_mbox_notify(adapter); - if (!status) { - struct be_cmd_resp_get_stats *resp = nonemb_cmd->va; - be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats)); - } + be_mcc_notify(adapter); - spin_unlock(&adapter->mbox_lock); - return status; + spin_unlock_bh(&adapter->mcc_lock); + return 0; } +/* Uses synchronous mcc */ int be_cmd_link_status_query(struct be_adapter *adapter, bool *link_up) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_link_status *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_link_status *req; int status; - spin_lock(&adapter->mbox_lock); + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + req = embedded_payload(wrb); *link_up = false; - memset(wrb, 0, sizeof(*wrb)); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req)); - status = be_mbox_notify(adapter); + status = be_mcc_notify_wait(adapter); if (!status) { struct be_cmd_resp_link_status *resp = embedded_payload(wrb); if (resp->mac_speed != PHY_LINK_SPEED_ZERO) *link_up = true; } - spin_unlock(&adapter->mbox_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } +/* Uses Mbox */ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_get_fw_version *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_get_fw_version *req; int status; spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_GET_FW_VERSION, sizeof(*req)); - status = be_mbox_notify(adapter); + status = be_mbox_notify_wait(adapter); if (!status) { struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb); strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN); @@ -816,15 +879,18 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) return status; } -/* set the EQ delay interval of an EQ to specified value */ +/* set the EQ delay interval of an EQ to specified value + * Uses async mcc + */ int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_modify_eq_delay *req = embedded_payload(wrb); - int status; + struct be_mcc_wrb *wrb; + struct be_cmd_req_modify_eq_delay *req; - spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -836,21 +902,24 @@ int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd) req->delay[0].phase = 0; req->delay[0].delay_multiplier = cpu_to_le32(eqd); - status = be_mbox_notify(adapter); + be_mcc_notify(adapter); - spin_unlock(&adapter->mbox_lock); - return status; + spin_unlock_bh(&adapter->mcc_lock); + return 0; } +/* Uses sycnhronous mcc */ int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array, u32 num, bool untagged, bool promiscuous) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_vlan_config *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_vlan_config *req; int status; - spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -866,23 +935,24 @@ int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array, req->num_vlan * sizeof(vtag_array[0])); } - status = be_mbox_notify(adapter); + status = be_mcc_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } -/* Use MCC for this command as it may be called in BH context */ +/* Uses MCC for this command as it may be called in BH context + * Uses synchronous mcc + */ int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en) { struct be_mcc_wrb *wrb; struct be_cmd_req_promiscuous_config *req; + int status; spin_lock_bh(&adapter->mcc_lock); - wrb = wrb_from_mcc(&adapter->mcc_obj.q); - BUG_ON(!wrb); - + wrb = wrb_from_mccq(adapter); req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -895,14 +965,14 @@ int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en) else req->port0_promiscuous = en; - be_mcc_notify_wait(adapter); + status = be_mcc_notify_wait(adapter); spin_unlock_bh(&adapter->mcc_lock); - return 0; + return status; } /* - * Use MCC for this command as it may be called in BH context + * Uses MCC for this command as it may be called in BH context * (mc == NULL) => multicast promiscous */ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, @@ -914,9 +984,7 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, spin_lock_bh(&adapter->mcc_lock); - wrb = wrb_from_mcc(&adapter->mcc_obj.q); - BUG_ON(!wrb); - + wrb = wrb_from_mccq(adapter); req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -944,15 +1012,17 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, return 0; } +/* Uses synchrounous mcc */ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_set_flow_control *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_set_flow_control *req; int status; - spin_lock(&adapter->mbox_lock); + spin_lock_bh(&adapter->mcc_lock); - memset(wrb, 0, sizeof(*wrb)); + wrb = wrb_from_mccq(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -962,28 +1032,30 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc) req->tx_flow_control = cpu_to_le16((u16)tx_fc); req->rx_flow_control = cpu_to_le16((u16)rx_fc); - status = be_mbox_notify(adapter); + status = be_mcc_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } +/* Uses sycn mcc */ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_get_flow_control *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_get_flow_control *req; int status; - spin_lock(&adapter->mbox_lock); + spin_lock_bh(&adapter->mcc_lock); - memset(wrb, 0, sizeof(*wrb)); + wrb = wrb_from_mccq(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_GET_FLOW_CONTROL, sizeof(*req)); - status = be_mbox_notify(adapter); + status = be_mcc_notify_wait(adapter); if (!status) { struct be_cmd_resp_get_flow_control *resp = embedded_payload(wrb); @@ -991,26 +1063,28 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc) *rx_fc = le16_to_cpu(resp->rx_flow_control); } - spin_unlock(&adapter->mbox_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } +/* Uses mbox */ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_query_fw_cfg *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_query_fw_cfg *req; int status; spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req)); - status = be_mbox_notify(adapter); + status = be_mbox_notify_wait(adapter); if (!status) { struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb); *port_num = le32_to_cpu(resp->phys_port); @@ -1020,22 +1094,24 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num) return status; } +/* Uses mbox */ int be_cmd_reset_function(struct be_adapter *adapter) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); - struct be_cmd_req_hdr *req = embedded_payload(wrb); + struct be_mcc_wrb *wrb; + struct be_cmd_req_hdr *req; int status; spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); be_cmd_hdr_prepare(req, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_FUNCTION_RESET, sizeof(*req)); - status = be_mbox_notify(adapter); + status = be_mbox_notify_wait(adapter); spin_unlock(&adapter->mbox_lock); return status; @@ -1044,13 +1120,17 @@ int be_cmd_reset_function(struct be_adapter *adapter) int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, u32 flash_type, u32 flash_opcode, u32 buf_size) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem); + struct be_mcc_wrb *wrb; struct be_cmd_write_flashrom *req = cmd->va; - struct be_sge *sge = nonembedded_sgl(wrb); + struct be_sge *sge; int status; - spin_lock(&adapter->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + req = embedded_payload(wrb); + sge = nonembedded_sgl(wrb); + be_wrb_hdr_prepare(wrb, cmd->size, false, 1); be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, @@ -1063,8 +1143,8 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, req->params.op_code = cpu_to_le32(flash_opcode); req->params.data_buf_size = cpu_to_le32(buf_size); - status = be_mbox_notify(adapter); + status = be_mcc_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index fd7028e5b78..93e432f3d92 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -61,7 +61,8 @@ enum { /* The command is completing because the queue was getting flushed */ MCC_STATUS_QUEUE_FLUSHING = 0x4, /* The command is completing with a DMA error */ - MCC_STATUS_DMA_FAILED = 0x5 + MCC_STATUS_DMA_FAILED = 0x5, + MCC_STATUS_NOT_SUPPORTED = 0x66 }; #define CQE_STATUS_COMPL_MASK 0xFFFF @@ -761,7 +762,7 @@ extern int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc); extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num); extern int be_cmd_reset_function(struct be_adapter *adapter); -extern void be_process_mcc(struct be_adapter *adapter); +extern int be_process_mcc(struct be_adapter *adapter); extern int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, u32 flash_oper, u32 flash_opcode, u32 buf_size); diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index ce11bba2cb6..409cf059590 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -135,7 +135,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p) return status; } -static void netdev_stats_update(struct be_adapter *adapter) +void netdev_stats_update(struct be_adapter *adapter) { struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va); struct be_rxf_stats *rxf_stats = &hw_stats->rxf; @@ -431,8 +431,7 @@ static int make_tx_wrbs(struct be_adapter *adapter, } static netdev_tx_t be_xmit(struct sk_buff *skb, - struct net_device *netdev) - + struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev); struct be_tx_obj *tx_obj = &adapter->tx_obj; @@ -490,11 +489,11 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu) * program them in BE. If more than BE_NUM_VLANS_SUPPORTED are configured, * set the BE in promiscuous VLAN mode. */ -static void be_vid_config(struct net_device *netdev) +static int be_vid_config(struct be_adapter *adapter) { - struct be_adapter *adapter = netdev_priv(netdev); u16 vtag[BE_NUM_VLANS_SUPPORTED]; u16 ntags = 0, i; + int status; if (adapter->num_vlans <= BE_NUM_VLANS_SUPPORTED) { /* Construct VLAN Table to give to HW */ @@ -504,12 +503,13 @@ static void be_vid_config(struct net_device *netdev) ntags++; } } - be_cmd_vlan_config(adapter, adapter->if_handle, - vtag, ntags, 1, 0); + status = be_cmd_vlan_config(adapter, adapter->if_handle, + vtag, ntags, 1, 0); } else { - be_cmd_vlan_config(adapter, adapter->if_handle, - NULL, 0, 1, 1); + status = be_cmd_vlan_config(adapter, adapter->if_handle, + NULL, 0, 1, 1); } + return status; } static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp) @@ -532,7 +532,7 @@ static void be_vlan_add_vid(struct net_device *netdev, u16 vid) adapter->num_vlans++; adapter->vlan_tag[vid] = 1; - be_vid_config(netdev); + be_vid_config(adapter); } static void be_vlan_rem_vid(struct net_device *netdev, u16 vid) @@ -543,7 +543,7 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid) adapter->vlan_tag[vid] = 0; vlan_group_set_device(adapter->vlan_grp, vid, NULL); - be_vid_config(netdev); + be_vid_config(adapter); } static void be_set_multicast_list(struct net_device *netdev) @@ -1444,12 +1444,8 @@ static void be_worker(struct work_struct *work) { struct be_adapter *adapter = container_of(work, struct be_adapter, work.work); - int status; - /* Get Stats */ - status = be_cmd_get_stats(adapter, &adapter->stats.cmd); - if (!status) - netdev_stats_update(adapter); + be_cmd_get_stats(adapter, &adapter->stats.cmd); /* Set EQ delay */ be_rx_eqd_update(adapter); @@ -1622,11 +1618,6 @@ static int be_setup(struct be_adapter *adapter) if (status != 0) goto do_none; - be_vid_config(netdev); - - status = be_cmd_set_flow_control(adapter, true, true); - if (status != 0) - goto if_destroy; status = be_tx_queues_create(adapter); if (status != 0) @@ -1640,8 +1631,17 @@ static int be_setup(struct be_adapter *adapter) if (status != 0) goto rx_qs_destroy; + status = be_vid_config(adapter); + if (status != 0) + goto mccqs_destroy; + + status = be_cmd_set_flow_control(adapter, true, true); + if (status != 0) + goto mccqs_destroy; return 0; +mccqs_destroy: + be_mcc_queues_destroy(adapter); rx_qs_destroy: be_rx_queues_destroy(adapter); tx_qs_destroy: diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index a7e731f8a0d..69c5b15e22d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1093,15 +1093,8 @@ static struct slave *bond_find_best_slave(struct bonding *bond) return NULL; /* still no slave, return NULL */ } - /* - * first try the primary link; if arping, a link must tx/rx - * traffic before it can be considered the curr_active_slave. - * also, we would skip slaves between the curr_active_slave - * and primary_slave that may be up and able to arp - */ if ((bond->primary_slave) && - (!bond->params.arp_interval) && - (IS_UP(bond->primary_slave->dev))) { + bond->primary_slave->link == BOND_LINK_UP) { new_active = bond->primary_slave; } @@ -1109,15 +1102,14 @@ static struct slave *bond_find_best_slave(struct bonding *bond) old_active = new_active; bond_for_each_slave_from(bond, new_active, i, old_active) { - if (IS_UP(new_active->dev)) { - if (new_active->link == BOND_LINK_UP) { - return new_active; - } else if (new_active->link == BOND_LINK_BACK) { - /* link up, but waiting for stabilization */ - if (new_active->delay < mintime) { - mintime = new_active->delay; - bestslave = new_active; - } + if (new_active->link == BOND_LINK_UP) { + return new_active; + } else if (new_active->link == BOND_LINK_BACK && + IS_UP(new_active->dev)) { + /* link up, but waiting for stabilization */ + if (new_active->delay < mintime) { + mintime = new_active->delay; + bestslave = new_active; } } } @@ -1211,7 +1203,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); - netdev_bonding_change(bond->dev); + netdev_bonding_change(bond->dev, NETDEV_BONDING_FAILOVER); read_lock(&bond->lock); write_lock_bh(&bond->curr_slave_lock); @@ -1469,14 +1461,17 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) */ if (bond->slave_cnt == 0) { if (bond_dev->type != slave_dev->type) { - dev_close(bond_dev); pr_debug("%s: change device type from %d to %d\n", bond_dev->name, bond_dev->type, slave_dev->type); + + netdev_bonding_change(bond_dev, NETDEV_BONDING_OLDTYPE); + if (slave_dev->type != ARPHRD_ETHER) bond_setup_by_slave(bond_dev, slave_dev); else ether_setup(bond_dev); - dev_open(bond_dev); + + netdev_bonding_change(bond_dev, NETDEV_BONDING_NEWTYPE); } } else if (bond_dev->type != slave_dev->type) { pr_err(DRV_NAME ": %s ether type (%d) is different " @@ -2929,18 +2924,6 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) } } - read_lock(&bond->curr_slave_lock); - - /* - * Trigger a commit if the primary option setting has changed. - */ - if (bond->primary_slave && - (bond->primary_slave != bond->curr_active_slave) && - (bond->primary_slave->link == BOND_LINK_UP)) - commit++; - - read_unlock(&bond->curr_slave_lock); - return commit; } @@ -2961,90 +2944,58 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) continue; case BOND_LINK_UP: - write_lock_bh(&bond->curr_slave_lock); - - if (!bond->curr_active_slave && - time_before_eq(jiffies, dev_trans_start(slave->dev) + - delta_in_ticks)) { + if ((!bond->curr_active_slave && + time_before_eq(jiffies, + dev_trans_start(slave->dev) + + delta_in_ticks)) || + bond->curr_active_slave != slave) { slave->link = BOND_LINK_UP; - bond_change_active_slave(bond, slave); bond->current_arp_slave = NULL; pr_info(DRV_NAME - ": %s: %s is up and now the " - "active interface\n", - bond->dev->name, slave->dev->name); - - } else if (bond->curr_active_slave != slave) { - /* this slave has just come up but we - * already have a current slave; this can - * also happen if bond_enslave adds a new - * slave that is up while we are searching - * for a new slave - */ - slave->link = BOND_LINK_UP; - bond_set_slave_inactive_flags(slave); - bond->current_arp_slave = NULL; + ": %s: link status definitely " + "up for interface %s.\n", + bond->dev->name, slave->dev->name); - pr_info(DRV_NAME - ": %s: backup interface %s is now up\n", - bond->dev->name, slave->dev->name); - } + if (!bond->curr_active_slave || + (slave == bond->primary_slave)) + goto do_failover; - write_unlock_bh(&bond->curr_slave_lock); + } - break; + continue; case BOND_LINK_DOWN: if (slave->link_failure_count < UINT_MAX) slave->link_failure_count++; slave->link = BOND_LINK_DOWN; + bond_set_slave_inactive_flags(slave); - if (slave == bond->curr_active_slave) { - pr_info(DRV_NAME - ": %s: link status down for active " - "interface %s, disabling it\n", - bond->dev->name, slave->dev->name); - - bond_set_slave_inactive_flags(slave); - - write_lock_bh(&bond->curr_slave_lock); - - bond_select_active_slave(bond); - if (bond->curr_active_slave) - bond->curr_active_slave->jiffies = - jiffies; - - write_unlock_bh(&bond->curr_slave_lock); + pr_info(DRV_NAME + ": %s: link status definitely down for " + "interface %s, disabling it\n", + bond->dev->name, slave->dev->name); + if (slave == bond->curr_active_slave) { bond->current_arp_slave = NULL; - - } else if (slave->state == BOND_STATE_BACKUP) { - pr_info(DRV_NAME - ": %s: backup interface %s is now down\n", - bond->dev->name, slave->dev->name); - - bond_set_slave_inactive_flags(slave); + goto do_failover; } - break; + + continue; default: pr_err(DRV_NAME ": %s: impossible: new_link %d on slave %s\n", bond->dev->name, slave->new_link, slave->dev->name); + continue; } - } - /* - * No race with changes to primary via sysfs, as we hold rtnl. - */ - if (bond->primary_slave && - (bond->primary_slave != bond->curr_active_slave) && - (bond->primary_slave->link == BOND_LINK_UP)) { +do_failover: + ASSERT_RTNL(); write_lock_bh(&bond->curr_slave_lock); - bond_change_active_slave(bond, bond->primary_slave); + bond_select_active_slave(bond); write_unlock_bh(&bond->curr_slave_lock); } diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c index 6971f6cd37f..80ac5631398 100644 --- a/drivers/net/can/vcan.c +++ b/drivers/net/can/vcan.c @@ -80,7 +80,7 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev) skb->dev = dev; skb->ip_summed = CHECKSUM_UNNECESSARY; - netif_rx(skb); + netif_rx_ni(skb); } static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) diff --git a/drivers/net/fec.c b/drivers/net/fec.c index b47201874d8..29234380e6c 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1154,19 +1154,9 @@ static void __inline__ fec_request_mii_intr(struct net_device *dev) printk("FEC: Could not allocate fec(MII) IRQ(66)!\n"); } -static void __inline__ fec_disable_phy_intr(void) +static void __inline__ fec_disable_phy_intr(struct net_device *dev) { - volatile unsigned long *icrp; - icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = 0x08000000; -} - -static void __inline__ fec_phy_ack_intr(void) -{ - volatile unsigned long *icrp; - /* Acknowledge the interrupt */ - icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = 0x0d000000; + free_irq(66, dev); } #endif @@ -1398,7 +1388,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev) writel(0, fep->hwp + FEC_MII_SPEED); fep->phy_speed = 0; #ifdef HAVE_mii_link_interrupt - fec_disable_phy_intr(); + fec_disable_phy_intr(dev); #endif } } @@ -1411,8 +1401,6 @@ mii_link_interrupt(int irq, void * dev_id) struct net_device *dev = dev_id; struct fec_enet_private *fep = netdev_priv(dev); - fec_phy_ack_intr(); - mii_do_cmd(dev, fep->phy->ack_int); mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 6158c0f3b20..f8f5772557c 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -49,11 +49,10 @@ static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16 *); static s32 igb_reset_hw_82575(struct e1000_hw *); static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *, bool); static s32 igb_setup_copper_link_82575(struct e1000_hw *); -static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *); +static s32 igb_setup_serdes_link_82575(struct e1000_hw *); static s32 igb_write_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16); static void igb_clear_hw_cntrs_82575(struct e1000_hw *); static s32 igb_acquire_swfw_sync_82575(struct e1000_hw *, u16); -static void igb_configure_pcs_link_82575(struct e1000_hw *); static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *, u16 *, u16 *); static s32 igb_get_phy_id_82575(struct e1000_hw *); @@ -105,16 +104,20 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) dev_spec->sgmii_active = false; ctrl_ext = rd32(E1000_CTRL_EXT); - if ((ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) == - E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES) { - hw->phy.media_type = e1000_media_type_internal_serdes; - ctrl_ext |= E1000_CTRL_I2C_ENA; - } else if (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_SGMII) { + switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) { + case E1000_CTRL_EXT_LINK_MODE_SGMII: dev_spec->sgmii_active = true; ctrl_ext |= E1000_CTRL_I2C_ENA; - } else { + break; + case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES: + hw->phy.media_type = e1000_media_type_internal_serdes; + ctrl_ext |= E1000_CTRL_I2C_ENA; + break; + default: ctrl_ext &= ~E1000_CTRL_I2C_ENA; + break; } + wr32(E1000_CTRL_EXT, ctrl_ext); /* Set mta register count */ @@ -134,7 +137,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) mac->ops.setup_physical_interface = (hw->phy.media_type == e1000_media_type_copper) ? igb_setup_copper_link_82575 - : igb_setup_fiber_serdes_link_82575; + : igb_setup_serdes_link_82575; /* NVM initialization */ eecd = rd32(E1000_EECD); @@ -379,6 +382,7 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw) struct e1000_phy_info *phy = &hw->phy; s32 ret_val = 0; u16 phy_id; + u32 ctrl_ext; /* * For SGMII PHYs, we try the list of possible addresses until @@ -393,6 +397,12 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw) goto out; } + /* Power on sgmii phy if it is disabled */ + ctrl_ext = rd32(E1000_CTRL_EXT); + wr32(E1000_CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA); + wrfl(); + msleep(300); + /* * The address field in the I2CCMD register is 3 bits and 0 is invalid. * Therefore, we need to test 1-7 @@ -418,9 +428,12 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw) phy->addr = 0; ret_val = -E1000_ERR_PHY; goto out; + } else { + ret_val = igb_get_phy_id(hw); } - ret_val = igb_get_phy_id(hw); + /* restore previous sfp cage power state */ + wr32(E1000_CTRL_EXT, ctrl_ext); out: return ret_val; @@ -766,17 +779,18 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed, } /** - * igb_shutdown_fiber_serdes_link_82575 - Remove link during power down + * igb_shutdown_serdes_link_82575 - Remove link during power down * @hw: pointer to the HW structure * * In the case of fiber serdes, shut down optics and PCS on driver unload * when management pass thru is not enabled. **/ -void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw) +void igb_shutdown_serdes_link_82575(struct e1000_hw *hw) { u32 reg; - if (hw->phy.media_type != e1000_media_type_internal_serdes) + if (hw->phy.media_type != e1000_media_type_internal_serdes || + igb_sgmii_active_82575(hw)) return; /* if the management interface is not enabled, then power down */ @@ -788,7 +802,7 @@ void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw) /* shutdown the laser */ reg = rd32(E1000_CTRL_EXT); - reg |= E1000_CTRL_EXT_SDP7_DATA; + reg |= E1000_CTRL_EXT_SDP3_DATA; wr32(E1000_CTRL_EXT, reg); /* flush the write to verify completion */ @@ -927,6 +941,17 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); wr32(E1000_CTRL, ctrl); + ret_val = igb_setup_serdes_link_82575(hw); + if (ret_val) + goto out; + + if (igb_sgmii_active_82575(hw) && !hw->phy.reset_disable) { + ret_val = hw->phy.ops.reset(hw); + if (ret_val) { + hw_dbg("Error resetting the PHY.\n"); + goto out; + } + } switch (hw->phy.type) { case e1000_phy_m88: ret_val = igb_copper_link_setup_m88(hw); @@ -963,8 +988,6 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) } } - igb_configure_pcs_link_82575(hw); - /* * Check link status. Wait up to 100 microseconds for link to become * valid. @@ -987,14 +1010,18 @@ out: } /** - * igb_setup_fiber_serdes_link_82575 - Setup link for fiber/serdes + * igb_setup_serdes_link_82575 - Setup link for fiber/serdes * @hw: pointer to the HW structure * * Configures speed and duplex for fiber and serdes links. **/ -static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw) +static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw) { - u32 reg; + u32 ctrl_reg, reg; + + if ((hw->phy.media_type != e1000_media_type_internal_serdes) && + !igb_sgmii_active_82575(hw)) + return 0; /* * On the 82575, SerDes loopback mode persists until it is @@ -1004,26 +1031,38 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw) */ wr32(E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK); - /* Force link up, set 1gb, set both sw defined pins */ - reg = rd32(E1000_CTRL); - reg |= E1000_CTRL_SLU | - E1000_CTRL_SPD_1000 | - E1000_CTRL_FRCSPD | - E1000_CTRL_SWDPIN0 | - E1000_CTRL_SWDPIN1; - wr32(E1000_CTRL, reg); - - /* Power on phy for 82576 fiber adapters */ - if (hw->mac.type == e1000_82576) { - reg = rd32(E1000_CTRL_EXT); - reg &= ~E1000_CTRL_EXT_SDP7_DATA; - wr32(E1000_CTRL_EXT, reg); + /* power on the sfp cage if present */ + reg = rd32(E1000_CTRL_EXT); + reg &= ~E1000_CTRL_EXT_SDP3_DATA; + wr32(E1000_CTRL_EXT, reg); + + ctrl_reg = rd32(E1000_CTRL); + ctrl_reg |= E1000_CTRL_SLU; + + if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576) { + /* set both sw defined pins */ + ctrl_reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1; + + /* Set switch control to serdes energy detect */ + reg = rd32(E1000_CONNSW); + reg |= E1000_CONNSW_ENRGSRC; + wr32(E1000_CONNSW, reg); + } + + reg = rd32(E1000_PCS_LCTL); + + if (igb_sgmii_active_82575(hw)) { + /* allow time for SFP cage to power up phy */ + msleep(300); + + /* AN time out should be disabled for SGMII mode */ + reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT); + } else { + ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD | + E1000_CTRL_FD | E1000_CTRL_FRCDPX; } - /* Set switch control to serdes energy detect */ - reg = rd32(E1000_CONNSW); - reg |= E1000_CONNSW_ENRGSRC; - wr32(E1000_CONNSW, reg); + wr32(E1000_CTRL, ctrl_reg); /* * New SerDes mode allows for forcing speed or autonegotiating speed @@ -1031,12 +1070,21 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw) * mode that will be compatible with older link partners and switches. * However, both are supported by the hardware and some drivers/tools. */ - reg = rd32(E1000_PCS_LCTL); reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP | E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK); - if (hw->mac.autoneg) { + /* + * We force flow control to prevent the CTRL register values from being + * overwritten by the autonegotiated flow control values + */ + reg |= E1000_PCS_LCTL_FORCE_FCTRL; + + /* + * we always set sgmii to autoneg since it is the phy that will be + * forcing the link and the serdes is just a go-between + */ + if (hw->mac.autoneg || igb_sgmii_active_82575(hw)) { /* Set PCS register for autoneg */ reg |= E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */ E1000_PCS_LCTL_FDV_FULL | /* SerDes Full duplex */ @@ -1053,75 +1101,12 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw) hw_dbg("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg); } - if (hw->mac.type == e1000_82576) { - reg |= E1000_PCS_LCTL_FORCE_FCTRL; - igb_force_mac_fc(hw); - } - wr32(E1000_PCS_LCTL, reg); - return 0; -} - -/** - * igb_configure_pcs_link_82575 - Configure PCS link - * @hw: pointer to the HW structure - * - * Configure the physical coding sub-layer (PCS) link. The PCS link is - * only used on copper connections where the serialized gigabit media - * independent interface (sgmii) is being used. Configures the link - * for auto-negotiation or forces speed/duplex. - **/ -static void igb_configure_pcs_link_82575(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - u32 reg = 0; - - if (hw->phy.media_type != e1000_media_type_copper || - !(igb_sgmii_active_82575(hw))) - return; - - /* For SGMII, we need to issue a PCS autoneg restart */ - reg = rd32(E1000_PCS_LCTL); - - /* AN time out should be disabled for SGMII mode */ - reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT); - - if (mac->autoneg) { - /* Make sure forced speed and force link are not set */ - reg &= ~(E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK); - - /* - * The PHY should be setup prior to calling this function. - * All we need to do is restart autoneg and enable autoneg. - */ - reg |= E1000_PCS_LCTL_AN_RESTART | E1000_PCS_LCTL_AN_ENABLE; - } else { - /* Set PCS register for forced speed */ - - /* Turn off bits for full duplex, speed, and autoneg */ - reg &= ~(E1000_PCS_LCTL_FSV_1000 | - E1000_PCS_LCTL_FSV_100 | - E1000_PCS_LCTL_FDV_FULL | - E1000_PCS_LCTL_AN_ENABLE); - - /* Check for duplex first */ - if (mac->forced_speed_duplex & E1000_ALL_FULL_DUPLEX) - reg |= E1000_PCS_LCTL_FDV_FULL; - - /* Now set speed */ - if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) - reg |= E1000_PCS_LCTL_FSV_100; - - /* Force speed and force link */ - reg |= E1000_PCS_LCTL_FSD | - E1000_PCS_LCTL_FORCE_LINK | - E1000_PCS_LCTL_FLV_LINK_UP; + if (!igb_sgmii_active_82575(hw)) + igb_force_mac_fc(hw); - hw_dbg("Wrote 0x%08X to PCS_LCTL to configure forced link\n", - reg); - } - wr32(E1000_PCS_LCTL, reg); + return 0; } /** @@ -1248,7 +1233,8 @@ static void igb_clear_hw_cntrs_82575(struct e1000_hw *hw) temp = rd32(E1000_LENERRS); /* This register should not be read in copper configurations */ - if (hw->phy.media_type == e1000_media_type_internal_serdes) + if (hw->phy.media_type == e1000_media_type_internal_serdes || + igb_sgmii_active_82575(hw)) temp = rd32(E1000_SCVPC); } diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h index 8a1e6597061..ebd146fd4e1 100644 --- a/drivers/net/igb/e1000_82575.h +++ b/drivers/net/igb/e1000_82575.h @@ -28,7 +28,7 @@ #ifndef _E1000_82575_H_ #define _E1000_82575_H_ -extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw); +extern void igb_shutdown_serdes_link_82575(struct e1000_hw *hw); extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw); #define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \ diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index c85829355d5..cb916833f30 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -44,7 +44,7 @@ #define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ /* Extended Device Control */ -#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */ +#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Defineable Pin 3 */ /* Physical Func Reset Done Indication */ #define E1000_CTRL_EXT_PFRSTD 0x00004000 #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c index c1f4da63042..ee460600e74 100644 --- a/drivers/net/igb/e1000_phy.c +++ b/drivers/net/igb/e1000_phy.c @@ -1565,9 +1565,12 @@ out: **/ s32 igb_phy_sw_reset(struct e1000_hw *hw) { - s32 ret_val; + s32 ret_val = 0; u16 phy_ctrl; + if (!(hw->phy.ops.read_reg)) + goto out; + ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl); if (ret_val) goto out; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 943186b7848..d2639c4a086 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -5320,7 +5320,7 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake) *enable_wake = wufc || adapter->en_mng_pt; if (!*enable_wake) - igb_shutdown_fiber_serdes_link_82575(hw); + igb_shutdown_serdes_link_82575(hw); /* Release control of h/w to f/w. If f/w is AMT enabled, this * would have already happened in close and is redundant. */ diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index cb7f0c3c6e1..56b12f3192f 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -322,14 +322,16 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) break; case IXGBE_DEV_ID_82598AF_DUAL_PORT: case IXGBE_DEV_ID_82598AF_SINGLE_PORT: - case IXGBE_DEV_ID_82598EB_CX4: - case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: case IXGBE_DEV_ID_82598_DA_DUAL_PORT: case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: case IXGBE_DEV_ID_82598EB_XF_LR: case IXGBE_DEV_ID_82598EB_SFP_LOM: media_type = ixgbe_media_type_fiber; break; + case IXGBE_DEV_ID_82598EB_CX4: + case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: + media_type = ixgbe_media_type_cx4; + break; case IXGBE_DEV_ID_82598AT: case IXGBE_DEV_ID_82598AT2: media_type = ixgbe_media_type_copper; diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 61af47e75aa..2ec58dcdb82 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -337,6 +337,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) case IXGBE_DEV_ID_82599_SFP: media_type = ixgbe_media_type_fiber; break; + case IXGBE_DEV_ID_82599_CX4: + media_type = ixgbe_media_type_cx4; + break; default: media_type = ixgbe_media_type_unknown; break; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 45bf8b9716e..59ad9590e70 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -97,6 +97,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = { board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP), board_82599 }, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4), + board_82599 }, /* required last entry */ {0, } @@ -2055,6 +2057,8 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) rx_ring->flags |= IXGBE_RING_RX_PS_ENABLED; + else + rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED; #ifdef IXGBE_FCOE if (netdev->features & NETIF_F_FCOE_MTU) { diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 8ba90eec1dc..8761d7899f7 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -49,6 +49,7 @@ #define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM 0x10E1 #define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4 #define IXGBE_DEV_ID_82599_KX4 0x10F7 +#define IXGBE_DEV_ID_82599_CX4 0x10F9 #define IXGBE_DEV_ID_82599_SFP 0x10FB #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC @@ -2143,6 +2144,7 @@ enum ixgbe_media_type { ixgbe_media_type_fiber, ixgbe_media_type_copper, ixgbe_media_type_backplane, + ixgbe_media_type_cx4, ixgbe_media_type_virtual }; diff --git a/drivers/net/mlx4/catas.c b/drivers/net/mlx4/catas.c index aa9674b7f19..f599294fa8a 100644 --- a/drivers/net/mlx4/catas.c +++ b/drivers/net/mlx4/catas.c @@ -96,12 +96,17 @@ static void catas_reset(struct work_struct *work) spin_unlock_irq(&catas_lock); list_for_each_entry_safe(priv, tmppriv, &tlist, catas_err.list) { + struct pci_dev *pdev = priv->dev.pdev; + ret = mlx4_restart_one(priv->dev.pdev); - dev = &priv->dev; + /* 'priv' now is not valid */ if (ret) - mlx4_err(dev, "Reset failed (%d)\n", ret); - else + printk(KERN_ERR "mlx4 %s: Reset failed (%d)\n", + pci_name(pdev), ret); + else { + dev = pci_get_drvdata(pdev); mlx4_dbg(dev, "Reset succeeded\n"); + } } } diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 90a94d21583..97db1c73234 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1750,11 +1750,11 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID2("EN-6200P2", 0xa996d078), /* too generic! */ /* PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100 Ethernet Card", 0x281f1c5d, 0x11b0ffc0), */ - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"), PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "DP83903.cis"), diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index e0f9219a0ae..cc394d07375 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -229,7 +229,7 @@ static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel); static atomic_t pppol2tp_tunnel_count; static atomic_t pppol2tp_session_count; static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL }; -static struct proto_ops pppol2tp_ops; +static const struct proto_ops pppol2tp_ops; /* per-net private data for this module */ static int pppol2tp_net_id; @@ -2574,7 +2574,7 @@ static const struct file_operations pppol2tp_proc_fops = { * Init and cleanup *****************************************************************************/ -static struct proto_ops pppol2tp_ops = { +static const struct proto_ops pppol2tp_ops = { .family = AF_PPPOX, .owner = THIS_MODULE, .release = pppol2tp_release, diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 00bc65a0aac..4bb52e9cd37 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -65,8 +65,8 @@ #define RX_DEF_PENDING RX_MAX_PENDING /* This is the worst case number of transmit list elements for a single skb: - VLAN + TSO + CKSUM + Data + skb_frags * DMA */ -#define MAX_SKB_TX_LE (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS) + VLAN:GSO + CKSUM + Data + skb_frags * DMA */ +#define MAX_SKB_TX_LE (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1)) #define TX_MIN_PENDING (MAX_SKB_TX_LE+1) #define TX_MAX_PENDING 4096 #define TX_DEF_PENDING 127 @@ -1567,11 +1567,13 @@ static unsigned tx_le_req(const struct sk_buff *skb) { unsigned count; - count = sizeof(dma_addr_t) / sizeof(u32); - count += skb_shinfo(skb)->nr_frags * count; + count = (skb_shinfo(skb)->nr_frags + 1) + * (sizeof(dma_addr_t) / sizeof(u32)); if (skb_is_gso(skb)) ++count; + else if (sizeof(dma_addr_t) == sizeof(u32)) + ++count; /* possible vlan */ if (skb->ip_summed == CHECKSUM_PARTIAL) ++count; @@ -4548,16 +4550,18 @@ static int __devinit sky2_probe(struct pci_dev *pdev, if (hw->ports > 1) { struct net_device *dev1; + err = -ENOMEM; dev1 = sky2_init_netdev(hw, 1, using_dac, wol_default); - if (!dev1) - dev_warn(&pdev->dev, "allocation for second device failed\n"); - else if ((err = register_netdev(dev1))) { + if (dev1 && (err = register_netdev(dev1)) == 0) + sky2_show_addr(dev1); + else { dev_warn(&pdev->dev, "register of second port failed (%d)\n", err); hw->dev[1] = NULL; - free_netdev(dev1); - } else - sky2_show_addr(dev1); + hw->ports = 1; + if (dev1) + free_netdev(dev1); + } } setup_timer(&hw->watchdog_timer, sky2_watchdog, (unsigned long) hw); diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 784b631cfa3..3911be7c0cb 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -83,34 +83,6 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg) } } -#elif defined(CONFIG_BLACKFIN) - -#define SMC_IRQ_FLAGS IRQF_TRIGGER_HIGH -#define RPC_LSA_DEFAULT RPC_LED_100_10 -#define RPC_LSB_DEFAULT RPC_LED_TX_RX - -#define SMC_CAN_USE_8BIT 0 -#define SMC_CAN_USE_16BIT 1 -# if defined(CONFIG_BF561) -#define SMC_CAN_USE_32BIT 1 -# else -#define SMC_CAN_USE_32BIT 0 -# endif -#define SMC_IO_SHIFT 0 -#define SMC_NOWAIT 1 -#define SMC_USE_BFIN_DMA 0 - -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) -#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) -# if SMC_CAN_USE_32BIT -#define SMC_inl(a, r) readl((a) + (r)) -#define SMC_outl(v, a, r) writel(v, (a) + (r)) -#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) -#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) -# endif - #elif defined(CONFIG_REDWOOD_5) || defined(CONFIG_REDWOOD_6) /* We can only do 16-bit reads and writes in the static memory space. */ diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index 97e54d9d03c..33d5c579c5a 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c @@ -264,7 +264,6 @@ static int usbpn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) switch (cmd) { case SIOCPNGAUTOCONF: req->ifr_phonet_autoconf.device = PN_DEV_PC; - printk(KERN_CRIT"device is PN_DEV_PC\n"); return 0; } return -ENOIOCTLCMD; diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index ad89d23968d..49ea9c92b7e 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -5,6 +5,7 @@ menuconfig WLAN bool "Wireless LAN" depends on !S390 + default y ---help--- This section contains all the pre 802.11 and 802.11 wireless device drivers. For a complete list of drivers and documentation diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index a7cbb07988c..2b493742ef1 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -327,7 +327,8 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) aniState->firstepLevel + 1); return; } else { - if (conf->channel->band == IEEE80211_BAND_2GHZ) { + if ((conf->channel->band == IEEE80211_BAND_2GHZ) && + !conf_is_ht(conf)) { if (!aniState->ofdmWeakSigDetectOff) ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, @@ -369,7 +370,8 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); } else { - if (conf->channel->band == IEEE80211_BAND_2GHZ) { + if ((conf->channel->band == IEEE80211_BAND_2GHZ) && + !conf_is_ht(conf)) { if (aniState->firstepLevel > 0) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0); diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 7a9a3fa5542..e789792a36b 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2289,11 +2289,7 @@ static int b43_upload_microcode(struct b43_wldev *dev) err = -ENODEV; goto error; } - msleep_interruptible(50); - if (signal_pending(current)) { - err = -EINTR; - goto error; - } + msleep(50); } b43_read32(dev, B43_MMIO_GEN_IRQ_REASON); /* dummy read */ @@ -4287,6 +4283,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev) if (!dev->suspend_in_progress) b43_rng_init(wl); + ieee80211_wake_queues(dev->wl->hw); + b43_set_status(dev, B43_STAT_INITIALIZED); if (!dev->suspend_in_progress) diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 6fe122f18c0..eb57d1ea361 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -875,15 +875,16 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local, switch(type) { case HOSTAP_INTERFACE_AP: + dev->tx_queue_len = 0; /* use main radio device queue */ dev->netdev_ops = &hostap_mgmt_netdev_ops; dev->type = ARPHRD_IEEE80211; dev->header_ops = &hostap_80211_ops; break; case HOSTAP_INTERFACE_MASTER: - dev->tx_queue_len = 0; /* use main radio device queue */ dev->netdev_ops = &hostap_master_ops; break; default: + dev->tx_queue_len = 0; /* use main radio device queue */ dev->netdev_ops = &hostap_netdev_ops; } diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 6a13bfbc9d9..ca61d3796ce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2346,6 +2346,7 @@ struct iwl_cfg iwl4965_agn_cfg = { .mod_params = &iwl4965_mod_params, .use_isr_legacy = true, .ht_greenfield_support = false, + .broken_powersave = true, }; /* Module firmware */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 40b207aa8fe..346dc06fa7b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -760,6 +760,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, u16 high_low; u8 switch_to_legacy = 0; u8 is_green = lq_sta->is_green; + struct iwl_priv *priv = lq_sta->drv; /* check if we need to switch from HT to legacy rates. * assumption is that mandatory rates (1Mbps or 6Mbps) @@ -773,7 +774,8 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, tbl->lq_type = LQ_G; if (num_of_ant(tbl->ant_type) > 1) - tbl->ant_type = ANT_A;/*FIXME:RS*/ + tbl->ant_type = + first_antenna(priv->hw_params.valid_tx_ant); tbl->is_ht40 = 0; tbl->is_SGI = 0; @@ -883,6 +885,12 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, mac_index &= RATE_MCS_CODE_MSK; /* Remove # of streams */ if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE)) mac_index++; + /* + * mac80211 HT index is always zero-indexed; we need to move + * HT OFDM rates after CCK rates in 2.4 GHz band + */ + if (priv->band == IEEE80211_BAND_2GHZ) + mac_index += IWL_FIRST_OFDM_RATE; } if ((mac_index < 0) || diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index acfd7b40afb..fd26c0dc9c5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1585,9 +1585,12 @@ int iwl_setup_mac(struct iwl_priv *priv) hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM | IEEE80211_HW_AMPDU_AGGREGATION | - IEEE80211_HW_SPECTRUM_MGMT | - IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_SUPPORTS_DYNAMIC_PS; + IEEE80211_HW_SPECTRUM_MGMT; + + if (!priv->cfg->broken_powersave) + hw->flags |= IEEE80211_HW_SUPPORTS_PS | + IEEE80211_HW_SUPPORTS_DYNAMIC_PS; + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index c04d2a27081..7ff9ffb2b70 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -252,6 +252,7 @@ struct iwl_cfg { const u16 max_ll_items; const bool shadow_ram_support; const bool ht_greenfield_support; + const bool broken_powersave; }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 4ec6a8307cc..60be976afff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -292,8 +292,9 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) else dtimper = 1; - /* TT power setting overwrites everything */ - if (tt->state >= IWL_TI_1) + if (priv->cfg->broken_powersave) + iwl_power_sleep_cam_cmd(priv, &cmd); + else if (tt->state >= IWL_TI_1) iwl_static_sleep_cmd(priv, &cmd, tt->tt_power_mode, dtimper); else if (!enabled) iwl_power_sleep_cam_cmd(priv, &cmd); diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 8150c5c3a16..b90adcb73b0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -239,26 +239,22 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority) struct iwl_rx_queue *rxq = &priv->rxq; struct list_head *element; struct iwl_rx_mem_buffer *rxb; + struct sk_buff *skb; unsigned long flags; while (1) { spin_lock_irqsave(&rxq->lock, flags); - if (list_empty(&rxq->rx_used)) { spin_unlock_irqrestore(&rxq->lock, flags); return; } - element = rxq->rx_used.next; - rxb = list_entry(element, struct iwl_rx_mem_buffer, list); - list_del(element); - spin_unlock_irqrestore(&rxq->lock, flags); /* Alloc a new receive buffer */ - rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256, + skb = alloc_skb(priv->hw_params.rx_buf_size + 256, priority); - if (!rxb->skb) { + if (!skb) { IWL_CRIT(priv, "Can not allocate SKB buffers\n"); /* We don't reschedule replenish work here -- we will * call the restock method and if it still needs @@ -266,6 +262,20 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority) break; } + spin_lock_irqsave(&rxq->lock, flags); + + if (list_empty(&rxq->rx_used)) { + spin_unlock_irqrestore(&rxq->lock, flags); + dev_kfree_skb_any(skb); + return; + } + element = rxq->rx_used.next; + rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + list_del(element); + + spin_unlock_irqrestore(&rxq->lock, flags); + + rxb->skb = skb; /* Get physical address of RB/SKB */ rxb->real_dma_addr = pci_map_single( priv->pci_dev, diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 2238c9f2018..090966837f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1134,6 +1134,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) struct iwl_rx_queue *rxq = &priv->rxq; struct list_head *element; struct iwl_rx_mem_buffer *rxb; + struct sk_buff *skb; unsigned long flags; while (1) { @@ -1143,17 +1144,11 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) spin_unlock_irqrestore(&rxq->lock, flags); return; } - - element = rxq->rx_used.next; - rxb = list_entry(element, struct iwl_rx_mem_buffer, list); - list_del(element); spin_unlock_irqrestore(&rxq->lock, flags); /* Alloc a new receive buffer */ - rxb->skb = - alloc_skb(priv->hw_params.rx_buf_size, - priority); - if (!rxb->skb) { + skb = alloc_skb(priv->hw_params.rx_buf_size, priority); + if (!skb) { if (net_ratelimit()) IWL_CRIT(priv, ": Can not allocate SKB buffers\n"); /* We don't reschedule replenish work here -- we will @@ -1162,6 +1157,19 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) break; } + spin_lock_irqsave(&rxq->lock, flags); + if (list_empty(&rxq->rx_used)) { + spin_unlock_irqrestore(&rxq->lock, flags); + dev_kfree_skb_any(skb); + return; + } + element = rxq->rx_used.next; + rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + list_del(element); + spin_unlock_irqrestore(&rxq->lock, flags); + + rxb->skb = skb; + /* If radiotap head is required, reserve some headroom here. * The physical head count is a variable rx_stats->phy_count. * We reserve 4 bytes here. Plus these extra bytes, the diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index e44460ff149..17e199546ee 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -67,6 +67,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/ {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */ {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */ + {USB_DEVICE(0x0cde, 0x0015)}, /* Zcomax XG-705A */ {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */ {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */ {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */ diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index d9169b47ac4..27298b19d5b 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -644,11 +644,10 @@ static int wl1271_op_config_interface(struct ieee80211_hw *hw, { struct wl1271 *wl = hw->priv; struct sk_buff *beacon; - DECLARE_MAC_BUF(mac); int ret; - wl1271_debug(DEBUG_MAC80211, "mac80211 config_interface bssid %s", - print_mac(mac, conf->bssid)); + wl1271_debug(DEBUG_MAC80211, "mac80211 config_interface bssid %pM", + conf->bssid); wl1271_dump_ascii(DEBUG_MAC80211, "ssid: ", conf->ssid, conf->ssid_len); diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 79c9c5f5cdb..ed4648b556c 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -868,11 +868,11 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab), PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f), PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"), PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"), @@ -883,10 +883,10 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ - PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"), + PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"), PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), - PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"), + PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"), PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"), PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b), PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83), diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index f853d5600ca..9e50896233a 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -600,6 +600,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, ssb_printk(KERN_WARNING PFX "Unsupported SPROM" " revision %d detected. Will extract" " v1\n", out->revision); + out->revision = 1; sprom_extract_r123(out, in); } } diff --git a/drivers/ssb/sdio.c b/drivers/ssb/sdio.c index 114051056b5..65a6080cb02 100644 --- a/drivers/ssb/sdio.c +++ b/drivers/ssb/sdio.c @@ -21,7 +21,7 @@ #include "ssb_private.h" /* Define the following to 1 to enable a printk on each coreswitch. */ -#define SSB_VERBOSE_SDIOCORESWITCH_DEBUG 1 +#define SSB_VERBOSE_SDIOCORESWITCH_DEBUG 0 /* Hardware invariants CIS tuples */ @@ -333,7 +333,7 @@ static void ssb_sdio_block_read(struct ssb_device *dev, void *buffer, goto out; err_out: - dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%u), error %d\n", + dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n", bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error); out: sdio_release_host(bus->host_sdio); @@ -440,7 +440,7 @@ static void ssb_sdio_block_write(struct ssb_device *dev, const void *buffer, goto out; err_out: - dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%u), error %d\n", + dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n", bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error); out: sdio_release_host(bus->host_sdio); diff --git a/drivers/staging/octeon/cvmx-mdio.h b/drivers/staging/octeon/cvmx-mdio.h index c987a75a20c..f45dc49512f 100644 --- a/drivers/staging/octeon/cvmx-mdio.h +++ b/drivers/staging/octeon/cvmx-mdio.h @@ -421,7 +421,7 @@ static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device, do { cvmx_wait(1000); smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id)); - } while (smi_rd.s.pending && timeout--); + } while (smi_rd.s.pending && --timeout); if (timeout <= 0) { cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d " diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index 9052bcb4f52..e7eeb63fab2 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c @@ -887,8 +887,7 @@ static int hwarc_post_reset(struct usb_interface *iface) struct hwarc *hwarc = usb_get_intfdata(iface); struct uwb_rc *uwb_rc = hwarc->uwb_rc; - uwb_rc_post_reset(uwb_rc); - return 0; + return uwb_rc_post_reset(uwb_rc); } /** USB device ID's that we handle */ diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c index 9cf21e6bb62..9611ef3b787 100644 --- a/drivers/uwb/lc-rc.c +++ b/drivers/uwb/lc-rc.c @@ -288,8 +288,8 @@ error_sys_add: error_dev_add: error_rc_setup: rc->stop(rc); - uwbd_stop(rc); error_rc_start: + uwbd_stop(rc); return result; } EXPORT_SYMBOL_GPL(uwb_rc_add); diff --git a/drivers/uwb/reset.c b/drivers/uwb/reset.c index 70f8050221f..7f0512e43d9 100644 --- a/drivers/uwb/reset.c +++ b/drivers/uwb/reset.c @@ -30,6 +30,7 @@ */ #include <linux/kernel.h> #include <linux/err.h> +#include <linux/delay.h> #include "uwb-internal.h" @@ -323,13 +324,15 @@ int uwbd_msg_handle_reset(struct uwb_event *evt) dev_info(&rc->uwb_dev.dev, "resetting radio controller\n"); ret = rc->reset(rc); - if (ret) { + if (ret < 0) { dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret); goto error; } return 0; error: - /* Nothing can be done except try the reset again. */ + /* Nothing can be done except try the reset again. Wait a bit + to avoid reset loops during probe() or remove(). */ + msleep(1000); uwb_rc_reset_all(rc); return ret; } @@ -368,22 +371,20 @@ void uwb_rc_pre_reset(struct uwb_rc *rc) } EXPORT_SYMBOL_GPL(uwb_rc_pre_reset); -void uwb_rc_post_reset(struct uwb_rc *rc) +int uwb_rc_post_reset(struct uwb_rc *rc) { int ret; ret = rc->start(rc); if (ret) - goto error; + goto out; ret = uwb_rc_mac_addr_set(rc, &rc->uwb_dev.mac_addr); if (ret) - goto error; + goto out; ret = uwb_rc_dev_addr_set(rc, &rc->uwb_dev.dev_addr); if (ret) - goto error; - return; -error: - /* Nothing can be done except try the reset again. */ - uwb_rc_reset_all(rc); + goto out; +out: + return ret; } EXPORT_SYMBOL_GPL(uwb_rc_post_reset); diff --git a/drivers/uwb/umc-bus.c b/drivers/uwb/umc-bus.c index 5ad36164c13..cdd6c8efc9f 100644 --- a/drivers/uwb/umc-bus.c +++ b/drivers/uwb/umc-bus.c @@ -66,7 +66,7 @@ int umc_controller_reset(struct umc_dev *umc) return -EAGAIN; ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper); if (ret >= 0) - device_for_each_child(parent, parent, umc_bus_post_reset_helper); + ret = device_for_each_child(parent, parent, umc_bus_post_reset_helper); up(&parent->sem); return ret; diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c index 57bd6bfef37..5a777d8624d 100644 --- a/drivers/uwb/uwbd.c +++ b/drivers/uwb/uwbd.c @@ -187,12 +187,12 @@ int uwbd_event_handle_urc(struct uwb_event *evt) event = le16_to_cpu(evt->notif.rceb->wEvent); context = evt->notif.rceb->bEventContext; - if (type > ARRAY_SIZE(uwbd_urc_evt_type_handlers)) + if (type >= ARRAY_SIZE(uwbd_urc_evt_type_handlers)) goto out; type_table = &uwbd_urc_evt_type_handlers[type]; if (type_table->uwbd_events == NULL) goto out; - if (event > type_table->size) + if (event >= type_table->size) goto out; handler = type_table->uwbd_events[event].handler; if (handler == NULL) diff --git a/drivers/uwb/whc-rc.c b/drivers/uwb/whc-rc.c index 19a1dd12921..1d9a6f54658 100644 --- a/drivers/uwb/whc-rc.c +++ b/drivers/uwb/whc-rc.c @@ -443,8 +443,7 @@ static int whcrc_post_reset(struct umc_dev *umc) struct whcrc *whcrc = umc_get_drvdata(umc); struct uwb_rc *uwb_rc = whcrc->uwb_rc; - uwb_rc_post_reset(uwb_rc); - return 0; + return uwb_rc_post_reset(uwb_rc); } /* PCI device ID's that we handle [so it gets loaded] */ diff --git a/drivers/video/console/.gitignore b/drivers/video/console/.gitignore deleted file mode 100644 index 0c258b45439..00000000000 --- a/drivers/video/console/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# conmakehash generated file -promcon_tbl.c diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 2f50a80b413..fc7d9bbb548 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -67,16 +67,9 @@ config SGI_NEWPORT_CONSOLE # bool 'IODC console' CONFIG_IODC_CONSOLE -config PROM_CONSOLE - bool "PROM console" - depends on SPARC - help - Say Y to build a console driver for Sun machines that uses the - terminal emulation built into their console PROMS. - config DUMMY_CONSOLE bool - depends on PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y + depends on VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y default y config DUMMY_CONSOLE_COLUMNS diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile index ac46cc3f6a2..a862e9173eb 100644 --- a/drivers/video/console/Makefile +++ b/drivers/video/console/Makefile @@ -22,7 +22,6 @@ font-objs += $(font-objs-y) obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o font.o -obj-$(CONFIG_PROM_CONSOLE) += promcon.o promcon_tbl.o obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o font.o obj-$(CONFIG_VGA_CONSOLE) += vgacon.o obj-$(CONFIG_MDA_CONSOLE) += mdacon.o @@ -40,14 +39,3 @@ obj-$(CONFIG_FB_STI) += sticore.o font.o ifeq ($(CONFIG_USB_SISUSBVGA_CON),y) obj-$(CONFIG_USB_SISUSBVGA) += font.o endif - -# Targets that kbuild needs to know about -targets := promcon_tbl.c - -quiet_cmd_conmakehash = CNMKHSH $@ - cmd_conmakehash = scripts/conmakehash $< | \ - sed -e '/\#include <[^>]*>/p' -e 's/types/init/' \ - -e 's/dfont\(_uni.*\]\)/promfont\1 /' > $@ - -$(obj)/promcon_tbl.c: $(src)/prom.uni - $(call cmd,conmakehash) diff --git a/drivers/video/console/prom.uni b/drivers/video/console/prom.uni deleted file mode 100644 index 58f9c04ed9d..00000000000 --- a/drivers/video/console/prom.uni +++ /dev/null @@ -1,11 +0,0 @@ -# -# Unicode mapping table for font in Sun PROM -# -# -0x20-0x7e idem -0xa0-0xff idem -# -0x7c U+2502 -0x2d U+2500 -0x2b U+250c U+2510 U+2514 U+2518 U+251c U+2524 U+252c U+2534 U+253c -0xa4 U+fffd diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c deleted file mode 100644 index ae02e4eb18e..00000000000 --- a/drivers/video/console/promcon.c +++ /dev/null @@ -1,598 +0,0 @@ -/* $Id: promcon.c,v 1.17 2000/07/26 23:02:52 davem Exp $ - * Console driver utilizing PROM sun terminal emulation - * - * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) - * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/console.h> -#include <linux/vt_kern.h> -#include <linux/selection.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/kd.h> - -#include <asm/oplib.h> -#include <asm/uaccess.h> - -static short pw = 80 - 1, ph = 34 - 1; -static short px, py; -static unsigned long promcon_uni_pagedir[2]; - -extern u8 promfont_unicount[]; -extern u16 promfont_unitable[]; - -#define PROMCON_COLOR 0 - -#if PROMCON_COLOR -#define inverted(s) ((((s) & 0x7700) == 0x0700) ? 0 : 1) -#else -#define inverted(s) (((s) & 0x0800) ? 1 : 0) -#endif - -static __inline__ void -promcon_puts(char *buf, int cnt) -{ - prom_printf("%*.*s", cnt, cnt, buf); -} - -static int -promcon_start(struct vc_data *conp, char *b) -{ - unsigned short *s = (unsigned short *) - (conp->vc_origin + py * conp->vc_size_row + (px << 1)); - u16 cs; - - cs = scr_readw(s); - if (px == pw) { - unsigned short *t = s - 1; - u16 ct = scr_readw(t); - - if (inverted(cs) && inverted(ct)) - return sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs, - ct); - else if (inverted(cs)) - return sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs, - ct); - else if (inverted(ct)) - return sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs, - ct); - else - return sprintf(b, "\b%c\b\033[@%c", cs, ct); - } - - if (inverted(cs)) - return sprintf(b, "\033[7m%c\033[m\b", cs); - else - return sprintf(b, "%c\b", cs); -} - -static int -promcon_end(struct vc_data *conp, char *b) -{ - unsigned short *s = (unsigned short *) - (conp->vc_origin + py * conp->vc_size_row + (px << 1)); - char *p = b; - u16 cs; - - b += sprintf(b, "\033[%d;%dH", py + 1, px + 1); - - cs = scr_readw(s); - if (px == pw) { - unsigned short *t = s - 1; - u16 ct = scr_readw(t); - - if (inverted(cs) && inverted(ct)) - b += sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs, ct); - else if (inverted(cs)) - b += sprintf(b, "\b%c\b\033[@%c", cs, ct); - else if (inverted(ct)) - b += sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs, ct); - else - b += sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs, ct); - return b - p; - } - - if (inverted(cs)) - b += sprintf(b, "%c\b", cs); - else - b += sprintf(b, "\033[7m%c\033[m\b", cs); - return b - p; -} - -const char *promcon_startup(void) -{ - const char *display_desc = "PROM"; - int node; - char buf[40]; - - node = prom_getchild(prom_root_node); - node = prom_searchsiblings(node, "options"); - if (prom_getproperty(node, "screen-#columns", buf, 40) != -1) { - pw = simple_strtoul(buf, NULL, 0); - if (pw < 10 || pw > 256) - pw = 80; - pw--; - } - if (prom_getproperty(node, "screen-#rows", buf, 40) != -1) { - ph = simple_strtoul(buf, NULL, 0); - if (ph < 10 || ph > 256) - ph = 34; - ph--; - } - promcon_puts("\033[H\033[J", 6); - return display_desc; -} - -static void -promcon_init_unimap(struct vc_data *conp) -{ - mm_segment_t old_fs = get_fs(); - struct unipair *p, *p1; - u16 *q; - int i, j, k; - - p = kmalloc(256*sizeof(struct unipair), GFP_KERNEL); - if (!p) return; - - q = promfont_unitable; - p1 = p; - k = 0; - for (i = 0; i < 256; i++) - for (j = promfont_unicount[i]; j; j--) { - p1->unicode = *q++; - p1->fontpos = i; - p1++; - k++; - } - set_fs(KERNEL_DS); - con_clear_unimap(conp, NULL); - con_set_unimap(conp, k, p); - con_protect_unimap(conp, 1); - set_fs(old_fs); - kfree(p); -} - -static void -promcon_init(struct vc_data *conp, int init) -{ - unsigned long p; - - conp->vc_can_do_color = PROMCON_COLOR; - if (init) { - conp->vc_cols = pw + 1; - conp->vc_rows = ph + 1; - } - p = *conp->vc_uni_pagedir_loc; - if (conp->vc_uni_pagedir_loc == &conp->vc_uni_pagedir || - !--conp->vc_uni_pagedir_loc[1]) - con_free_unimap(conp); - conp->vc_uni_pagedir_loc = promcon_uni_pagedir; - promcon_uni_pagedir[1]++; - if (!promcon_uni_pagedir[0] && p) { - promcon_init_unimap(conp); - } - if (!init) { - if (conp->vc_cols != pw + 1 || conp->vc_rows != ph + 1) - vc_resize(conp, pw + 1, ph + 1); - } -} - -static void -promcon_deinit(struct vc_data *conp) -{ - /* When closing the last console, reset video origin */ - if (!--promcon_uni_pagedir[1]) - con_free_unimap(conp); - conp->vc_uni_pagedir_loc = &conp->vc_uni_pagedir; - con_set_default_unimap(conp); -} - -static int -promcon_switch(struct vc_data *conp) -{ - return 1; -} - -static unsigned short * -promcon_repaint_line(unsigned short *s, unsigned char *buf, unsigned char **bp) -{ - int cnt = pw + 1; - int attr = -1; - unsigned char *b = *bp; - - while (cnt--) { - u16 c = scr_readw(s); - if (attr != inverted(c)) { - attr = inverted(c); - if (attr) { - strcpy (b, "\033[7m"); - b += 4; - } else { - strcpy (b, "\033[m"); - b += 3; - } - } - *b++ = c; - s++; - if (b - buf >= 224) { - promcon_puts(buf, b - buf); - b = buf; - } - } - *bp = b; - return s; -} - -static void -promcon_putcs(struct vc_data *conp, const unsigned short *s, - int count, int y, int x) -{ - unsigned char buf[256], *b = buf; - unsigned short attr = scr_readw(s); - unsigned char save; - int i, last = 0; - - if (console_blanked) - return; - - if (count <= 0) - return; - - b += promcon_start(conp, b); - - if (x + count >= pw + 1) { - if (count == 1) { - x -= 1; - save = scr_readw((unsigned short *)(conp->vc_origin - + y * conp->vc_size_row - + (x << 1))); - - if (px != x || py != y) { - b += sprintf(b, "\033[%d;%dH", y + 1, x + 1); - px = x; - py = y; - } - - if (inverted(attr)) - b += sprintf(b, "\033[7m%c\033[m", scr_readw(s++)); - else - b += sprintf(b, "%c", scr_readw(s++)); - - strcpy(b, "\b\033[@"); - b += 4; - - if (inverted(save)) - b += sprintf(b, "\033[7m%c\033[m", save); - else - b += sprintf(b, "%c", save); - - px++; - - b += promcon_end(conp, b); - promcon_puts(buf, b - buf); - return; - } else { - last = 1; - count = pw - x - 1; - } - } - - if (inverted(attr)) { - strcpy(b, "\033[7m"); - b += 4; - } - - if (px != x || py != y) { - b += sprintf(b, "\033[%d;%dH", y + 1, x + 1); - px = x; - py = y; - } - - for (i = 0; i < count; i++) { - if (b - buf >= 224) { - promcon_puts(buf, b - buf); - b = buf; - } - *b++ = scr_readw(s++); - } - - px += count; - - if (last) { - save = scr_readw(s++); - b += sprintf(b, "%c\b\033[@%c", scr_readw(s++), save); - px++; - } - - if (inverted(attr)) { - strcpy(b, "\033[m"); - b += 3; - } - - b += promcon_end(conp, b); - promcon_puts(buf, b - buf); -} - -static void -promcon_putc(struct vc_data *conp, int c, int y, int x) -{ - unsigned short s; - - if (console_blanked) - return; - - scr_writew(c, &s); - promcon_putcs(conp, &s, 1, y, x); -} - -static void -promcon_clear(struct vc_data *conp, int sy, int sx, int height, int width) -{ - unsigned char buf[256], *b = buf; - int i, j; - - if (console_blanked) - return; - - b += promcon_start(conp, b); - - if (!sx && width == pw + 1) { - - if (!sy && height == ph + 1) { - strcpy(b, "\033[H\033[J"); - b += 6; - b += promcon_end(conp, b); - promcon_puts(buf, b - buf); - return; - } else if (sy + height == ph + 1) { - b += sprintf(b, "\033[%dH\033[J", sy + 1); - b += promcon_end(conp, b); - promcon_puts(buf, b - buf); - return; - } - - b += sprintf(b, "\033[%dH", sy + 1); - for (i = 1; i < height; i++) { - strcpy(b, "\033[K\n"); - b += 4; - } - - strcpy(b, "\033[K"); - b += 3; - - b += promcon_end(conp, b); - promcon_puts(buf, b - buf); - return; - - } else if (sx + width == pw + 1) { - - b += sprintf(b, "\033[%d;%dH", sy + 1, sx + 1); - for (i = 1; i < height; i++) { - strcpy(b, "\033[K\n"); - b += 4; - } - - strcpy(b, "\033[K"); - b += 3; - - b += promcon_end(conp, b); - promcon_puts(buf, b - buf); - return; - } - - for (i = sy + 1; i <= sy + height; i++) { - b += sprintf(b, "\033[%d;%dH", i, sx + 1); - for (j = 0; j < width; j++) - *b++ = ' '; - if (b - buf + width >= 224) { - promcon_puts(buf, b - buf); - b = buf; - } - } - - b += promcon_end(conp, b); - promcon_puts(buf, b - buf); -} - -static void -promcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx, - int height, int width) -{ - char buf[256], *b = buf; - - if (console_blanked) - return; - - b += promcon_start(conp, b); - if (sy == dy && height == 1) { - if (dx > sx && dx + width == conp->vc_cols) - b += sprintf(b, "\033[%d;%dH\033[%d@\033[%d;%dH", - sy + 1, sx + 1, dx - sx, py + 1, px + 1); - else if (dx < sx && sx + width == conp->vc_cols) - b += sprintf(b, "\033[%d;%dH\033[%dP\033[%d;%dH", - dy + 1, dx + 1, sx - dx, py + 1, px + 1); - - b += promcon_end(conp, b); - promcon_puts(buf, b - buf); - return; - } - - /* - * FIXME: What to do here??? - * Current console.c should not call it like that ever. - */ - prom_printf("\033[7mFIXME: bmove not handled\033[m\n"); -} - -static void -promcon_cursor(struct vc_data *conp, int mode) -{ - char buf[32], *b = buf; - - switch (mode) { - case CM_ERASE: - break; - - case CM_MOVE: - case CM_DRAW: - b += promcon_start(conp, b); - if (px != conp->vc_x || py != conp->vc_y) { - px = conp->vc_x; - py = conp->vc_y; - b += sprintf(b, "\033[%d;%dH", py + 1, px + 1); - } - promcon_puts(buf, b - buf); - break; - } -} - -static int -promcon_blank(struct vc_data *conp, int blank, int mode_switch) -{ - if (blank) { - promcon_puts("\033[H\033[J\033[7m \033[m\b", 15); - return 0; - } else { - /* Let console.c redraw */ - return 1; - } -} - -static int -promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count) -{ - unsigned char buf[256], *p = buf; - unsigned short *s; - int i; - - if (console_blanked) - return 0; - - p += promcon_start(conp, p); - - switch (dir) { - case SM_UP: - if (b == ph + 1) { - p += sprintf(p, "\033[%dH\033[%dM", t + 1, count); - px = 0; - py = t; - p += promcon_end(conp, p); - promcon_puts(buf, p - buf); - break; - } - - s = (unsigned short *)(conp->vc_origin - + (t + count) * conp->vc_size_row); - - p += sprintf(p, "\033[%dH", t + 1); - - for (i = t; i < b - count; i++) - s = promcon_repaint_line(s, buf, &p); - - for (; i < b - 1; i++) { - strcpy(p, "\033[K\n"); - p += 4; - if (p - buf >= 224) { - promcon_puts(buf, p - buf); - p = buf; - } - } - - strcpy(p, "\033[K"); - p += 3; - - p += promcon_end(conp, p); - promcon_puts(buf, p - buf); - break; - - case SM_DOWN: - if (b == ph + 1) { - p += sprintf(p, "\033[%dH\033[%dL", t + 1, count); - px = 0; - py = t; - p += promcon_end(conp, p); - promcon_puts(buf, p - buf); - break; - } - - s = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row); - - p += sprintf(p, "\033[%dH", t + 1); - - for (i = t; i < t + count; i++) { - strcpy(p, "\033[K\n"); - p += 4; - if (p - buf >= 224) { - promcon_puts(buf, p - buf); - p = buf; - } - } - - for (; i < b; i++) - s = promcon_repaint_line(s, buf, &p); - - p += promcon_end(conp, p); - promcon_puts(buf, p - buf); - break; - } - - return 0; -} - -#if !(PROMCON_COLOR) -static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity, - u8 _blink, u8 _underline, u8 _reverse, u8 _italic) -{ - return (_reverse) ? 0xf : 0x7; -} -#endif - -/* - * The console 'switch' structure for the VGA based console - */ - -static int promcon_dummy(void) -{ - return 0; -} - -#define DUMMY (void *) promcon_dummy - -const struct consw prom_con = { - .owner = THIS_MODULE, - .con_startup = promcon_startup, - .con_init = promcon_init, - .con_deinit = promcon_deinit, - .con_clear = promcon_clear, - .con_putc = promcon_putc, - .con_putcs = promcon_putcs, - .con_cursor = promcon_cursor, - .con_scroll = promcon_scroll, - .con_bmove = promcon_bmove, - .con_switch = promcon_switch, - .con_blank = promcon_blank, - .con_set_palette = DUMMY, - .con_scrolldelta = DUMMY, -#if !(PROMCON_COLOR) - .con_build_attr = promcon_build_attr, -#endif -}; - -void __init prom_con_init(void) -{ -#ifdef CONFIG_DUMMY_CONSOLE - if (conswitchp == &dummy_con) - take_over_console(&prom_con, 0, MAX_NR_CONSOLES-1, 1); - else -#endif - if (conswitchp == &prom_con) - promcon_init_unimap(vc_cons[fg_console].d); -} diff --git a/firmware/Makefile b/firmware/Makefile index 878329cf482..ffe2663d49f 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -51,9 +51,10 @@ fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \ e100/d102e_ucode.bin fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin -fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis +fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis +fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \ advansys/3550.bin advansys/38C0800.bin diff --git a/firmware/WHENCE b/firmware/WHENCE index d9e3a94cb4d..82db5256a4e 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -596,6 +596,7 @@ Found in hex form in kernel source. Driver: PCMCIA_PCNET - NE2000 compatible PCMCIA adapter File: cis/LA-PCM.cis + cis/PCMLM28.cis Licence: GPL @@ -623,6 +624,17 @@ Originally developed by the pcmcia-cs project -------------------------------------------------------------------------- +Driver: SERIAL_8250_CS - Serial PCMCIA adapter + +File: cis/MT5634ZLX.cis + cis/RS-COM-2P.cis + +Licence: GPL + +Originally developed by the pcmcia-cs project + +-------------------------------------------------------------------------- + Driver: PCMCIA_SMC91C92 - SMC 91Cxx PCMCIA File: ositech/Xilinx7OD.bin diff --git a/firmware/cis/MT5634ZLX.cis.ihex b/firmware/cis/MT5634ZLX.cis.ihex new file mode 100644 index 00000000000..72500b9d95d --- /dev/null +++ b/firmware/cis/MT5634ZLX.cis.ihex @@ -0,0 +1,11 @@ +:100000000101FF152204014D756C74695465636824 +:100010000050434D4349412035364B2044617461C3 +:10002000466178000000FF20040002010021020266 +:10003000001A05012780FF671B0FCF418B01550177 +:10004000550155AA60F80307281B08970108AA6004 +:10005000F802071B089F0108AA60E803071B08A70E +:0B0060000108AA60E802071400FF007E +:00000001FF +# +# Replacement CIS for Multitech MT5634ZLX modems +# diff --git a/firmware/cis/PCMLM28.cis.ihex b/firmware/cis/PCMLM28.cis.ihex new file mode 100644 index 00000000000..ffdfe8522ef --- /dev/null +++ b/firmware/cis/PCMLM28.cis.ihex @@ -0,0 +1,18 @@ +:1000000001030000FF151504014C494E4B53595391 +:100010000050434D4C4D3238000000FF2004430196 +:10002000ABC0210200001A05012FF803031B10E4E6 +:1000300001190155E06100031FF8020730FFFF1BA3 +:100040000BA50108E06120031FF802071B0BA601A6 +:1000500008E06140031FF802071B0BA70108E061DD +:1000600060031FF802071B0BA80108E06100031FD3 +:10007000E803071B0BA90108E06120031FE8030741 +:100080001B0BAA0108E06140031FE803071B0BAB31 +:100090000108E06160031FE803071B0BAC0108E0E7 +:1000A0006100031FE802071B0BAD0108E06120039C +:1000B0001FE802071B0BAE0108E06140031FE802C6 +:1000C000071B0BAF0108E06160031FE80207140083 +:0200D000FF002F +:00000001FF +# +# The on-card CIS says it is MFC-compliant, but it is not +# diff --git a/firmware/cis/RS-COM-2P.cis.ihex b/firmware/cis/RS-COM-2P.cis.ihex new file mode 100644 index 00000000000..0801ca5da80 --- /dev/null +++ b/firmware/cis/RS-COM-2P.cis.ihex @@ -0,0 +1,10 @@ +:1000000001030000FF1516040150434D4349410010 +:1000100052532D434F4D203250000000FF21020269 +:10002000011A0501030001011B0EC18118AA61E834 +:100030000307E8020730B89E1B0B820108AA615033 +:1000400002075802071B0B830108AA6160020768B8 +:0600500002071400FF008E +:00000001FF +# +# Replacement CIS for dual-serial-port IO card +# diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index aecf2519db7..d5e5559e31d 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -216,7 +216,6 @@ xfs_setfilesize( if (ip->i_d.di_size < isize) { ip->i_d.di_size = isize; ip->i_update_core = 1; - ip->i_update_size = 1; xfs_mark_inode_dirty_sync(ip); } diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 0542fd50764..988d8f87bc0 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -172,12 +172,21 @@ xfs_file_release( */ STATIC int xfs_file_fsync( - struct file *filp, - struct dentry *dentry, - int datasync) + struct file *file, + struct dentry *dentry, + int datasync) { - xfs_iflags_clear(XFS_I(dentry->d_inode), XFS_ITRUNCATED); - return -xfs_fsync(XFS_I(dentry->d_inode)); + struct inode *inode = dentry->d_inode; + struct xfs_inode *ip = XFS_I(inode); + int error; + + /* capture size updates in I/O completion before writing the inode. */ + error = filemap_fdatawait(inode->i_mapping); + if (error) + return error; + + xfs_iflags_clear(ip, XFS_ITRUNCATED); + return -xfs_fsync(ip); } STATIC int diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 6c32f1d63d8..da0159d99f8 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -43,7 +43,6 @@ #include "xfs_error.h" #include "xfs_itable.h" #include "xfs_rw.h" -#include "xfs_acl.h" #include "xfs_attr.h" #include "xfs_buf_item.h" #include "xfs_utils.h" diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index fde63a3c4ec..49e4a6aea73 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -812,19 +812,21 @@ write_retry: /* Handle various SYNC-type writes */ if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { + loff_t end = pos + ret - 1; int error2; xfs_iunlock(xip, iolock); if (need_i_mutex) mutex_unlock(&inode->i_mutex); - error2 = filemap_write_and_wait_range(mapping, pos, - pos + ret - 1); + + error2 = filemap_write_and_wait_range(mapping, pos, end); if (!error) error = error2; if (need_i_mutex) mutex_lock(&inode->i_mutex); xfs_ilock(xip, iolock); - error2 = xfs_write_sync_logforce(mp, xip); + + error2 = xfs_fsync(xip); if (!error) error = error2; } diff --git a/fs/xfs/linux-2.6/xfs_stats.c b/fs/xfs/linux-2.6/xfs_stats.c index c3526d445f6..76fdc586193 100644 --- a/fs/xfs/linux-2.6/xfs_stats.c +++ b/fs/xfs/linux-2.6/xfs_stats.c @@ -20,16 +20,9 @@ DEFINE_PER_CPU(struct xfsstats, xfsstats); -STATIC int -xfs_read_xfsstats( - char *buffer, - char **start, - off_t offset, - int count, - int *eof, - void *data) +static int xfs_stat_proc_show(struct seq_file *m, void *v) { - int c, i, j, len, val; + int c, i, j, val; __uint64_t xs_xstrat_bytes = 0; __uint64_t xs_write_bytes = 0; __uint64_t xs_read_bytes = 0; @@ -60,18 +53,18 @@ xfs_read_xfsstats( }; /* Loop over all stats groups */ - for (i=j=len = 0; i < ARRAY_SIZE(xstats); i++) { - len += sprintf(buffer + len, "%s", xstats[i].desc); + for (i=j = 0; i < ARRAY_SIZE(xstats); i++) { + seq_printf(m, "%s", xstats[i].desc); /* inner loop does each group */ while (j < xstats[i].endpoint) { val = 0; /* sum over all cpus */ for_each_possible_cpu(c) val += *(((__u32*)&per_cpu(xfsstats, c) + j)); - len += sprintf(buffer + len, " %u", val); + seq_printf(m, " %u", val); j++; } - buffer[len++] = '\n'; + seq_putc(m, '\n'); } /* extra precision counters */ for_each_possible_cpu(i) { @@ -80,36 +73,38 @@ xfs_read_xfsstats( xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes; } - len += sprintf(buffer + len, "xpc %Lu %Lu %Lu\n", + seq_printf(m, "xpc %Lu %Lu %Lu\n", xs_xstrat_bytes, xs_write_bytes, xs_read_bytes); - len += sprintf(buffer + len, "debug %u\n", + seq_printf(m, "debug %u\n", #if defined(DEBUG) 1); #else 0); #endif + return 0; +} - if (offset >= len) { - *start = buffer; - *eof = 1; - return 0; - } - *start = buffer + offset; - if ((len -= offset) > count) - return count; - *eof = 1; - - return len; +static int xfs_stat_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, xfs_stat_proc_show, NULL); } +static const struct file_operations xfs_stat_proc_fops = { + .owner = THIS_MODULE, + .open = xfs_stat_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + int xfs_init_procfs(void) { if (!proc_mkdir("fs/xfs", NULL)) goto out; - if (!create_proc_read_entry("fs/xfs/stat", 0, NULL, - xfs_read_xfsstats, NULL)) + if (!proc_create("fs/xfs/stat", 0, NULL, + &xfs_stat_proc_fops)) goto out_remove_entry; return 0; diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index a220d36f789..5d7c60ac77b 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -579,15 +579,19 @@ xfs_showargs( else if (mp->m_qflags & XFS_UQUOTA_ACCT) seq_puts(m, "," MNTOPT_UQUOTANOENF); - if (mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) - seq_puts(m, "," MNTOPT_PRJQUOTA); - else if (mp->m_qflags & XFS_PQUOTA_ACCT) - seq_puts(m, "," MNTOPT_PQUOTANOENF); - - if (mp->m_qflags & (XFS_GQUOTA_ACCT|XFS_OQUOTA_ENFD)) - seq_puts(m, "," MNTOPT_GRPQUOTA); - else if (mp->m_qflags & XFS_GQUOTA_ACCT) - seq_puts(m, "," MNTOPT_GQUOTANOENF); + /* Either project or group quotas can be active, not both */ + + if (mp->m_qflags & XFS_PQUOTA_ACCT) { + if (mp->m_qflags & XFS_OQUOTA_ENFD) + seq_puts(m, "," MNTOPT_PRJQUOTA); + else + seq_puts(m, "," MNTOPT_PQUOTANOENF); + } else if (mp->m_qflags & XFS_GQUOTA_ACCT) { + if (mp->m_qflags & XFS_OQUOTA_ENFD) + seq_puts(m, "," MNTOPT_GRPQUOTA); + else + seq_puts(m, "," MNTOPT_GQUOTANOENF); + } if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) seq_puts(m, "," MNTOPT_NOQUOTA); @@ -687,7 +691,7 @@ xfs_barrier_test( return error; } -void +STATIC void xfs_mountfs_check_barriers(xfs_mount_t *mp) { int error; diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 98ef624d9ba..320be6aea49 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c @@ -749,21 +749,6 @@ __xfs_inode_clear_reclaim_tag( XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG); } -void -xfs_inode_clear_reclaim_tag( - xfs_inode_t *ip) -{ - xfs_mount_t *mp = ip->i_mount; - xfs_perag_t *pag = xfs_get_perag(mp, ip->i_ino); - - read_lock(&pag->pag_ici_lock); - spin_lock(&ip->i_flags_lock); - __xfs_inode_clear_reclaim_tag(mp, pag, ip); - spin_unlock(&ip->i_flags_lock); - read_unlock(&pag->pag_ici_lock); - xfs_put_perag(mp, pag); -} - STATIC int xfs_reclaim_inode_now( struct xfs_inode *ip, diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h index 59120602588..27920eb7a82 100644 --- a/fs/xfs/linux-2.6/xfs_sync.h +++ b/fs/xfs/linux-2.6/xfs_sync.h @@ -49,7 +49,6 @@ int xfs_reclaim_inodes(struct xfs_mount *mp, int mode); void xfs_inode_set_reclaim_tag(struct xfs_inode *ip); void __xfs_inode_set_reclaim_tag(struct xfs_perag *pag, struct xfs_inode *ip); -void xfs_inode_clear_reclaim_tag(struct xfs_inode *ip); void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag, struct xfs_inode *ip); diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/quota/xfs_qm_stats.c index 21b08c0396a..83e7ea3e25f 100644 --- a/fs/xfs/quota/xfs_qm_stats.c +++ b/fs/xfs/quota/xfs_qm_stats.c @@ -48,50 +48,34 @@ struct xqmstats xqmstats; -STATIC int -xfs_qm_read_xfsquota( - char *buffer, - char **start, - off_t offset, - int count, - int *eof, - void *data) +static int xqm_proc_show(struct seq_file *m, void *v) { - int len; - /* maximum; incore; ratio free to inuse; freelist */ - len = sprintf(buffer, "%d\t%d\t%d\t%u\n", + seq_printf(m, "%d\t%d\t%d\t%u\n", ndquot, xfs_Gqm? atomic_read(&xfs_Gqm->qm_totaldquots) : 0, xfs_Gqm? xfs_Gqm->qm_dqfree_ratio : 0, xfs_Gqm? xfs_Gqm->qm_dqfreelist.qh_nelems : 0); - - if (offset >= len) { - *start = buffer; - *eof = 1; - return 0; - } - *start = buffer + offset; - if ((len -= offset) > count) - return count; - *eof = 1; - - return len; + return 0; } -STATIC int -xfs_qm_read_stats( - char *buffer, - char **start, - off_t offset, - int count, - int *eof, - void *data) +static int xqm_proc_open(struct inode *inode, struct file *file) { - int len; + return single_open(file, xqm_proc_show, NULL); +} + +static const struct file_operations xqm_proc_fops = { + .owner = THIS_MODULE, + .open = xqm_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +static int xqmstat_proc_show(struct seq_file *m, void *v) +{ /* quota performance statistics */ - len = sprintf(buffer, "qm %u %u %u %u %u %u %u %u\n", + seq_printf(m, "qm %u %u %u %u %u %u %u %u\n", xqmstats.xs_qm_dqreclaims, xqmstats.xs_qm_dqreclaim_misses, xqmstats.xs_qm_dquot_dups, @@ -100,25 +84,27 @@ xfs_qm_read_stats( xqmstats.xs_qm_dqwants, xqmstats.xs_qm_dqshake_reclaims, xqmstats.xs_qm_dqinact_reclaims); + return 0; +} - if (offset >= len) { - *start = buffer; - *eof = 1; - return 0; - } - *start = buffer + offset; - if ((len -= offset) > count) - return count; - *eof = 1; - - return len; +static int xqmstat_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, xqmstat_proc_show, NULL); } +static const struct file_operations xqmstat_proc_fops = { + .owner = THIS_MODULE, + .open = xqmstat_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + void xfs_qm_init_procfs(void) { - create_proc_read_entry("fs/xfs/xqmstat", 0, NULL, xfs_qm_read_stats, NULL); - create_proc_read_entry("fs/xfs/xqm", 0, NULL, xfs_qm_read_xfsquota, NULL); + proc_create("fs/xfs/xqmstat", 0, NULL, &xqmstat_proc_fops); + proc_create("fs/xfs/xqm", 0, NULL, &xqm_proc_fops); } void diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index f24b50b68d0..a5d54bf4931 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h @@ -198,6 +198,15 @@ typedef struct xfs_perag xfs_agino_t pagi_count; /* number of allocated inodes */ int pagb_count; /* pagb slots in use */ xfs_perag_busy_t *pagb_list; /* unstable blocks */ + + /* + * Inode allocation search lookup optimisation. + * If the pagino matches, the search for new inodes + * doesn't need to search the near ones again straight away + */ + xfs_agino_t pagl_pagino; + xfs_agino_t pagl_leftrec; + xfs_agino_t pagl_rightrec; #ifdef __KERNEL__ spinlock_t pagb_lock; /* lock for pagb_list */ diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 8ee5b5a76a2..8971fb09d38 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -3713,7 +3713,7 @@ done: * entry (null if none). Else, *lastxp will be set to the index * of the found entry; *gotp will contain the entry. */ -xfs_bmbt_rec_host_t * /* pointer to found extent entry */ +STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */ xfs_bmap_search_multi_extents( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_fileoff_t bno, /* block number searched for */ diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index 1b8ff9256bd..56f62d2edc3 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h @@ -392,17 +392,6 @@ xfs_bmap_count_blocks( int whichfork, int *count); -/* - * Search the extent records for the entry containing block bno. - * If bno lies in a hole, point to the next entry. If bno lies - * past eof, *eofp will be set, and *prevp will contain the last - * entry (null if none). Else, *lastxp will be set to the index - * of the found entry; *gotp will contain the entry. - */ -xfs_bmbt_rec_host_t * -xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *, - xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *); - #endif /* __KERNEL__ */ #endif /* __XFS_BMAP_H__ */ diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 5c1ade06578..eb7b702d069 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -202,16 +202,6 @@ xfs_bmbt_get_state( ext_flag); } -/* Endian flipping versions of the bmbt extraction functions */ -void -xfs_bmbt_disk_get_all( - xfs_bmbt_rec_t *r, - xfs_bmbt_irec_t *s) -{ - __xfs_bmbt_get_all(get_unaligned_be64(&r->l0), - get_unaligned_be64(&r->l1), s); -} - /* * Extract the blockcount field from an on disk bmap extent record. */ @@ -816,6 +806,16 @@ xfs_bmbt_trace_key( *l1 = 0; } +/* Endian flipping versions of the bmbt extraction functions */ +STATIC void +xfs_bmbt_disk_get_all( + xfs_bmbt_rec_t *r, + xfs_bmbt_irec_t *s) +{ + __xfs_bmbt_get_all(get_unaligned_be64(&r->l0), + get_unaligned_be64(&r->l1), s); +} + STATIC void xfs_bmbt_trace_record( struct xfs_btree_cur *cur, diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h index 0e8df007615..5549d495947 100644 --- a/fs/xfs/xfs_bmap_btree.h +++ b/fs/xfs/xfs_bmap_btree.h @@ -220,7 +220,6 @@ extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_host_t *r); extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_host_t *r); extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_host_t *r); -extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r); extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r); diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 26717388acf..52b5f14d0c3 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c @@ -646,46 +646,6 @@ xfs_btree_read_bufl( } /* - * Get a buffer for the block, return it read in. - * Short-form addressing. - */ -int /* error */ -xfs_btree_read_bufs( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ - xfs_agblock_t agbno, /* allocation group block number */ - uint lock, /* lock flags for read_buf */ - xfs_buf_t **bpp, /* buffer for agno/agbno */ - int refval) /* ref count value for buffer */ -{ - xfs_buf_t *bp; /* return value */ - xfs_daddr_t d; /* real disk block address */ - int error; - - ASSERT(agno != NULLAGNUMBER); - ASSERT(agbno != NULLAGBLOCK); - d = XFS_AGB_TO_DADDR(mp, agno, agbno); - if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, - mp->m_bsize, lock, &bp))) { - return error; - } - ASSERT(!bp || !XFS_BUF_GETERROR(bp)); - if (bp != NULL) { - switch (refval) { - case XFS_ALLOC_BTREE_REF: - XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval); - break; - case XFS_INO_BTREE_REF: - XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, refval); - break; - } - } - *bpp = bp; - return 0; -} - -/* * Read-ahead the block, don't wait for it, don't return a buffer. * Long-form addressing. */ @@ -2951,7 +2911,7 @@ error0: * inode we have to copy the single block it was pointing to into the * inode. */ -int +STATIC int xfs_btree_kill_iroot( struct xfs_btree_cur *cur) { diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h index 4f852b735b9..7fa07062bdd 100644 --- a/fs/xfs/xfs_btree.h +++ b/fs/xfs/xfs_btree.h @@ -379,20 +379,6 @@ xfs_btree_read_bufl( int refval);/* ref count value for buffer */ /* - * Get a buffer for the block, return it read in. - * Short-form addressing. - */ -int /* error */ -xfs_btree_read_bufs( - struct xfs_mount *mp, /* file system mount point */ - struct xfs_trans *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ - xfs_agblock_t agbno, /* allocation group block number */ - uint lock, /* lock flags for read_buf */ - struct xfs_buf **bpp, /* buffer for agno/agbno */ - int refval);/* ref count value for buffer */ - -/* * Read-ahead the block, don't wait for it, don't return a buffer. * Long-form addressing. */ @@ -432,7 +418,6 @@ int xfs_btree_decrement(struct xfs_btree_cur *, int, int *); int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *); int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *); int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *); -int xfs_btree_kill_iroot(struct xfs_btree_cur *); int xfs_btree_insert(struct xfs_btree_cur *, int *); int xfs_btree_delete(struct xfs_btree_cur *, int *); int xfs_btree_get_rec(struct xfs_btree_cur *, union xfs_btree_rec **, int *); diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 3120a3a5e20..ab64f3efb43 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c @@ -57,75 +57,35 @@ xfs_ialloc_cluster_alignment( } /* - * Lookup the record equal to ino in the btree given by cur. - */ -STATIC int /* error */ -xfs_inobt_lookup_eq( - struct xfs_btree_cur *cur, /* btree cursor */ - xfs_agino_t ino, /* starting inode of chunk */ - __int32_t fcnt, /* free inode count */ - xfs_inofree_t free, /* free inode mask */ - int *stat) /* success/failure */ -{ - cur->bc_rec.i.ir_startino = ino; - cur->bc_rec.i.ir_freecount = fcnt; - cur->bc_rec.i.ir_free = free; - return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat); -} - -/* - * Lookup the first record greater than or equal to ino - * in the btree given by cur. + * Lookup a record by ino in the btree given by cur. */ int /* error */ -xfs_inobt_lookup_ge( +xfs_inobt_lookup( struct xfs_btree_cur *cur, /* btree cursor */ xfs_agino_t ino, /* starting inode of chunk */ - __int32_t fcnt, /* free inode count */ - xfs_inofree_t free, /* free inode mask */ + xfs_lookup_t dir, /* <=, >=, == */ int *stat) /* success/failure */ { cur->bc_rec.i.ir_startino = ino; - cur->bc_rec.i.ir_freecount = fcnt; - cur->bc_rec.i.ir_free = free; - return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat); + cur->bc_rec.i.ir_freecount = 0; + cur->bc_rec.i.ir_free = 0; + return xfs_btree_lookup(cur, dir, stat); } /* - * Lookup the first record less than or equal to ino - * in the btree given by cur. - */ -int /* error */ -xfs_inobt_lookup_le( - struct xfs_btree_cur *cur, /* btree cursor */ - xfs_agino_t ino, /* starting inode of chunk */ - __int32_t fcnt, /* free inode count */ - xfs_inofree_t free, /* free inode mask */ - int *stat) /* success/failure */ -{ - cur->bc_rec.i.ir_startino = ino; - cur->bc_rec.i.ir_freecount = fcnt; - cur->bc_rec.i.ir_free = free; - return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat); -} - -/* - * Update the record referred to by cur to the value given - * by [ino, fcnt, free]. + * Update the record referred to by cur to the value given. * This either works (return 0) or gets an EFSCORRUPTED error. */ STATIC int /* error */ xfs_inobt_update( struct xfs_btree_cur *cur, /* btree cursor */ - xfs_agino_t ino, /* starting inode of chunk */ - __int32_t fcnt, /* free inode count */ - xfs_inofree_t free) /* free inode mask */ + xfs_inobt_rec_incore_t *irec) /* btree record */ { union xfs_btree_rec rec; - rec.inobt.ir_startino = cpu_to_be32(ino); - rec.inobt.ir_freecount = cpu_to_be32(fcnt); - rec.inobt.ir_free = cpu_to_be64(free); + rec.inobt.ir_startino = cpu_to_be32(irec->ir_startino); + rec.inobt.ir_freecount = cpu_to_be32(irec->ir_freecount); + rec.inobt.ir_free = cpu_to_be64(irec->ir_free); return xfs_btree_update(cur, &rec); } @@ -135,9 +95,7 @@ xfs_inobt_update( int /* error */ xfs_inobt_get_rec( struct xfs_btree_cur *cur, /* btree cursor */ - xfs_agino_t *ino, /* output: starting inode of chunk */ - __int32_t *fcnt, /* output: number of free inodes */ - xfs_inofree_t *free, /* output: free inode mask */ + xfs_inobt_rec_incore_t *irec, /* btree record */ int *stat) /* output: success/failure */ { union xfs_btree_rec *rec; @@ -145,14 +103,136 @@ xfs_inobt_get_rec( error = xfs_btree_get_rec(cur, &rec, stat); if (!error && *stat == 1) { - *ino = be32_to_cpu(rec->inobt.ir_startino); - *fcnt = be32_to_cpu(rec->inobt.ir_freecount); - *free = be64_to_cpu(rec->inobt.ir_free); + irec->ir_startino = be32_to_cpu(rec->inobt.ir_startino); + irec->ir_freecount = be32_to_cpu(rec->inobt.ir_freecount); + irec->ir_free = be64_to_cpu(rec->inobt.ir_free); } return error; } /* + * Verify that the number of free inodes in the AGI is correct. + */ +#ifdef DEBUG +STATIC int +xfs_check_agi_freecount( + struct xfs_btree_cur *cur, + struct xfs_agi *agi) +{ + if (cur->bc_nlevels == 1) { + xfs_inobt_rec_incore_t rec; + int freecount = 0; + int error; + int i; + + error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); + if (error) + return error; + + do { + error = xfs_inobt_get_rec(cur, &rec, &i); + if (error) + return error; + + if (i) { + freecount += rec.ir_freecount; + error = xfs_btree_increment(cur, 0, &i); + if (error) + return error; + } + } while (i == 1); + + if (!XFS_FORCED_SHUTDOWN(cur->bc_mp)) + ASSERT(freecount == be32_to_cpu(agi->agi_freecount)); + } + return 0; +} +#else +#define xfs_check_agi_freecount(cur, agi) 0 +#endif + +/* + * Initialise a new set of inodes. + */ +STATIC void +xfs_ialloc_inode_init( + struct xfs_mount *mp, + struct xfs_trans *tp, + xfs_agnumber_t agno, + xfs_agblock_t agbno, + xfs_agblock_t length, + unsigned int gen) +{ + struct xfs_buf *fbuf; + struct xfs_dinode *free; + int blks_per_cluster, nbufs, ninodes; + int version; + int i, j; + xfs_daddr_t d; + + /* + * Loop over the new block(s), filling in the inodes. + * For small block sizes, manipulate the inodes in buffers + * which are multiples of the blocks size. + */ + if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) { + blks_per_cluster = 1; + nbufs = length; + ninodes = mp->m_sb.sb_inopblock; + } else { + blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) / + mp->m_sb.sb_blocksize; + nbufs = length / blks_per_cluster; + ninodes = blks_per_cluster * mp->m_sb.sb_inopblock; + } + + /* + * Figure out what version number to use in the inodes we create. + * If the superblock version has caught up to the one that supports + * the new inode format, then use the new inode version. Otherwise + * use the old version so that old kernels will continue to be + * able to use the file system. + */ + if (xfs_sb_version_hasnlink(&mp->m_sb)) + version = 2; + else + version = 1; + + for (j = 0; j < nbufs; j++) { + /* + * Get the block. + */ + d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster)); + fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, + mp->m_bsize * blks_per_cluster, + XFS_BUF_LOCK); + ASSERT(fbuf); + ASSERT(!XFS_BUF_GETERROR(fbuf)); + + /* + * Initialize all inodes in this buffer and then log them. + * + * XXX: It would be much better if we had just one transaction + * to log a whole cluster of inodes instead of all the + * individual transactions causing a lot of log traffic. + */ + xfs_biozero(fbuf, 0, ninodes << mp->m_sb.sb_inodelog); + for (i = 0; i < ninodes; i++) { + int ioffset = i << mp->m_sb.sb_inodelog; + uint isize = sizeof(struct xfs_dinode); + + free = xfs_make_iptr(mp, fbuf, i); + free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); + free->di_version = version; + free->di_gen = cpu_to_be32(gen); + free->di_next_unlinked = cpu_to_be32(NULLAGINO); + xfs_trans_log_buf(tp, fbuf, ioffset, ioffset + isize - 1); + } + xfs_trans_inode_alloc_buf(tp, fbuf); + } +} + +/* * Allocate new inodes in the allocation group specified by agbp. * Return 0 for success, else error code. */ @@ -164,24 +244,15 @@ xfs_ialloc_ag_alloc( { xfs_agi_t *agi; /* allocation group header */ xfs_alloc_arg_t args; /* allocation argument structure */ - int blks_per_cluster; /* fs blocks per inode cluster */ xfs_btree_cur_t *cur; /* inode btree cursor */ - xfs_daddr_t d; /* disk addr of buffer */ xfs_agnumber_t agno; int error; - xfs_buf_t *fbuf; /* new free inodes' buffer */ - xfs_dinode_t *free; /* new free inode structure */ - int i; /* inode counter */ - int j; /* block counter */ - int nbufs; /* num bufs of new inodes */ + int i; xfs_agino_t newino; /* new first inode's number */ xfs_agino_t newlen; /* new number of inodes */ - int ninodes; /* num inodes per buf */ xfs_agino_t thisino; /* current inode number, for loop */ - int version; /* inode version number to use */ int isaligned = 0; /* inode allocation at stripe unit */ /* boundary */ - unsigned int gen; args.tp = tp; args.mp = tp->t_mountp; @@ -202,12 +273,12 @@ xfs_ialloc_ag_alloc( */ agi = XFS_BUF_TO_AGI(agbp); newino = be32_to_cpu(agi->agi_newino); + agno = be32_to_cpu(agi->agi_seqno); args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) + XFS_IALLOC_BLOCKS(args.mp); if (likely(newino != NULLAGINO && (args.agbno < be32_to_cpu(agi->agi_length)))) { - args.fsbno = XFS_AGB_TO_FSB(args.mp, - be32_to_cpu(agi->agi_seqno), args.agbno); + args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno); args.type = XFS_ALLOCTYPE_THIS_BNO; args.mod = args.total = args.wasdel = args.isfl = args.userdata = args.minalignslop = 0; @@ -258,8 +329,7 @@ xfs_ialloc_ag_alloc( * For now, just allocate blocks up front. */ args.agbno = be32_to_cpu(agi->agi_root); - args.fsbno = XFS_AGB_TO_FSB(args.mp, - be32_to_cpu(agi->agi_seqno), args.agbno); + args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno); /* * Allocate a fixed-size extent of inodes. */ @@ -282,8 +352,7 @@ xfs_ialloc_ag_alloc( if (isaligned && args.fsbno == NULLFSBLOCK) { args.type = XFS_ALLOCTYPE_NEAR_BNO; args.agbno = be32_to_cpu(agi->agi_root); - args.fsbno = XFS_AGB_TO_FSB(args.mp, - be32_to_cpu(agi->agi_seqno), args.agbno); + args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno); args.alignment = xfs_ialloc_cluster_alignment(&args); if ((error = xfs_alloc_vextent(&args))) return error; @@ -294,85 +363,30 @@ xfs_ialloc_ag_alloc( return 0; } ASSERT(args.len == args.minlen); - /* - * Convert the results. - */ - newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0); - /* - * Loop over the new block(s), filling in the inodes. - * For small block sizes, manipulate the inodes in buffers - * which are multiples of the blocks size. - */ - if (args.mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(args.mp)) { - blks_per_cluster = 1; - nbufs = (int)args.len; - ninodes = args.mp->m_sb.sb_inopblock; - } else { - blks_per_cluster = XFS_INODE_CLUSTER_SIZE(args.mp) / - args.mp->m_sb.sb_blocksize; - nbufs = (int)args.len / blks_per_cluster; - ninodes = blks_per_cluster * args.mp->m_sb.sb_inopblock; - } - /* - * Figure out what version number to use in the inodes we create. - * If the superblock version has caught up to the one that supports - * the new inode format, then use the new inode version. Otherwise - * use the old version so that old kernels will continue to be - * able to use the file system. - */ - if (xfs_sb_version_hasnlink(&args.mp->m_sb)) - version = 2; - else - version = 1; /* + * Stamp and write the inode buffers. + * * Seed the new inode cluster with a random generation number. This * prevents short-term reuse of generation numbers if a chunk is * freed and then immediately reallocated. We use random numbers * rather than a linear progression to prevent the next generation * number from being easily guessable. */ - gen = random32(); - for (j = 0; j < nbufs; j++) { - /* - * Get the block. - */ - d = XFS_AGB_TO_DADDR(args.mp, be32_to_cpu(agi->agi_seqno), - args.agbno + (j * blks_per_cluster)); - fbuf = xfs_trans_get_buf(tp, args.mp->m_ddev_targp, d, - args.mp->m_bsize * blks_per_cluster, - XFS_BUF_LOCK); - ASSERT(fbuf); - ASSERT(!XFS_BUF_GETERROR(fbuf)); + xfs_ialloc_inode_init(args.mp, tp, agno, args.agbno, args.len, + random32()); - /* - * Initialize all inodes in this buffer and then log them. - * - * XXX: It would be much better if we had just one transaction to - * log a whole cluster of inodes instead of all the individual - * transactions causing a lot of log traffic. - */ - xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog); - for (i = 0; i < ninodes; i++) { - int ioffset = i << args.mp->m_sb.sb_inodelog; - uint isize = sizeof(struct xfs_dinode); - - free = xfs_make_iptr(args.mp, fbuf, i); - free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); - free->di_version = version; - free->di_gen = cpu_to_be32(gen); - free->di_next_unlinked = cpu_to_be32(NULLAGINO); - xfs_trans_log_buf(tp, fbuf, ioffset, ioffset + isize - 1); - } - xfs_trans_inode_alloc_buf(tp, fbuf); - } + /* + * Convert the results. + */ + newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0); be32_add_cpu(&agi->agi_count, newlen); be32_add_cpu(&agi->agi_freecount, newlen); - agno = be32_to_cpu(agi->agi_seqno); down_read(&args.mp->m_peraglock); args.mp->m_perag[agno].pagi_freecount += newlen; up_read(&args.mp->m_peraglock); agi->agi_newino = cpu_to_be32(newino); + /* * Insert records describing the new inode chunk into the btree. */ @@ -380,13 +394,17 @@ xfs_ialloc_ag_alloc( for (thisino = newino; thisino < newino + newlen; thisino += XFS_INODES_PER_CHUNK) { - if ((error = xfs_inobt_lookup_eq(cur, thisino, - XFS_INODES_PER_CHUNK, XFS_INOBT_ALL_FREE, &i))) { + cur->bc_rec.i.ir_startino = thisino; + cur->bc_rec.i.ir_freecount = XFS_INODES_PER_CHUNK; + cur->bc_rec.i.ir_free = XFS_INOBT_ALL_FREE; + error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, &i); + if (error) { xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); return error; } ASSERT(i == 0); - if ((error = xfs_btree_insert(cur, &i))) { + error = xfs_btree_insert(cur, &i); + if (error) { xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); return error; } @@ -539,6 +557,62 @@ nextag: } /* + * Try to retrieve the next record to the left/right from the current one. + */ +STATIC int +xfs_ialloc_next_rec( + struct xfs_btree_cur *cur, + xfs_inobt_rec_incore_t *rec, + int *done, + int left) +{ + int error; + int i; + + if (left) + error = xfs_btree_decrement(cur, 0, &i); + else + error = xfs_btree_increment(cur, 0, &i); + + if (error) + return error; + *done = !i; + if (i) { + error = xfs_inobt_get_rec(cur, rec, &i); + if (error) + return error; + XFS_WANT_CORRUPTED_RETURN(i == 1); + } + + return 0; +} + +STATIC int +xfs_ialloc_get_rec( + struct xfs_btree_cur *cur, + xfs_agino_t agino, + xfs_inobt_rec_incore_t *rec, + int *done, + int left) +{ + int error; + int i; + + error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_EQ, &i); + if (error) + return error; + *done = !i; + if (i) { + error = xfs_inobt_get_rec(cur, rec, &i); + if (error) + return error; + XFS_WANT_CORRUPTED_RETURN(i == 1); + } + + return 0; +} + +/* * Visible inode allocation functions. */ @@ -592,8 +666,8 @@ xfs_dialloc( int j; /* result code */ xfs_mount_t *mp; /* file system mount structure */ int offset; /* index of inode in chunk */ - xfs_agino_t pagino; /* parent's a.g. relative inode # */ - xfs_agnumber_t pagno; /* parent's allocation group number */ + xfs_agino_t pagino; /* parent's AG relative inode # */ + xfs_agnumber_t pagno; /* parent's AG number */ xfs_inobt_rec_incore_t rec; /* inode allocation record */ xfs_agnumber_t tagno; /* testing allocation group number */ xfs_btree_cur_t *tcur; /* temp cursor */ @@ -716,6 +790,8 @@ nextag: */ agno = tagno; *IO_agbp = NULL; + + restart_pagno: cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno)); /* * If pagino is 0 (this is the root inode allocation) use newino. @@ -723,220 +799,199 @@ nextag: */ if (!pagino) pagino = be32_to_cpu(agi->agi_newino); -#ifdef DEBUG - if (cur->bc_nlevels == 1) { - int freecount = 0; - if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i))) - goto error0; - XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - do { - if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino, - &rec.ir_freecount, &rec.ir_free, &i))) - goto error0; - XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - freecount += rec.ir_freecount; - if ((error = xfs_btree_increment(cur, 0, &i))) - goto error0; - } while (i == 1); + error = xfs_check_agi_freecount(cur, agi); + if (error) + goto error0; - ASSERT(freecount == be32_to_cpu(agi->agi_freecount) || - XFS_FORCED_SHUTDOWN(mp)); - } -#endif /* - * If in the same a.g. as the parent, try to get near the parent. + * If in the same AG as the parent, try to get near the parent. */ if (pagno == agno) { - if ((error = xfs_inobt_lookup_le(cur, pagino, 0, 0, &i))) + xfs_perag_t *pag = &mp->m_perag[agno]; + int doneleft; /* done, to the left */ + int doneright; /* done, to the right */ + int searchdistance = 10; + + error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i); + if (error) + goto error0; + XFS_WANT_CORRUPTED_GOTO(i == 1, error0); + + error = xfs_inobt_get_rec(cur, &rec, &j); + if (error) goto error0; - if (i != 0 && - (error = xfs_inobt_get_rec(cur, &rec.ir_startino, - &rec.ir_freecount, &rec.ir_free, &j)) == 0 && - j == 1 && - rec.ir_freecount > 0) { + XFS_WANT_CORRUPTED_GOTO(i == 1, error0); + + if (rec.ir_freecount > 0) { /* * Found a free inode in the same chunk - * as parent, done. + * as the parent, done. */ + goto alloc_inode; } + + + /* + * In the same AG as parent, but parent's chunk is full. + */ + + /* duplicate the cursor, search left & right simultaneously */ + error = xfs_btree_dup_cursor(cur, &tcur); + if (error) + goto error0; + /* - * In the same a.g. as parent, but parent's chunk is full. + * Skip to last blocks looked up if same parent inode. */ - else { - int doneleft; /* done, to the left */ - int doneright; /* done, to the right */ + if (pagino != NULLAGINO && + pag->pagl_pagino == pagino && + pag->pagl_leftrec != NULLAGINO && + pag->pagl_rightrec != NULLAGINO) { + error = xfs_ialloc_get_rec(tcur, pag->pagl_leftrec, + &trec, &doneleft, 1); + if (error) + goto error1; + error = xfs_ialloc_get_rec(cur, pag->pagl_rightrec, + &rec, &doneright, 0); if (error) - goto error0; - ASSERT(i == 1); - ASSERT(j == 1); - /* - * Duplicate the cursor, search left & right - * simultaneously. - */ - if ((error = xfs_btree_dup_cursor(cur, &tcur))) - goto error0; - /* - * Search left with tcur, back up 1 record. - */ - if ((error = xfs_btree_decrement(tcur, 0, &i))) goto error1; - doneleft = !i; - if (!doneleft) { - if ((error = xfs_inobt_get_rec(tcur, - &trec.ir_startino, - &trec.ir_freecount, - &trec.ir_free, &i))) - goto error1; - XFS_WANT_CORRUPTED_GOTO(i == 1, error1); - } - /* - * Search right with cur, go forward 1 record. - */ - if ((error = xfs_btree_increment(cur, 0, &i))) + } else { + /* search left with tcur, back up 1 record */ + error = xfs_ialloc_next_rec(tcur, &trec, &doneleft, 1); + if (error) goto error1; - doneright = !i; - if (!doneright) { - if ((error = xfs_inobt_get_rec(cur, - &rec.ir_startino, - &rec.ir_freecount, - &rec.ir_free, &i))) - goto error1; - XFS_WANT_CORRUPTED_GOTO(i == 1, error1); - } - /* - * Loop until we find the closest inode chunk - * with a free one. - */ - while (!doneleft || !doneright) { - int useleft; /* using left inode - chunk this time */ + /* search right with cur, go forward 1 record. */ + error = xfs_ialloc_next_rec(cur, &rec, &doneright, 0); + if (error) + goto error1; + } + + /* + * Loop until we find an inode chunk with a free inode. + */ + while (!doneleft || !doneright) { + int useleft; /* using left inode chunk this time */ + + if (!--searchdistance) { /* - * Figure out which block is closer, - * if both are valid. - */ - if (!doneleft && !doneright) - useleft = - pagino - - (trec.ir_startino + - XFS_INODES_PER_CHUNK - 1) < - rec.ir_startino - pagino; - else - useleft = !doneleft; - /* - * If checking the left, does it have - * free inodes? - */ - if (useleft && trec.ir_freecount) { - /* - * Yes, set it up as the chunk to use. - */ - rec = trec; - xfs_btree_del_cursor(cur, - XFS_BTREE_NOERROR); - cur = tcur; - break; - } - /* - * If checking the right, does it have - * free inodes? - */ - if (!useleft && rec.ir_freecount) { - /* - * Yes, it's already set up. - */ - xfs_btree_del_cursor(tcur, - XFS_BTREE_NOERROR); - break; - } - /* - * If used the left, get another one - * further left. - */ - if (useleft) { - if ((error = xfs_btree_decrement(tcur, 0, - &i))) - goto error1; - doneleft = !i; - if (!doneleft) { - if ((error = xfs_inobt_get_rec( - tcur, - &trec.ir_startino, - &trec.ir_freecount, - &trec.ir_free, &i))) - goto error1; - XFS_WANT_CORRUPTED_GOTO(i == 1, - error1); - } - } - /* - * If used the right, get another one - * further right. + * Not in range - save last search + * location and allocate a new inode */ - else { - if ((error = xfs_btree_increment(cur, 0, - &i))) - goto error1; - doneright = !i; - if (!doneright) { - if ((error = xfs_inobt_get_rec( - cur, - &rec.ir_startino, - &rec.ir_freecount, - &rec.ir_free, &i))) - goto error1; - XFS_WANT_CORRUPTED_GOTO(i == 1, - error1); - } - } + pag->pagl_leftrec = trec.ir_startino; + pag->pagl_rightrec = rec.ir_startino; + pag->pagl_pagino = pagino; + goto newino; + } + + /* figure out the closer block if both are valid. */ + if (!doneleft && !doneright) { + useleft = pagino - + (trec.ir_startino + XFS_INODES_PER_CHUNK - 1) < + rec.ir_startino - pagino; + } else { + useleft = !doneleft; } - ASSERT(!doneleft || !doneright); + + /* free inodes to the left? */ + if (useleft && trec.ir_freecount) { + rec = trec; + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + cur = tcur; + + pag->pagl_leftrec = trec.ir_startino; + pag->pagl_rightrec = rec.ir_startino; + pag->pagl_pagino = pagino; + goto alloc_inode; + } + + /* free inodes to the right? */ + if (!useleft && rec.ir_freecount) { + xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); + + pag->pagl_leftrec = trec.ir_startino; + pag->pagl_rightrec = rec.ir_startino; + pag->pagl_pagino = pagino; + goto alloc_inode; + } + + /* get next record to check */ + if (useleft) { + error = xfs_ialloc_next_rec(tcur, &trec, + &doneleft, 1); + } else { + error = xfs_ialloc_next_rec(cur, &rec, + &doneright, 0); + } + if (error) + goto error1; } + + /* + * We've reached the end of the btree. because + * we are only searching a small chunk of the + * btree each search, there is obviously free + * inodes closer to the parent inode than we + * are now. restart the search again. + */ + pag->pagl_pagino = NULLAGINO; + pag->pagl_leftrec = NULLAGINO; + pag->pagl_rightrec = NULLAGINO; + xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + goto restart_pagno; } + /* - * In a different a.g. from the parent. + * In a different AG from the parent. * See if the most recently allocated block has any free. */ - else if (be32_to_cpu(agi->agi_newino) != NULLAGINO) { - if ((error = xfs_inobt_lookup_eq(cur, - be32_to_cpu(agi->agi_newino), 0, 0, &i))) +newino: + if (be32_to_cpu(agi->agi_newino) != NULLAGINO) { + error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino), + XFS_LOOKUP_EQ, &i); + if (error) goto error0; - if (i == 1 && - (error = xfs_inobt_get_rec(cur, &rec.ir_startino, - &rec.ir_freecount, &rec.ir_free, &j)) == 0 && - j == 1 && - rec.ir_freecount > 0) { - /* - * The last chunk allocated in the group still has - * a free inode. - */ - } - /* - * None left in the last group, search the whole a.g. - */ - else { + + if (i == 1) { + error = xfs_inobt_get_rec(cur, &rec, &j); if (error) goto error0; - if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i))) - goto error0; - ASSERT(i == 1); - for (;;) { - if ((error = xfs_inobt_get_rec(cur, - &rec.ir_startino, - &rec.ir_freecount, &rec.ir_free, - &i))) - goto error0; - XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - if (rec.ir_freecount > 0) - break; - if ((error = xfs_btree_increment(cur, 0, &i))) - goto error0; - XFS_WANT_CORRUPTED_GOTO(i == 1, error0); + + if (j == 1 && rec.ir_freecount > 0) { + /* + * The last chunk allocated in the group + * still has a free inode. + */ + goto alloc_inode; } } } + + /* + * None left in the last group, search the whole AG + */ + error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); + if (error) + goto error0; + XFS_WANT_CORRUPTED_GOTO(i == 1, error0); + + for (;;) { + error = xfs_inobt_get_rec(cur, &rec, &i); + if (error) + goto error0; + XFS_WANT_CORRUPTED_GOTO(i == 1, error0); + if (rec.ir_freecount > 0) + break; + error = xfs_btree_increment(cur, 0, &i); + if (error) + goto error0; + XFS_WANT_CORRUPTED_GOTO(i == 1, error0); + } + +alloc_inode: offset = xfs_ialloc_find_free(&rec.ir_free); ASSERT(offset >= 0); ASSERT(offset < XFS_INODES_PER_CHUNK); @@ -945,33 +1000,19 @@ nextag: ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset); rec.ir_free &= ~XFS_INOBT_MASK(offset); rec.ir_freecount--; - if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount, - rec.ir_free))) + error = xfs_inobt_update(cur, &rec); + if (error) goto error0; be32_add_cpu(&agi->agi_freecount, -1); xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); down_read(&mp->m_peraglock); mp->m_perag[tagno].pagi_freecount--; up_read(&mp->m_peraglock); -#ifdef DEBUG - if (cur->bc_nlevels == 1) { - int freecount = 0; - if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i))) - goto error0; - do { - if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino, - &rec.ir_freecount, &rec.ir_free, &i))) - goto error0; - XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - freecount += rec.ir_freecount; - if ((error = xfs_btree_increment(cur, 0, &i))) - goto error0; - } while (i == 1); - ASSERT(freecount == be32_to_cpu(agi->agi_freecount) || - XFS_FORCED_SHUTDOWN(mp)); - } -#endif + error = xfs_check_agi_freecount(cur, agi); + if (error) + goto error0; + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1); *inop = ino; @@ -1062,38 +1103,23 @@ xfs_difree( * Initialize the cursor. */ cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); -#ifdef DEBUG - if (cur->bc_nlevels == 1) { - int freecount = 0; - if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i))) - goto error0; - do { - if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino, - &rec.ir_freecount, &rec.ir_free, &i))) - goto error0; - if (i) { - freecount += rec.ir_freecount; - if ((error = xfs_btree_increment(cur, 0, &i))) - goto error0; - } - } while (i == 1); - ASSERT(freecount == be32_to_cpu(agi->agi_freecount) || - XFS_FORCED_SHUTDOWN(mp)); - } -#endif + error = xfs_check_agi_freecount(cur, agi); + if (error) + goto error0; + /* * Look for the entry describing this inode. */ - if ((error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i))) { + if ((error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i))) { cmn_err(CE_WARN, - "xfs_difree: xfs_inobt_lookup_le returned() an error %d on %s. Returning error.", + "xfs_difree: xfs_inobt_lookup returned() an error %d on %s. Returning error.", error, mp->m_fsname); goto error0; } XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino, &rec.ir_freecount, - &rec.ir_free, &i))) { + error = xfs_inobt_get_rec(cur, &rec, &i); + if (error) { cmn_err(CE_WARN, "xfs_difree: xfs_inobt_get_rec() returned an error %d on %s. Returning error.", error, mp->m_fsname); @@ -1148,12 +1174,14 @@ xfs_difree( } else { *delete = 0; - if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount, rec.ir_free))) { + error = xfs_inobt_update(cur, &rec); + if (error) { cmn_err(CE_WARN, - "xfs_difree: xfs_inobt_update() returned an error %d on %s. Returning error.", + "xfs_difree: xfs_inobt_update returned an error %d on %s.", error, mp->m_fsname); goto error0; } + /* * Change the inode free counts and log the ag/sb changes. */ @@ -1165,28 +1193,10 @@ xfs_difree( xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1); } -#ifdef DEBUG - if (cur->bc_nlevels == 1) { - int freecount = 0; + error = xfs_check_agi_freecount(cur, agi); + if (error) + goto error0; - if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i))) - goto error0; - do { - if ((error = xfs_inobt_get_rec(cur, - &rec.ir_startino, - &rec.ir_freecount, - &rec.ir_free, &i))) - goto error0; - if (i) { - freecount += rec.ir_freecount; - if ((error = xfs_btree_increment(cur, 0, &i))) - goto error0; - } - } while (i == 1); - ASSERT(freecount == be32_to_cpu(agi->agi_freecount) || - XFS_FORCED_SHUTDOWN(mp)); - } -#endif xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); return 0; @@ -1297,9 +1307,7 @@ xfs_imap( chunk_agbno = agbno - offset_agbno; } else { xfs_btree_cur_t *cur; /* inode btree cursor */ - xfs_agino_t chunk_agino; /* first agino in inode chunk */ - __int32_t chunk_cnt; /* count of free inodes in chunk */ - xfs_inofree_t chunk_free; /* mask of free inodes in chunk */ + xfs_inobt_rec_incore_t chunk_rec; xfs_buf_t *agbp; /* agi buffer */ int i; /* temp state */ @@ -1315,15 +1323,14 @@ xfs_imap( } cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); - error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i); + error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i); if (error) { xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " - "xfs_inobt_lookup_le() failed"); + "xfs_inobt_lookup() failed"); goto error0; } - error = xfs_inobt_get_rec(cur, &chunk_agino, &chunk_cnt, - &chunk_free, &i); + error = xfs_inobt_get_rec(cur, &chunk_rec, &i); if (error) { xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " "xfs_inobt_get_rec() failed"); @@ -1341,7 +1348,7 @@ xfs_imap( xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); if (error) return error; - chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_agino); + chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_rec.ir_startino); offset_agbno = agbno - chunk_agbno; } diff --git a/fs/xfs/xfs_ialloc.h b/fs/xfs/xfs_ialloc.h index aeee8278f92..bb5385475e1 100644 --- a/fs/xfs/xfs_ialloc.h +++ b/fs/xfs/xfs_ialloc.h @@ -150,23 +150,15 @@ xfs_ialloc_pagi_init( xfs_agnumber_t agno); /* allocation group number */ /* - * Lookup the first record greater than or equal to ino - * in the btree given by cur. + * Lookup a record by ino in the btree given by cur. */ -int xfs_inobt_lookup_ge(struct xfs_btree_cur *cur, xfs_agino_t ino, - __int32_t fcnt, xfs_inofree_t free, int *stat); - -/* - * Lookup the first record less than or equal to ino - * in the btree given by cur. - */ -int xfs_inobt_lookup_le(struct xfs_btree_cur *cur, xfs_agino_t ino, - __int32_t fcnt, xfs_inofree_t free, int *stat); +int xfs_inobt_lookup(struct xfs_btree_cur *cur, xfs_agino_t ino, + xfs_lookup_t dir, int *stat); /* * Get the data from the pointed-to record. */ -extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur, xfs_agino_t *ino, - __int32_t *fcnt, xfs_inofree_t *free, int *stat); +extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur, + xfs_inobt_rec_incore_t *rec, int *stat); #endif /* __XFS_IALLOC_H__ */ diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index ecbf8b4d2e2..80e526489be 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -82,7 +82,6 @@ xfs_inode_alloc( memset(&ip->i_df, 0, sizeof(xfs_ifork_t)); ip->i_flags = 0; ip->i_update_core = 0; - ip->i_update_size = 0; ip->i_delayed_blks = 0; memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); ip->i_size = 0; @@ -456,32 +455,6 @@ out_error_or_again: return error; } - -/* - * Look for the inode corresponding to the given ino in the hash table. - * If it is there and its i_transp pointer matches tp, return it. - * Otherwise, return NULL. - */ -xfs_inode_t * -xfs_inode_incore(xfs_mount_t *mp, - xfs_ino_t ino, - xfs_trans_t *tp) -{ - xfs_inode_t *ip; - xfs_perag_t *pag; - - pag = xfs_get_perag(mp, ino); - read_lock(&pag->pag_ici_lock); - ip = radix_tree_lookup(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ino)); - read_unlock(&pag->pag_ici_lock); - xfs_put_perag(mp, pag); - - /* the returned inode must match the transaction */ - if (ip && (ip->i_transp != tp)) - return NULL; - return ip; -} - /* * Decrement reference count of an inode structure and unlock it. * diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index da428b3fe0f..c1dc7ef5a1d 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -651,7 +651,7 @@ xfs_iformat_btree( return 0; } -void +STATIC void xfs_dinode_from_disk( xfs_icdinode_t *to, xfs_dinode_t *from) @@ -1247,7 +1247,7 @@ xfs_isize_check( * In that case the pages will still be in memory, but the inode size * will never have been updated. */ -xfs_fsize_t +STATIC xfs_fsize_t xfs_file_last_byte( xfs_inode_t *ip) { @@ -3837,7 +3837,7 @@ xfs_iext_inline_to_direct( /* * Resize an extent indirection array to new_size bytes. */ -void +STATIC void xfs_iext_realloc_indirect( xfs_ifork_t *ifp, /* inode fork pointer */ int new_size) /* new indirection array size */ @@ -3862,7 +3862,7 @@ xfs_iext_realloc_indirect( /* * Switch from indirection array to linear (direct) extent allocations. */ -void +STATIC void xfs_iext_indirect_to_direct( xfs_ifork_t *ifp) /* inode fork pointer */ { diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 65f24a3cc99..0b38b9a869e 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -261,7 +261,6 @@ typedef struct xfs_inode { /* Miscellaneous state. */ unsigned short i_flags; /* see defined flags below */ unsigned char i_update_core; /* timestamps/size is dirty */ - unsigned char i_update_size; /* di_size field is dirty */ unsigned int i_delayed_blks; /* count of delay alloc blks */ xfs_icdinode_t i_d; /* most of ondisk inode */ @@ -468,8 +467,6 @@ static inline void xfs_ifunlock(xfs_inode_t *ip) /* * xfs_iget.c prototypes. */ -xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, - struct xfs_trans *); int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, uint, uint, xfs_inode_t **, xfs_daddr_t); void xfs_iput(xfs_inode_t *, uint); @@ -504,7 +501,6 @@ void xfs_ipin(xfs_inode_t *); void xfs_iunpin(xfs_inode_t *); int xfs_iflush(xfs_inode_t *, uint); void xfs_ichgtime(xfs_inode_t *, int); -xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); void xfs_lock_inodes(xfs_inode_t **, int, uint); void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); @@ -572,8 +568,6 @@ int xfs_itobp(struct xfs_mount *, struct xfs_trans *, struct xfs_buf **, uint); int xfs_iread(struct xfs_mount *, struct xfs_trans *, struct xfs_inode *, xfs_daddr_t, uint); -void xfs_dinode_from_disk(struct xfs_icdinode *, - struct xfs_dinode *); void xfs_dinode_to_disk(struct xfs_dinode *, struct xfs_icdinode *); void xfs_idestroy_fork(struct xfs_inode *, int); @@ -592,8 +586,6 @@ void xfs_iext_remove_inline(xfs_ifork_t *, xfs_extnum_t, int); void xfs_iext_remove_direct(xfs_ifork_t *, xfs_extnum_t, int); void xfs_iext_remove_indirect(xfs_ifork_t *, xfs_extnum_t, int); void xfs_iext_realloc_direct(xfs_ifork_t *, int); -void xfs_iext_realloc_indirect(xfs_ifork_t *, int); -void xfs_iext_indirect_to_direct(xfs_ifork_t *); void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t); void xfs_iext_inline_to_direct(xfs_ifork_t *, int); void xfs_iext_destroy(xfs_ifork_t *); diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 977c4aec587..47d5b663c37 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -263,14 +263,6 @@ xfs_inode_item_format( } /* - * We don't have to worry about re-ordering here because - * the update_size field is protected by the inode lock - * and we have that held in exclusive mode. - */ - if (ip->i_update_size) - ip->i_update_size = 0; - - /* * Make sure to get the latest atime from the Linux inode. */ xfs_synchronize_atime(ip); @@ -712,8 +704,6 @@ xfs_inode_item_unlock( * Clear out the fields of the inode log item particular * to the current transaction. */ - iip->ili_ilock_recur = 0; - iip->ili_iolock_recur = 0; iip->ili_flags = 0; /* diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index a52ac125f05..65bae4c9b8b 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h @@ -137,8 +137,6 @@ typedef struct xfs_inode_log_item { struct xfs_inode *ili_inode; /* inode ptr */ xfs_lsn_t ili_flush_lsn; /* lsn at last flush */ xfs_lsn_t ili_last_lsn; /* lsn at last transaction */ - unsigned short ili_ilock_recur; /* lock recursion count */ - unsigned short ili_iolock_recur; /* lock recursion count */ unsigned short ili_flags; /* misc flags */ unsigned short ili_logged; /* flushed logged data */ unsigned int ili_last_fields; /* fields when flushed */ diff --git a/fs/xfs/xfs_inum.h b/fs/xfs/xfs_inum.h index 7a28191cb0d..b8e4ee4e89a 100644 --- a/fs/xfs/xfs_inum.h +++ b/fs/xfs/xfs_inum.h @@ -72,7 +72,6 @@ struct xfs_mount; #if XFS_BIG_INUMS #define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 56) - 1ULL)) -#define XFS_INO64_OFFSET ((xfs_ino_t)(1ULL << 32)) #else #define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 32) - 1ULL)) #endif diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index aeb2d2221c7..b68f9107e26 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -39,7 +39,7 @@ #include "xfs_error.h" #include "xfs_btree.h" -int +STATIC int xfs_internal_inum( xfs_mount_t *mp, xfs_ino_t ino) @@ -353,9 +353,6 @@ xfs_bulkstat( int end_of_ag; /* set if we've seen the ag end */ int error; /* error code */ int fmterror;/* bulkstat formatter result */ - __int32_t gcnt; /* current btree rec's count */ - xfs_inofree_t gfree; /* current btree rec's free mask */ - xfs_agino_t gino; /* current btree rec's start inode */ int i; /* loop index */ int icount; /* count of inodes good in irbuf */ size_t irbsize; /* size of irec buffer in bytes */ @@ -442,40 +439,43 @@ xfs_bulkstat( * we need to get the remainder of the chunk we're in. */ if (agino > 0) { + xfs_inobt_rec_incore_t r; + /* * Lookup the inode chunk that this inode lives in. */ - error = xfs_inobt_lookup_le(cur, agino, 0, 0, &tmp); + error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, + &tmp); if (!error && /* no I/O error */ tmp && /* lookup succeeded */ /* got the record, should always work */ - !(error = xfs_inobt_get_rec(cur, &gino, &gcnt, - &gfree, &i)) && + !(error = xfs_inobt_get_rec(cur, &r, &i)) && i == 1 && /* this is the right chunk */ - agino < gino + XFS_INODES_PER_CHUNK && + agino < r.ir_startino + XFS_INODES_PER_CHUNK && /* lastino was not last in chunk */ - (chunkidx = agino - gino + 1) < + (chunkidx = agino - r.ir_startino + 1) < XFS_INODES_PER_CHUNK && /* there are some left allocated */ xfs_inobt_maskn(chunkidx, - XFS_INODES_PER_CHUNK - chunkidx) & ~gfree) { + XFS_INODES_PER_CHUNK - chunkidx) & + ~r.ir_free) { /* * Grab the chunk record. Mark all the * uninteresting inodes (because they're * before our start point) free. */ for (i = 0; i < chunkidx; i++) { - if (XFS_INOBT_MASK(i) & ~gfree) - gcnt++; + if (XFS_INOBT_MASK(i) & ~r.ir_free) + r.ir_freecount++; } - gfree |= xfs_inobt_maskn(0, chunkidx); - irbp->ir_startino = gino; - irbp->ir_freecount = gcnt; - irbp->ir_free = gfree; + r.ir_free |= xfs_inobt_maskn(0, chunkidx); + irbp->ir_startino = r.ir_startino; + irbp->ir_freecount = r.ir_freecount; + irbp->ir_free = r.ir_free; irbp++; - agino = gino + XFS_INODES_PER_CHUNK; - icount = XFS_INODES_PER_CHUNK - gcnt; + agino = r.ir_startino + XFS_INODES_PER_CHUNK; + icount = XFS_INODES_PER_CHUNK - r.ir_freecount; } else { /* * If any of those tests failed, bump the @@ -493,7 +493,7 @@ xfs_bulkstat( /* * Start of ag. Lookup the first inode chunk. */ - error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &tmp); + error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &tmp); icount = 0; } /* @@ -501,6 +501,8 @@ xfs_bulkstat( * until we run out of inodes or space in the buffer. */ while (irbp < irbufend && icount < ubcount) { + xfs_inobt_rec_incore_t r; + /* * Loop as long as we're unable to read the * inode btree. @@ -510,51 +512,55 @@ xfs_bulkstat( if (XFS_AGINO_TO_AGBNO(mp, agino) >= be32_to_cpu(agi->agi_length)) break; - error = xfs_inobt_lookup_ge(cur, agino, 0, 0, - &tmp); + error = xfs_inobt_lookup(cur, agino, + XFS_LOOKUP_GE, &tmp); cond_resched(); } /* * If ran off the end of the ag either with an error, * or the normal way, set end and stop collecting. */ - if (error || - (error = xfs_inobt_get_rec(cur, &gino, &gcnt, - &gfree, &i)) || - i == 0) { + if (error) { end_of_ag = 1; break; } + + error = xfs_inobt_get_rec(cur, &r, &i); + if (error || i == 0) { + end_of_ag = 1; + break; + } + /* * If this chunk has any allocated inodes, save it. * Also start read-ahead now for this chunk. */ - if (gcnt < XFS_INODES_PER_CHUNK) { + if (r.ir_freecount < XFS_INODES_PER_CHUNK) { /* * Loop over all clusters in the next chunk. * Do a readahead if there are any allocated * inodes in that cluster. */ - for (agbno = XFS_AGINO_TO_AGBNO(mp, gino), - chunkidx = 0; + agbno = XFS_AGINO_TO_AGBNO(mp, r.ir_startino); + for (chunkidx = 0; chunkidx < XFS_INODES_PER_CHUNK; chunkidx += nicluster, agbno += nbcluster) { - if (xfs_inobt_maskn(chunkidx, - nicluster) & ~gfree) + if (xfs_inobt_maskn(chunkidx, nicluster) + & ~r.ir_free) xfs_btree_reada_bufs(mp, agno, agbno, nbcluster); } - irbp->ir_startino = gino; - irbp->ir_freecount = gcnt; - irbp->ir_free = gfree; + irbp->ir_startino = r.ir_startino; + irbp->ir_freecount = r.ir_freecount; + irbp->ir_free = r.ir_free; irbp++; - icount += XFS_INODES_PER_CHUNK - gcnt; + icount += XFS_INODES_PER_CHUNK - r.ir_freecount; } /* * Set agino to after this chunk and bump the cursor. */ - agino = gino + XFS_INODES_PER_CHUNK; + agino = r.ir_startino + XFS_INODES_PER_CHUNK; error = xfs_btree_increment(cur, 0, &tmp); cond_resched(); } @@ -820,9 +826,7 @@ xfs_inumbers( int bufidx; xfs_btree_cur_t *cur; int error; - __int32_t gcnt; - xfs_inofree_t gfree; - xfs_agino_t gino; + xfs_inobt_rec_incore_t r; int i; xfs_ino_t ino; int left; @@ -855,7 +859,8 @@ xfs_inumbers( continue; } cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno); - error = xfs_inobt_lookup_ge(cur, agino, 0, 0, &tmp); + error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_GE, + &tmp); if (error) { xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); cur = NULL; @@ -870,9 +875,8 @@ xfs_inumbers( continue; } } - if ((error = xfs_inobt_get_rec(cur, &gino, &gcnt, &gfree, - &i)) || - i == 0) { + error = xfs_inobt_get_rec(cur, &r, &i); + if (error || i == 0) { xfs_buf_relse(agbp); agbp = NULL; xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); @@ -881,10 +885,12 @@ xfs_inumbers( agino = 0; continue; } - agino = gino + XFS_INODES_PER_CHUNK - 1; - buffer[bufidx].xi_startino = XFS_AGINO_TO_INO(mp, agno, gino); - buffer[bufidx].xi_alloccount = XFS_INODES_PER_CHUNK - gcnt; - buffer[bufidx].xi_allocmask = ~gfree; + agino = r.ir_startino + XFS_INODES_PER_CHUNK - 1; + buffer[bufidx].xi_startino = + XFS_AGINO_TO_INO(mp, agno, r.ir_startino); + buffer[bufidx].xi_alloccount = + XFS_INODES_PER_CHUNK - r.ir_freecount; + buffer[bufidx].xi_allocmask = ~r.ir_free; bufidx++; left--; if (bufidx == bcount) { diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h index 1fb04e7deb6..20792bf4594 100644 --- a/fs/xfs/xfs_itable.h +++ b/fs/xfs/xfs_itable.h @@ -99,11 +99,6 @@ xfs_bulkstat_one( void *dibuff, int *stat); -int -xfs_internal_inum( - xfs_mount_t *mp, - xfs_ino_t ino); - typedef int (*inumbers_fmt_pf)( void __user *ubuffer, /* buffer to write to */ const xfs_inogrp_t *buffer, /* buffer to read from */ diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index bcad5f4c1fd..679c7c4926a 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -451,8 +451,6 @@ extern int xlog_find_tail(xlog_t *log, extern int xlog_recover(xlog_t *log); extern int xlog_recover_finish(xlog_t *log); extern void xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int); -extern void xlog_recover_process_iunlinks(xlog_t *log); - extern struct xfs_buf *xlog_get_bp(xlog_t *, int); extern void xlog_put_bp(struct xfs_buf *); diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 47da2fb4537..1099395d7d6 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3263,7 +3263,7 @@ xlog_recover_process_one_iunlink( * freeing of the inode and its removal from the list must be * atomic. */ -void +STATIC void xlog_recover_process_iunlinks( xlog_t *log) { diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 5c6f092659c..8b6c9e807ef 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1568,7 +1568,7 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) * * The m_sb_lock must be held when this routine is called. */ -int +STATIC int xfs_mod_incore_sb_unlocked( xfs_mount_t *mp, xfs_sb_field_t field, diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index a5122382afd..a6c023bc0fb 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -414,13 +414,10 @@ typedef struct xfs_mod_sb { extern int xfs_log_sbcount(xfs_mount_t *, uint); extern int xfs_mountfs(xfs_mount_t *mp); -extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); extern void xfs_unmountfs(xfs_mount_t *); extern int xfs_unmountfs_writesb(xfs_mount_t *); extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int); -extern int xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t, - int64_t, int); extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, uint, int); extern int xfs_mount_log_sb(xfs_mount_t *, __int64_t); diff --git a/fs/xfs/xfs_mru_cache.c b/fs/xfs/xfs_mru_cache.c index afee7eb2432..4b0613d99fa 100644 --- a/fs/xfs/xfs_mru_cache.c +++ b/fs/xfs/xfs_mru_cache.c @@ -564,35 +564,6 @@ xfs_mru_cache_lookup( } /* - * To look up an element using its key, but leave its location in the internal - * lists alone, call xfs_mru_cache_peek(). If the element isn't found, this - * function returns NULL. - * - * See the comments above the declaration of the xfs_mru_cache_lookup() function - * for important locking information pertaining to this call. - */ -void * -xfs_mru_cache_peek( - xfs_mru_cache_t *mru, - unsigned long key) -{ - xfs_mru_cache_elem_t *elem; - - ASSERT(mru && mru->lists); - if (!mru || !mru->lists) - return NULL; - - spin_lock(&mru->lock); - elem = radix_tree_lookup(&mru->store, key); - if (!elem) - spin_unlock(&mru->lock); - else - __release(mru_lock); /* help sparse not be stupid */ - - return elem ? elem->value : NULL; -} - -/* * To release the internal data structure spinlock after having performed an * xfs_mru_cache_lookup() or an xfs_mru_cache_peek(), call xfs_mru_cache_done() * with the data store pointer. diff --git a/fs/xfs/xfs_mru_cache.h b/fs/xfs/xfs_mru_cache.h index dd58ea1bbeb..5d439f34b0c 100644 --- a/fs/xfs/xfs_mru_cache.h +++ b/fs/xfs/xfs_mru_cache.h @@ -49,7 +49,6 @@ int xfs_mru_cache_insert(struct xfs_mru_cache *mru, unsigned long key, void * xfs_mru_cache_remove(struct xfs_mru_cache *mru, unsigned long key); void xfs_mru_cache_delete(struct xfs_mru_cache *mru, unsigned long key); void *xfs_mru_cache_lookup(struct xfs_mru_cache *mru, unsigned long key); -void *xfs_mru_cache_peek(struct xfs_mru_cache *mru, unsigned long key); void xfs_mru_cache_done(struct xfs_mru_cache *mru); #endif /* __XFS_MRU_CACHE_H__ */ diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c index fea68615ed2..3f816ad7ff1 100644 --- a/fs/xfs/xfs_rw.c +++ b/fs/xfs/xfs_rw.c @@ -88,90 +88,6 @@ xfs_write_clear_setuid( } /* - * Handle logging requirements of various synchronous types of write. - */ -int -xfs_write_sync_logforce( - xfs_mount_t *mp, - xfs_inode_t *ip) -{ - int error = 0; - - /* - * If we're treating this as O_DSYNC and we have not updated the - * size, force the log. - */ - if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) && - !(ip->i_update_size)) { - xfs_inode_log_item_t *iip = ip->i_itemp; - - /* - * If an allocation transaction occurred - * without extending the size, then we have to force - * the log up the proper point to ensure that the - * allocation is permanent. We can't count on - * the fact that buffered writes lock out direct I/O - * writes - the direct I/O write could have extended - * the size nontransactionally, then finished before - * we started. xfs_write_file will think that the file - * didn't grow but the update isn't safe unless the - * size change is logged. - * - * Force the log if we've committed a transaction - * against the inode or if someone else has and - * the commit record hasn't gone to disk (e.g. - * the inode is pinned). This guarantees that - * all changes affecting the inode are permanent - * when we return. - */ - if (iip && iip->ili_last_lsn) { - error = _xfs_log_force(mp, iip->ili_last_lsn, - XFS_LOG_FORCE | XFS_LOG_SYNC, NULL); - } else if (xfs_ipincount(ip) > 0) { - error = _xfs_log_force(mp, (xfs_lsn_t)0, - XFS_LOG_FORCE | XFS_LOG_SYNC, NULL); - } - - } else { - xfs_trans_t *tp; - - /* - * O_SYNC or O_DSYNC _with_ a size update are handled - * the same way. - * - * If the write was synchronous then we need to make - * sure that the inode modification time is permanent. - * We'll have updated the timestamp above, so here - * we use a synchronous transaction to log the inode. - * It's not fast, but it's necessary. - * - * If this a dsync write and the size got changed - * non-transactionally, then we need to ensure that - * the size change gets logged in a synchronous - * transaction. - */ - tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC); - if ((error = xfs_trans_reserve(tp, 0, - XFS_SWRITE_LOG_RES(mp), - 0, 0, 0))) { - /* Transaction reserve failed */ - xfs_trans_cancel(tp, 0); - } else { - /* Transaction reserve successful */ - xfs_ilock(ip, XFS_ILOCK_EXCL); - xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_trans_ihold(tp, ip); - xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - xfs_trans_set_sync(tp); - error = xfs_trans_commit(tp, 0); - xfs_iunlock(ip, XFS_ILOCK_EXCL); - } - } - - return error; -} - -/* * Force a shutdown of the filesystem instantly while keeping * the filesystem consistent. We don't do an unmount here; just shutdown * the shop, make sure that absolutely nothing persistent happens to diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h index f76c003ec55..f5e4874c37d 100644 --- a/fs/xfs/xfs_rw.h +++ b/fs/xfs/xfs_rw.h @@ -68,7 +68,6 @@ xfs_get_extsz_hint( * Prototypes for functions in xfs_rw.c. */ extern int xfs_write_clear_setuid(struct xfs_inode *ip); -extern int xfs_write_sync_logforce(struct xfs_mount *mp, struct xfs_inode *ip); extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp); extern int xfs_bioerror(struct xfs_buf *bp); extern int xfs_bioerror_relse(struct xfs_buf *bp); @@ -78,10 +77,4 @@ extern int xfs_read_buf(struct xfs_mount *mp, xfs_buftarg_t *btp, extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp, xfs_buf_t *bp, xfs_daddr_t blkno); -/* - * Prototypes for functions in xfs_vnodeops.c. - */ -extern int xfs_free_eofblocks(struct xfs_mount *mp, struct xfs_inode *ip, - int flags); - #endif /* __XFS_RW_H__ */ diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 775249a54f6..ed47fc77759 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -68,7 +68,7 @@ typedef struct xfs_trans_header { #define XFS_TRANS_GROWFS 14 #define XFS_TRANS_STRAT_WRITE 15 #define XFS_TRANS_DIOSTRAT 16 -#define XFS_TRANS_WRITE_SYNC 17 +/* 17 was XFS_TRANS_WRITE_SYNC */ #define XFS_TRANS_WRITEID 18 #define XFS_TRANS_ADDAFORK 19 #define XFS_TRANS_ATTRINVAL 20 diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index 8ee2f8c8b0a..218829e6a15 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c @@ -307,7 +307,7 @@ xfs_trans_read_buf( return (flags & XFS_BUF_TRYLOCK) ? EAGAIN : XFS_ERROR(ENOMEM); - if ((bp != NULL) && (XFS_BUF_GETERROR(bp) != 0)) { + if (XFS_BUF_GETERROR(bp) != 0) { xfs_ioerror_alert("xfs_trans_read_buf", mp, bp, blkno); error = XFS_BUF_GETERROR(bp); @@ -315,7 +315,7 @@ xfs_trans_read_buf( return error; } #ifdef DEBUG - if (xfs_do_error && (bp != NULL)) { + if (xfs_do_error) { if (xfs_error_target == target) { if (((xfs_req_num++) % xfs_error_mod) == 0) { xfs_buf_relse(bp); diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index 23d276af2e0..785ff101da0 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c @@ -49,30 +49,7 @@ xfs_trans_inode_broot_debug( /* - * Get and lock the inode for the caller if it is not already - * locked within the given transaction. If it is already locked - * within the transaction, just increment its lock recursion count - * and return a pointer to it. - * - * For an inode to be locked in a transaction, the inode lock, as - * opposed to the io lock, must be taken exclusively. This ensures - * that the inode can be involved in only 1 transaction at a time. - * Lock recursion is handled on the io lock, but only for lock modes - * of equal or lesser strength. That is, you can recur on the io lock - * held EXCL with a SHARED request but not vice versa. Also, if - * the inode is already a part of the transaction then you cannot - * go from not holding the io lock to having it EXCL or SHARED. - * - * Use the inode cache routine xfs_inode_incore() to find the inode - * if it is already owned by this transaction. - * - * If we don't already own the inode, use xfs_iget() to get it. - * Since the inode log item structure is embedded in the incore - * inode structure and is initialized when the inode is brought - * into memory, there is nothing to do with it here. - * - * If the given transaction pointer is NULL, just call xfs_iget(). - * This simplifies code which must handle both cases. + * Get an inode and join it to the transaction. */ int xfs_trans_iget( @@ -84,62 +61,11 @@ xfs_trans_iget( xfs_inode_t **ipp) { int error; - xfs_inode_t *ip; - - /* - * If the transaction pointer is NULL, just call the normal - * xfs_iget(). - */ - if (tp == NULL) - return xfs_iget(mp, NULL, ino, flags, lock_flags, ipp, 0); - - /* - * If we find the inode in core with this transaction - * pointer in its i_transp field, then we know we already - * have it locked. In this case we just increment the lock - * recursion count and return the inode to the caller. - * Assert that the inode is already locked in the mode requested - * by the caller. We cannot do lock promotions yet, so - * die if someone gets this wrong. - */ - if ((ip = xfs_inode_incore(tp->t_mountp, ino, tp)) != NULL) { - /* - * Make sure that the inode lock is held EXCL and - * that the io lock is never upgraded when the inode - * is already a part of the transaction. - */ - ASSERT(ip->i_itemp != NULL); - ASSERT(lock_flags & XFS_ILOCK_EXCL); - ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) || - xfs_isilocked(ip, XFS_IOLOCK_EXCL)); - ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) || - (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_EXCL)); - ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) || - xfs_isilocked(ip, XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)); - ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) || - (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_ANY)); - - if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) { - ip->i_itemp->ili_iolock_recur++; - } - if (lock_flags & XFS_ILOCK_EXCL) { - ip->i_itemp->ili_ilock_recur++; - } - *ipp = ip; - return 0; - } - - ASSERT(lock_flags & XFS_ILOCK_EXCL); - error = xfs_iget(tp->t_mountp, tp, ino, flags, lock_flags, &ip, 0); - if (error) { - return error; - } - ASSERT(ip != NULL); - xfs_trans_ijoin(tp, ip, lock_flags); - *ipp = ip; - return 0; + error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp, 0); + if (!error && tp) + xfs_trans_ijoin(tp, *ipp, lock_flags); + return error; } /* @@ -163,8 +89,6 @@ xfs_trans_ijoin( xfs_inode_item_init(ip, ip->i_mount); iip = ip->i_itemp; ASSERT(iip->ili_flags == 0); - ASSERT(iip->ili_ilock_recur == 0); - ASSERT(iip->ili_iolock_recur == 0); /* * Get a log_item_desc to point at the new item. diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 492d75bae2b..a434f287962 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -611,7 +611,7 @@ xfs_fsync( xfs_inode_t *ip) { xfs_trans_t *tp; - int error; + int error = 0; int log_flushed = 0, changed = 1; xfs_itrace_entry(ip); @@ -619,14 +619,9 @@ xfs_fsync( if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return XFS_ERROR(EIO); - /* capture size updates in I/O completion before writing the inode. */ - error = xfs_wait_on_pages(ip, 0, -1); - if (error) - return XFS_ERROR(error); - /* * We always need to make sure that the required inode state is safe on - * disk. The vnode might be clean but we still might need to force the + * disk. The inode might be clean but we still might need to force the * log because of committed transactions that haven't hit the disk yet. * Likewise, there could be unflushed non-transactional changes to the * inode core that have to go to disk and this requires us to issue @@ -638,7 +633,7 @@ xfs_fsync( */ xfs_ilock(ip, XFS_ILOCK_SHARED); - if (!(ip->i_update_size || ip->i_update_core)) { + if (!ip->i_update_core) { /* * Timestamps/size haven't changed since last inode flush or * inode transaction commit. That means either nothing got @@ -718,7 +713,7 @@ xfs_fsync( * when the link count isn't zero and by xfs_dm_punch_hole() when * punching a hole to EOF. */ -int +STATIC int xfs_free_eofblocks( xfs_mount_t *mp, xfs_inode_t *ip, @@ -1476,8 +1471,8 @@ xfs_create( if (error == ENOSPC) { /* flush outstanding delalloc blocks and retry */ xfs_flush_inodes(dp); - error = xfs_trans_reserve(tp, resblks, XFS_CREATE_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT); + error = xfs_trans_reserve(tp, resblks, log_res, 0, + XFS_TRANS_PERM_LOG_RES, log_count); } if (error == ENOSPC) { /* No space at all so try a "no-allocation" reservation */ diff --git a/include/keys/rxrpc-type.h b/include/keys/rxrpc-type.h index 7609365577f..5cb86c307f5 100644 --- a/include/keys/rxrpc-type.h +++ b/include/keys/rxrpc-type.h @@ -21,4 +21,111 @@ extern struct key_type key_type_rxrpc; extern struct key *rxrpc_get_null_key(const char *); +/* + * RxRPC key for Kerberos IV (type-2 security) + */ +struct rxkad_key { + u32 vice_id; + u32 start; /* time at which ticket starts */ + u32 expiry; /* time at which ticket expires */ + u32 kvno; /* key version number */ + u8 primary_flag; /* T if key for primary cell for this user */ + u16 ticket_len; /* length of ticket[] */ + u8 session_key[8]; /* DES session key */ + u8 ticket[0]; /* the encrypted ticket */ +}; + +/* + * Kerberos 5 principal + * name/name/name@realm + */ +struct krb5_principal { + u8 n_name_parts; /* N of parts of the name part of the principal */ + char **name_parts; /* parts of the name part of the principal */ + char *realm; /* parts of the realm part of the principal */ +}; + +/* + * Kerberos 5 tagged data + */ +struct krb5_tagged_data { + /* for tag value, see /usr/include/krb5/krb5.h + * - KRB5_AUTHDATA_* for auth data + * - + */ + s32 tag; + u32 data_len; + u8 *data; +}; + +/* + * RxRPC key for Kerberos V (type-5 security) + */ +struct rxk5_key { + u64 authtime; /* time at which auth token generated */ + u64 starttime; /* time at which auth token starts */ + u64 endtime; /* time at which auth token expired */ + u64 renew_till; /* time to which auth token can be renewed */ + s32 is_skey; /* T if ticket is encrypted in another ticket's + * skey */ + s32 flags; /* mask of TKT_FLG_* bits (krb5/krb5.h) */ + struct krb5_principal client; /* client principal name */ + struct krb5_principal server; /* server principal name */ + u16 ticket_len; /* length of ticket */ + u16 ticket2_len; /* length of second ticket */ + u8 n_authdata; /* number of authorisation data elements */ + u8 n_addresses; /* number of addresses */ + struct krb5_tagged_data session; /* session data; tag is enctype */ + struct krb5_tagged_data *addresses; /* addresses */ + u8 *ticket; /* krb5 ticket */ + u8 *ticket2; /* second krb5 ticket, if related to ticket (via + * DUPLICATE-SKEY or ENC-TKT-IN-SKEY) */ + struct krb5_tagged_data *authdata; /* authorisation data */ +}; + +/* + * list of tokens attached to an rxrpc key + */ +struct rxrpc_key_token { + u16 security_index; /* RxRPC header security index */ + struct rxrpc_key_token *next; /* the next token in the list */ + union { + struct rxkad_key *kad; + struct rxk5_key *k5; + }; +}; + +/* + * structure of raw payloads passed to add_key() or instantiate key + */ +struct rxrpc_key_data_v1 { + u32 kif_version; /* 1 */ + u16 security_index; + u16 ticket_length; + u32 expiry; /* time_t */ + u32 kvno; + u8 session_key[8]; + u8 ticket[0]; +}; + +/* + * AF_RXRPC key payload derived from XDR format + * - based on openafs-1.4.10/src/auth/afs_token.xg + */ +#define AFSTOKEN_LENGTH_MAX 16384 /* max payload size */ +#define AFSTOKEN_STRING_MAX 256 /* max small string length */ +#define AFSTOKEN_DATA_MAX 64 /* max small data length */ +#define AFSTOKEN_CELL_MAX 64 /* max cellname length */ +#define AFSTOKEN_MAX 8 /* max tokens per payload */ +#define AFSTOKEN_BDATALN_MAX 16384 /* max big data length */ +#define AFSTOKEN_RK_TIX_MAX 12000 /* max RxKAD ticket size */ +#define AFSTOKEN_GK_KEY_MAX 64 /* max GSSAPI key size */ +#define AFSTOKEN_GK_TOKEN_MAX 16384 /* max GSSAPI token size */ +#define AFSTOKEN_K5_COMPONENTS_MAX 16 /* max K5 components */ +#define AFSTOKEN_K5_NAME_MAX 128 /* max K5 name length */ +#define AFSTOKEN_K5_REALM_MAX 64 /* max K5 realm name length */ +#define AFSTOKEN_K5_TIX_MAX 16384 /* max K5 ticket size */ +#define AFSTOKEN_K5_ADDRESSES_MAX 16 /* max K5 addresses */ +#define AFSTOKEN_K5_AUTHDATA_MAX 16 /* max K5 pieces of auth data */ + #endif /* _KEYS_RXRPC_TYPE_H */ diff --git a/include/linux/igmp.h b/include/linux/igmp.h index 92fbd8cbd68..fe158e0e20e 100644 --- a/include/linux/igmp.h +++ b/include/linux/igmp.h @@ -233,6 +233,8 @@ extern void ip_mc_init_dev(struct in_device *); extern void ip_mc_destroy_dev(struct in_device *); extern void ip_mc_up(struct in_device *); extern void ip_mc_down(struct in_device *); +extern void ip_mc_unmap(struct in_device *); +extern void ip_mc_remap(struct in_device *); extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr); extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr); extern void ip_mc_rejoin_group(struct ip_mc_list *im); diff --git a/include/linux/net.h b/include/linux/net.h index 4fc2ffd527f..9040a10584f 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -57,6 +57,7 @@ typedef enum { #include <linux/random.h> #include <linux/wait.h> #include <linux/fcntl.h> /* For O_CLOEXEC and O_NONBLOCK */ +#include <linux/kmemcheck.h> struct poll_table_struct; struct pipe_inode_info; @@ -127,7 +128,11 @@ enum sock_shutdown_cmd { */ struct socket { socket_state state; + + kmemcheck_bitfield_begin(type); short type; + kmemcheck_bitfield_end(type); + unsigned long flags; /* * Please keep fasync_list & wait fields in the same cache line diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a9aa4b5917d..94958c10976 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1873,7 +1873,8 @@ extern void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, struct extern int dev_set_promiscuity(struct net_device *dev, int inc); extern int dev_set_allmulti(struct net_device *dev, int inc); extern void netdev_state_change(struct net_device *dev); -extern void netdev_bonding_change(struct net_device *dev); +extern void netdev_bonding_change(struct net_device *dev, + unsigned long event); extern void netdev_features_change(struct net_device *dev); /* Load a device via the kmod */ extern void dev_load(struct net *net, const char *name); diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 0fbecbbe8e9..080f6ba9e73 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -176,12 +176,16 @@ struct netlink_skb_parms #define NETLINK_CREDS(skb) (&NETLINK_CB((skb)).creds) +extern void netlink_table_grab(void); +extern void netlink_table_ungrab(void); + extern struct sock *netlink_kernel_create(struct net *net, int unit,unsigned int groups, void (*input)(struct sk_buff *skb), struct mutex *cb_mutex, struct module *module); extern void netlink_kernel_release(struct sock *sk); +extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups); extern int netlink_change_ngroups(struct sock *sk, unsigned int groups); extern void netlink_clear_multicast_users(struct sock *sk, unsigned int group); extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err); diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 81bc252dc8a..44428d247db 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -199,6 +199,8 @@ static inline int notifier_to_errno(int ret) #define NETDEV_FEAT_CHANGE 0x000B #define NETDEV_BONDING_FAILOVER 0x000C #define NETDEV_PRE_UP 0x000D +#define NETDEV_BONDING_OLDTYPE 0x000E +#define NETDEV_BONDING_NEWTYPE 0x000F #define SYS_DOWN 0x0001 /* Notify of system down */ #define SYS_RESTART SYS_DOWN diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 8975add8668..3b6b788fe2b 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1529,6 +1529,8 @@ #define PCI_DEVICE_ID_ARTOP_ATP860R 0x0007 #define PCI_DEVICE_ID_ARTOP_ATP865 0x0008 #define PCI_DEVICE_ID_ARTOP_ATP865R 0x0009 +#define PCI_DEVICE_ID_ARTOP_ATP867A 0x000A +#define PCI_DEVICE_ID_ARTOP_ATP867B 0x000B #define PCI_DEVICE_ID_ARTOP_AEC7610 0x8002 #define PCI_DEVICE_ID_ARTOP_AEC7612UW 0x8010 #define PCI_DEVICE_ID_ARTOP_AEC7612U 0x8020 diff --git a/include/linux/rxrpc.h b/include/linux/rxrpc.h index f7b826b565c..a53915cd558 100644 --- a/include/linux/rxrpc.h +++ b/include/linux/rxrpc.h @@ -58,5 +58,12 @@ struct sockaddr_rxrpc { #define RXRPC_SECURITY_AUTH 1 /* authenticated packets */ #define RXRPC_SECURITY_ENCRYPT 2 /* encrypted packets */ +/* + * RxRPC security indices + */ +#define RXRPC_SECURITY_NONE 0 /* no security protocol */ +#define RXRPC_SECURITY_RXKAD 2 /* kaserver or kerberos 4 */ +#define RXRPC_SECURITY_RXGK 4 /* gssapi-based */ +#define RXRPC_SECURITY_RXK5 5 /* kerberos 5 */ #endif /* _LINUX_RXRPC_H */ diff --git a/include/linux/uwb.h b/include/linux/uwb.h index c02128991ff..7fc9746f22c 100644 --- a/include/linux/uwb.h +++ b/include/linux/uwb.h @@ -597,7 +597,7 @@ void uwb_rc_neh_grok(struct uwb_rc *, void *, size_t); void uwb_rc_neh_error(struct uwb_rc *, int); void uwb_rc_reset_all(struct uwb_rc *rc); void uwb_rc_pre_reset(struct uwb_rc *rc); -void uwb_rc_post_reset(struct uwb_rc *rc); +int uwb_rc_post_reset(struct uwb_rc *rc); /** * uwb_rsv_is_owner - is the owner of this reservation the RC? diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 7b55ab215a6..0f7c37825fc 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -143,6 +143,8 @@ extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr extern int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr); extern void ipv6_mc_up(struct inet6_dev *idev); extern void ipv6_mc_down(struct inet6_dev *idev); +extern void ipv6_mc_unmap(struct inet6_dev *idev); +extern void ipv6_mc_remap(struct inet6_dev *idev); extern void ipv6_mc_init_dev(struct inet6_dev *idev); extern void ipv6_mc_destroy_dev(struct inet6_dev *idev); extern void addrconf_dad_failure(struct inet6_ifaddr *ifp); diff --git a/include/net/protocol.h b/include/net/protocol.h index 1089d5aabd4..60249e51b66 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -94,21 +94,20 @@ struct inet_protosw { #define INET_PROTOSW_PERMANENT 0x02 /* Permanent protocols are unremovable. */ #define INET_PROTOSW_ICSK 0x04 /* Is this an inet_connection_sock? */ -extern struct net_protocol *inet_protocol_base; -extern struct net_protocol *inet_protos[MAX_INET_PROTOS]; +extern const struct net_protocol *inet_protos[MAX_INET_PROTOS]; #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) -extern struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; +extern const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; #endif -extern int inet_add_protocol(struct net_protocol *prot, unsigned char num); -extern int inet_del_protocol(struct net_protocol *prot, unsigned char num); +extern int inet_add_protocol(const struct net_protocol *prot, unsigned char num); +extern int inet_del_protocol(const struct net_protocol *prot, unsigned char num); extern void inet_register_protosw(struct inet_protosw *p); extern void inet_unregister_protosw(struct inet_protosw *p); #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) -extern int inet6_add_protocol(struct inet6_protocol *prot, unsigned char num); -extern int inet6_del_protocol(struct inet6_protocol *prot, unsigned char num); +extern int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char num); +extern int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char num); extern int inet6_register_protosw(struct inet_protosw *p); extern void inet6_unregister_protosw(struct inet_protosw *p); #endif diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 88eb9de095d..c33180dd42b 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -81,7 +81,7 @@ struct Qdisc struct Qdisc_class_ops { /* Child qdisc manipulation */ - unsigned int (*select_queue)(struct Qdisc *, struct tcmsg *); + struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *); int (*graft)(struct Qdisc *, unsigned long cl, struct Qdisc *, struct Qdisc **); struct Qdisc * (*leaf)(struct Qdisc *, unsigned long cl); diff --git a/include/net/tcp.h b/include/net/tcp.h index b71a446d58f..56b76027b85 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -793,6 +793,13 @@ static inline unsigned int tcp_packets_in_flight(const struct tcp_sock *tp) return tp->packets_out - tcp_left_out(tp) + tp->retrans_out; } +#define TCP_INFINITE_SSTHRESH 0x7fffffff + +static inline bool tcp_in_initial_slowstart(const struct tcp_sock *tp) +{ + return tp->snd_ssthresh >= TCP_INFINITE_SSTHRESH; +} + /* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd. * The exception is rate halving phase, when cwnd is decreasing towards * ssthresh. diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 4a6ff2ba4d0..b1a4290996b 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -1372,7 +1372,7 @@ static int atalk_route_packet(struct sk_buff *skb, struct net_device *dev, if (aarp_send_ddp(rt->dev, skb, &ta, NULL) == NET_XMIT_DROP) return NET_RX_DROP; - return NET_XMIT_SUCCESS; + return NET_RX_SUCCESS; free_it: kfree_skb(skb); drop: diff --git a/net/can/af_can.c b/net/can/af_can.c index ef1c43a2ed5..60683211567 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -199,6 +199,8 @@ static int can_create(struct net *net, struct socket *sock, int protocol) * @skb: pointer to socket buffer with CAN frame in data section * @loop: loopback for listeners on local CAN sockets (recommended default!) * + * Due to the loopback this routine must not be called from hardirq context. + * * Return: * 0 on success * -ENETDOWN when the selected interface is down @@ -278,7 +280,7 @@ int can_send(struct sk_buff *skb, int loop) } if (newskb) - netif_rx(newskb); + netif_rx_ni(newskb); /* update statistics */ can_stats.tx_frames++; diff --git a/net/core/dev.c b/net/core/dev.c index 84945470ab3..560c8c9c03a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1017,9 +1017,9 @@ void netdev_state_change(struct net_device *dev) } EXPORT_SYMBOL(netdev_state_change); -void netdev_bonding_change(struct net_device *dev) +void netdev_bonding_change(struct net_device *dev, unsigned long event) { - call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, dev); + call_netdevice_notifiers(event, dev); } EXPORT_SYMBOL(netdev_bonding_change); diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig index 4b5db44970a..8408398cd44 100644 --- a/net/dccp/ccids/Kconfig +++ b/net/dccp/ccids/Kconfig @@ -66,9 +66,9 @@ config IP_DCCP_CCID3_RTO A value of 0 disables this feature by enforcing the value specified in RFC 3448. The following values have been suggested as bounds for experimental use: - * 16-20ms to match the typical multimedia inter-frame interval - * 100ms as a reasonable compromise [default] - * 1000ms corresponds to the lower TCP RTO bound (RFC 2988, 2.4) + * 16-20ms to match the typical multimedia inter-frame interval + * 100ms as a reasonable compromise [default] + * 1000ms corresponds to the lower TCP RTO bound (RFC 2988, 2.4) The default of 100ms is a compromise between a large value for efficient DCCP implementations, and a small value to avoid disrupting diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index d235294ace2..e8cf99e880b 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -1,6 +1,4 @@ /* - * net/dccp/ccids/ccid2.c - * * Copyright (c) 2005, 2006 Andrea Bittau <a.bittau@cs.ucl.ac.uk> * * Changes to meet Linux coding standards, and DCCP infrastructure fixes. diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h index 2c94ca02901..326ac90fb90 100644 --- a/net/dccp/ccids/ccid2.h +++ b/net/dccp/ccids/ccid2.h @@ -1,6 +1,4 @@ /* - * net/dccp/ccids/ccid2.h - * * Copyright (c) 2005 Andrea Bittau <a.bittau@cs.ucl.ac.uk> * * This program is free software; you can redistribute it and/or modify @@ -40,14 +38,14 @@ struct ccid2_seq { #define CCID2_SEQBUF_LEN 1024 #define CCID2_SEQBUF_MAX 128 -/** struct ccid2_hc_tx_sock - CCID2 TX half connection - * +/** + * struct ccid2_hc_tx_sock - CCID2 TX half connection * @ccid2hctx_{cwnd,ssthresh,pipe}: as per RFC 4341, section 5 * @ccid2hctx_packets_acked - Ack counter for deriving cwnd growth (RFC 3465) * @ccid2hctx_lastrtt -time RTT was last measured * @ccid2hctx_rpseq - last consecutive seqno * @ccid2hctx_rpdupack - dupacks since rpseq -*/ + */ struct ccid2_hc_tx_sock { u32 ccid2hctx_cwnd; u32 ccid2hctx_ssthresh; diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index f596ce149c3..34dcc798c45 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -1,6 +1,4 @@ /* - * net/dccp/ccids/ccid3.c - * * Copyright (c) 2007 The University of Aberdeen, Scotland, UK * Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand. * Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz> @@ -750,7 +748,8 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) return 0; } -/** ccid3_first_li - Implements [RFC 3448, 6.3.1] +/** + * ccid3_first_li - Implements [RFC 5348, 6.3.1] * * Determine the length of the first loss interval via inverse lookup. * Assume that X_recv can be computed by the throughput equation diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h index 49ca32bd7e7..e5a24414384 100644 --- a/net/dccp/ccids/ccid3.h +++ b/net/dccp/ccids/ccid3.h @@ -1,6 +1,4 @@ /* - * net/dccp/ccids/ccid3.h - * * Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand. * Copyright (c) 2007 The University of Aberdeen, Scotland, UK * @@ -75,8 +73,8 @@ enum ccid3_hc_tx_states { TFRC_SSTATE_TERM, }; -/** struct ccid3_hc_tx_sock - CCID3 sender half-connection socket - * +/** + * struct ccid3_hc_tx_sock - CCID3 sender half-connection socket * @ccid3hctx_x - Current sending rate in 64 * bytes per second * @ccid3hctx_x_recv - Receive rate in 64 * bytes per second * @ccid3hctx_x_calc - Calculated rate in bytes per second @@ -119,9 +117,9 @@ struct ccid3_hc_tx_sock { static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk) { - struct ccid3_hc_tx_sock *hctx = ccid_priv(dccp_sk(sk)->dccps_hc_tx_ccid); - BUG_ON(hctx == NULL); - return hctx; + struct ccid3_hc_tx_sock *hctx = ccid_priv(dccp_sk(sk)->dccps_hc_tx_ccid); + BUG_ON(hctx == NULL); + return hctx; } /* TFRC receiver states */ @@ -131,22 +129,22 @@ enum ccid3_hc_rx_states { TFRC_RSTATE_TERM = 127, }; -/** struct ccid3_hc_rx_sock - CCID3 receiver half-connection socket - * - * @ccid3hcrx_x_recv - Receiver estimate of send rate (RFC 3448 4.3) - * @ccid3hcrx_rtt - Receiver estimate of rtt (non-standard) - * @ccid3hcrx_p - Current loss event rate (RFC 3448 5.4) - * @ccid3hcrx_last_counter - Tracks window counter (RFC 4342, 8.1) - * @ccid3hcrx_state - Receiver state, one of %ccid3_hc_rx_states - * @ccid3hcrx_bytes_recv - Total sum of DCCP payload bytes - * @ccid3hcrx_x_recv - Receiver estimate of send rate (RFC 3448, sec. 4.3) - * @ccid3hcrx_rtt - Receiver estimate of RTT - * @ccid3hcrx_tstamp_last_feedback - Time at which last feedback was sent - * @ccid3hcrx_tstamp_last_ack - Time at which last feedback was sent - * @ccid3hcrx_hist - Packet history (loss detection + RTT sampling) - * @ccid3hcrx_li_hist - Loss Interval database - * @ccid3hcrx_s - Received packet size in bytes - * @ccid3hcrx_pinv - Inverse of Loss Event Rate (RFC 4342, sec. 8.5) +/** + * struct ccid3_hc_rx_sock - CCID3 receiver half-connection socket + * @ccid3hcrx_x_recv - Receiver estimate of send rate (RFC 3448 4.3) + * @ccid3hcrx_rtt - Receiver estimate of rtt (non-standard) + * @ccid3hcrx_p - Current loss event rate (RFC 3448 5.4) + * @ccid3hcrx_last_counter - Tracks window counter (RFC 4342, 8.1) + * @ccid3hcrx_state - Receiver state, one of %ccid3_hc_rx_states + * @ccid3hcrx_bytes_recv - Total sum of DCCP payload bytes + * @ccid3hcrx_x_recv - Receiver estimate of send rate (RFC 3448, sec. 4.3) + * @ccid3hcrx_rtt - Receiver estimate of RTT + * @ccid3hcrx_tstamp_last_feedback - Time at which last feedback was sent + * @ccid3hcrx_tstamp_last_ack - Time at which last feedback was sent + * @ccid3hcrx_hist - Packet history (loss detection + RTT sampling) + * @ccid3hcrx_li_hist - Loss Interval database + * @ccid3hcrx_s - Received packet size in bytes + * @ccid3hcrx_pinv - Inverse of Loss Event Rate (RFC 4342, sec. 8.5) */ struct ccid3_hc_rx_sock { u8 ccid3hcrx_last_counter:4; @@ -163,9 +161,9 @@ struct ccid3_hc_rx_sock { static inline struct ccid3_hc_rx_sock *ccid3_hc_rx_sk(const struct sock *sk) { - struct ccid3_hc_rx_sock *hcrx = ccid_priv(dccp_sk(sk)->dccps_hc_rx_ccid); - BUG_ON(hcrx == NULL); - return hcrx; + struct ccid3_hc_rx_sock *hcrx = ccid_priv(dccp_sk(sk)->dccps_hc_rx_ccid); + BUG_ON(hcrx == NULL); + return hcrx; } #endif /* _DCCP_CCID3_H_ */ diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c index 4d1e4012726..8fc3cbf7907 100644 --- a/net/dccp/ccids/lib/loss_interval.c +++ b/net/dccp/ccids/lib/loss_interval.c @@ -1,6 +1,4 @@ /* - * net/dccp/ccids/lib/loss_interval.c - * * Copyright (c) 2007 The University of Aberdeen, Scotland, UK * Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand. * Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz> @@ -21,7 +19,7 @@ static const int tfrc_lh_weights[NINTERVAL] = { 10, 10, 10, 10, 8, 6, 4, 2 }; /* implements LIFO semantics on the array */ static inline u8 LIH_INDEX(const u8 ctr) { - return (LIH_SIZE - 1 - (ctr % LIH_SIZE)); + return LIH_SIZE - 1 - (ctr % LIH_SIZE); } /* the `counter' index always points at the next entry to be populated */ @@ -129,7 +127,8 @@ static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur, (cur->li_is_closed || SUB16(new_loss->tfrchrx_ccval, cur->li_ccval) > 4); } -/** tfrc_lh_interval_add - Insert new record into the Loss Interval database +/** + * tfrc_lh_interval_add - Insert new record into the Loss Interval database * @lh: Loss Interval database * @rh: Receive history containing a fresh loss event * @calc_first_li: Caller-dependent routine to compute length of first interval diff --git a/net/dccp/ccids/lib/loss_interval.h b/net/dccp/ccids/lib/loss_interval.h index 246018a3b26..d1d2f5383b7 100644 --- a/net/dccp/ccids/lib/loss_interval.h +++ b/net/dccp/ccids/lib/loss_interval.h @@ -1,8 +1,6 @@ #ifndef _DCCP_LI_HIST_ #define _DCCP_LI_HIST_ /* - * net/dccp/ccids/lib/loss_interval.h - * * Copyright (c) 2007 The University of Aberdeen, Scotland, UK * Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand. * Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz> diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c index b7785b3581e..3a4f414e94a 100644 --- a/net/dccp/ccids/lib/packet_history.c +++ b/net/dccp/ccids/lib/packet_history.c @@ -1,6 +1,4 @@ /* - * net/dccp/packet_history.c - * * Copyright (c) 2007 The University of Aberdeen, Scotland, UK * Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand. * @@ -128,7 +126,7 @@ u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, const u64 seqno, /* - * Receiver History Routines + * Receiver History Routines */ static struct kmem_cache *tfrc_rx_hist_slab; diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h index 461cc91cce8..7df6c529999 100644 --- a/net/dccp/ccids/lib/packet_history.h +++ b/net/dccp/ccids/lib/packet_history.h @@ -70,7 +70,6 @@ struct tfrc_rx_hist_entry { /** * tfrc_rx_hist - RX history structure for TFRC-based protocols - * * @ring: Packet history for RTT sampling and loss detection * @loss_count: Number of entries in circular history * @loss_start: Movable index (for loss detection) diff --git a/net/dccp/ccids/lib/tfrc.h b/net/dccp/ccids/lib/tfrc.h index e9720b14327..01bb48e96c2 100644 --- a/net/dccp/ccids/lib/tfrc.h +++ b/net/dccp/ccids/lib/tfrc.h @@ -1,8 +1,6 @@ #ifndef _TFRC_H_ #define _TFRC_H_ /* - * net/dccp/ccids/lib/tfrc.h - * * Copyright (c) 2007 The University of Aberdeen, Scotland, UK * Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand. * Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz> @@ -32,7 +30,7 @@ extern int tfrc_debug; /* integer-arithmetic divisions of type (a * 1000000)/b */ static inline u64 scaled_div(u64 a, u64 b) { - BUG_ON(b==0); + BUG_ON(b == 0); return div64_u64(a * 1000000, b); } diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c index c5d3a9e5a5a..22ca1cf0eb5 100644 --- a/net/dccp/ccids/lib/tfrc_equation.c +++ b/net/dccp/ccids/lib/tfrc_equation.c @@ -1,6 +1,4 @@ /* - * net/dccp/ccids/lib/tfrc_equation.c - * * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. * Copyright (c) 2005 Ian McDonald <ian.mcdonald@jandi.co.nz> * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br> @@ -79,10 +77,10 @@ } With the given configuration, we have, with M = TFRC_CALC_X_ARRSIZE-1, - lookup[0][0] = g(1000000/(M+1)) = 1000000 * f(0.2%) - lookup[M][0] = g(1000000) = 1000000 * f(100%) - lookup[0][1] = g(TFRC_SMALLEST_P) = 1000000 * f(0.01%) - lookup[M][1] = g(TFRC_CALC_X_SPLIT) = 1000000 * f(5%) + lookup[0][0] = g(1000000/(M+1)) = 1000000 * f(0.2%) + lookup[M][0] = g(1000000) = 1000000 * f(100%) + lookup[0][1] = g(TFRC_SMALLEST_P) = 1000000 * f(0.01%) + lookup[M][1] = g(TFRC_CALC_X_SPLIT) = 1000000 * f(5%) In summary, the two columns represent f(p) for the following ranges: * The first column is for 0.002 <= p <= 1.0 @@ -610,11 +608,10 @@ static inline u32 tfrc_binsearch(u32 fval, u8 small) /** * tfrc_calc_x - Calculate the send rate as per section 3.1 of RFC3448 - * - * @s: packet size in bytes - * @R: RTT scaled by 1000000 (i.e., microseconds) - * @p: loss ratio estimate scaled by 1000000 - * Returns X_calc in bytes per second (not scaled). + * @s: packet size in bytes + * @R: RTT scaled by 1000000 (i.e., microseconds) + * @p: loss ratio estimate scaled by 1000000 + * Returns X_calc in bytes per second (not scaled). */ u32 tfrc_calc_x(u16 s, u32 R, u32 p) { @@ -630,17 +627,17 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p) return ~0U; } - if (p <= TFRC_CALC_X_SPLIT) { /* 0.0000 < p <= 0.05 */ + if (p <= TFRC_CALC_X_SPLIT) { /* 0.0000 < p <= 0.05 */ if (p < TFRC_SMALLEST_P) { /* 0.0000 < p < 0.0001 */ DCCP_WARN("Value of p (%d) below resolution. " "Substituting %d\n", p, TFRC_SMALLEST_P); index = 0; - } else /* 0.0001 <= p <= 0.05 */ + } else /* 0.0001 <= p <= 0.05 */ index = p/TFRC_SMALLEST_P - 1; f = tfrc_calc_x_lookup[index][1]; - } else { /* 0.05 < p <= 1.00 */ + } else { /* 0.05 < p <= 1.00 */ index = p/(1000000/TFRC_CALC_X_ARRSIZE) - 1; f = tfrc_calc_x_lookup[index][0]; @@ -661,7 +658,6 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p) /** * tfrc_calc_x_reverse_lookup - try to find p given f(p) - * * @fvalue: function value to match, scaled by 1000000 * Returns closest match for p, also scaled by 1000000 */ diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index d01c00de1ad..7302e1498d4 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -948,7 +948,7 @@ static struct proto dccp_v4_prot = { #endif }; -static struct net_protocol dccp_v4_protocol = { +static const struct net_protocol dccp_v4_protocol = { .handler = dccp_v4_rcv, .err_handler = dccp_v4_err, .no_policy = 1, diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 64f011cc449..e48ca5d4565 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -1152,13 +1152,13 @@ static struct proto dccp_v6_prot = { #endif }; -static struct inet6_protocol dccp_v6_protocol = { +static const struct inet6_protocol dccp_v6_protocol = { .handler = dccp_v6_rcv, .err_handler = dccp_v6_err, .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL, }; -static struct proto_ops inet6_dccp_ops = { +static const struct proto_ops inet6_dccp_ops = { .family = PF_INET6, .owner = THIS_MODULE, .release = inet6_release, diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index 77ae6852b93..51593a48f2d 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c @@ -414,7 +414,7 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname, } static int dgram_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int __user optlen) + char __user *optval, int optlen) { struct dgram_sock *ro = dgram_sk(sk); int val; diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c index 2106ecbf030..ca767bde17a 100644 --- a/net/ieee802154/netlink.c +++ b/net/ieee802154/netlink.c @@ -35,6 +35,7 @@ #include <net/ieee802154_netdev.h> static unsigned int ieee802154_seq_num; +static DEFINE_SPINLOCK(ieee802154_seq_lock); static struct genl_family ieee802154_coordinator_family = { .id = GENL_ID_GENERATE, @@ -57,12 +58,15 @@ static struct sk_buff *ieee802154_nl_create(int flags, u8 req) { void *hdr; struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); + unsigned long f; if (!msg) return NULL; + spin_lock_irqsave(&ieee802154_seq_lock, f); hdr = genlmsg_put(msg, 0, ieee802154_seq_num++, &ieee802154_coordinator_family, flags, req); + spin_unlock_irqrestore(&ieee802154_seq_lock, f); if (!hdr) { nlmsg_free(msg); return NULL; diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c index 4681501aae9..13198859982 100644 --- a/net/ieee802154/raw.c +++ b/net/ieee802154/raw.c @@ -244,7 +244,7 @@ static int raw_getsockopt(struct sock *sk, int level, int optname, } static int raw_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int __user optlen) + char __user *optval, int optlen) { return -EOPNOTSUPP; } diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 6c30a73f03f..58c4b0f7c4a 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -244,7 +244,7 @@ EXPORT_SYMBOL(build_ehash_secret); static inline int inet_netns_ok(struct net *net, int protocol) { int hash; - struct net_protocol *ipprot; + const struct net_protocol *ipprot; if (net_eq(net, &init_net)) return 1; @@ -1162,7 +1162,7 @@ EXPORT_SYMBOL(inet_sk_rebuild_header); static int inet_gso_send_check(struct sk_buff *skb) { struct iphdr *iph; - struct net_protocol *ops; + const struct net_protocol *ops; int proto; int ihl; int err = -EINVAL; @@ -1198,7 +1198,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) { struct sk_buff *segs = ERR_PTR(-EINVAL); struct iphdr *iph; - struct net_protocol *ops; + const struct net_protocol *ops; int proto; int ihl; int id; @@ -1265,7 +1265,7 @@ out: static struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb) { - struct net_protocol *ops; + const struct net_protocol *ops; struct sk_buff **pp = NULL; struct sk_buff *p; struct iphdr *iph; @@ -1342,7 +1342,7 @@ out: static int inet_gro_complete(struct sk_buff *skb) { - struct net_protocol *ops; + const struct net_protocol *ops; struct iphdr *iph = ip_hdr(skb); int proto = iph->protocol & (MAX_INET_PROTOS - 1); int err = -ENOSYS; @@ -1427,13 +1427,13 @@ void snmp_mib_free(void *ptr[2]) EXPORT_SYMBOL_GPL(snmp_mib_free); #ifdef CONFIG_IP_MULTICAST -static struct net_protocol igmp_protocol = { +static const struct net_protocol igmp_protocol = { .handler = igmp_rcv, .netns_ok = 1, }; #endif -static struct net_protocol tcp_protocol = { +static const struct net_protocol tcp_protocol = { .handler = tcp_v4_rcv, .err_handler = tcp_v4_err, .gso_send_check = tcp_v4_gso_send_check, @@ -1444,7 +1444,7 @@ static struct net_protocol tcp_protocol = { .netns_ok = 1, }; -static struct net_protocol udp_protocol = { +static const struct net_protocol udp_protocol = { .handler = udp_rcv, .err_handler = udp_err, .gso_send_check = udp4_ufo_send_check, @@ -1453,7 +1453,7 @@ static struct net_protocol udp_protocol = { .netns_ok = 1, }; -static struct net_protocol icmp_protocol = { +static const struct net_protocol icmp_protocol = { .handler = icmp_rcv, .no_policy = 1, .netns_ok = 1, diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index e878e494296..5c662703eb1 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c @@ -311,7 +311,7 @@ static const struct xfrm_type ah_type = .output = ah_output }; -static struct net_protocol ah4_protocol = { +static const struct net_protocol ah4_protocol = { .handler = xfrm4_rcv, .err_handler = ah4_err, .no_policy = 1, diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 3863c3a4223..07336c6201f 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1087,6 +1087,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, case NETDEV_DOWN: ip_mc_down(in_dev); break; + case NETDEV_BONDING_OLDTYPE: + ip_mc_unmap(in_dev); + break; + case NETDEV_BONDING_NEWTYPE: + ip_mc_remap(in_dev); + break; case NETDEV_CHANGEMTU: if (inetdev_valid_mtu(dev->mtu)) break; diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 18bb383ea39..12f7287e902 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -615,7 +615,7 @@ static const struct xfrm_type esp_type = .output = esp_output }; -static struct net_protocol esp4_protocol = { +static const struct net_protocol esp4_protocol = { .handler = xfrm4_rcv, .err_handler = esp4_err, .no_policy = 1, diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 97c410e8438..5bc13fe816d 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -655,7 +655,7 @@ static void icmp_unreach(struct sk_buff *skb) struct iphdr *iph; struct icmphdr *icmph; int hash, protocol; - struct net_protocol *ipprot; + const struct net_protocol *ipprot; u32 info = 0; struct net *net; diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 01b4284ed69..d41e5de79a8 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1298,6 +1298,28 @@ void ip_mc_dec_group(struct in_device *in_dev, __be32 addr) } } +/* Device changing type */ + +void ip_mc_unmap(struct in_device *in_dev) +{ + struct ip_mc_list *i; + + ASSERT_RTNL(); + + for (i = in_dev->mc_list; i; i = i->next) + igmp_group_dropped(i); +} + +void ip_mc_remap(struct in_device *in_dev) +{ + struct ip_mc_list *i; + + ASSERT_RTNL(); + + for (i = in_dev->mc_list; i; i = i->next) + igmp_group_added(i); +} + /* Device going down */ void ip_mc_down(struct in_device *in_dev) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 533afaadefd..d9645c94a06 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -1288,7 +1288,7 @@ static void ipgre_fb_tunnel_init(struct net_device *dev) } -static struct net_protocol ipgre_protocol = { +static const struct net_protocol ipgre_protocol = { .handler = ipgre_rcv, .err_handler = ipgre_err, .netns_ok = 1, diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index db46b4b5b2b..6c98b43badf 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -202,7 +202,7 @@ static int ip_local_deliver_finish(struct sk_buff *skb) { int protocol = ip_hdr(skb)->protocol; int hash, raw; - struct net_protocol *ipprot; + const struct net_protocol *ipprot; resubmit: raw = raw_local_deliver(skb, protocol); diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 3262ce06294..38fbf04150a 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -146,7 +146,7 @@ static const struct xfrm_type ipcomp_type = { .output = ipcomp_output }; -static struct net_protocol ipcomp4_protocol = { +static const struct net_protocol ipcomp4_protocol = { .handler = xfrm4_rcv, .err_handler = ipcomp4_err, .no_policy = 1, diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 65d421cf5bc..c43ec2d51ce 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -99,10 +99,6 @@ static int ipmr_cache_report(struct net *net, struct sk_buff *pkt, vifi_t vifi, int assert); static int ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm); -#ifdef CONFIG_IP_PIMSM_V2 -static struct net_protocol pim_protocol; -#endif - static struct timer_list ipmr_expire_timer; /* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */ @@ -1945,7 +1941,7 @@ static const struct file_operations ipmr_mfc_fops = { #endif #ifdef CONFIG_IP_PIMSM_V2 -static struct net_protocol pim_protocol = { +static const struct net_protocol pim_protocol = { .handler = pim_rcv, .netns_ok = 1, }; diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c index a2e5fc0a15e..542f22fc98b 100644 --- a/net/ipv4/protocol.c +++ b/net/ipv4/protocol.c @@ -28,14 +28,14 @@ #include <linux/spinlock.h> #include <net/protocol.h> -struct net_protocol *inet_protos[MAX_INET_PROTOS] ____cacheline_aligned_in_smp; +const struct net_protocol *inet_protos[MAX_INET_PROTOS] ____cacheline_aligned_in_smp; static DEFINE_SPINLOCK(inet_proto_lock); /* * Add a protocol handler to the hash tables */ -int inet_add_protocol(struct net_protocol *prot, unsigned char protocol) +int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol) { int hash, ret; @@ -57,7 +57,7 @@ int inet_add_protocol(struct net_protocol *prot, unsigned char protocol) * Remove a protocol from the hash tables. */ -int inet_del_protocol(struct net_protocol *prot, unsigned char protocol) +int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol) { int hash, ret; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index edeea060db4..19a0612b8a2 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2012,7 +2012,7 @@ int tcp_disconnect(struct sock *sk, int flags) tp->snd_cwnd = 2; icsk->icsk_probes_out = 0; tp->packets_out = 0; - tp->snd_ssthresh = 0x7fffffff; + tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; tp->snd_cwnd_cnt = 0; tp->bytes_acked = 0; tcp_set_ca_state(sk, TCP_CA_Open); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index af6d6fa00db..d86784be7ab 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -761,7 +761,7 @@ void tcp_update_metrics(struct sock *sk) set_dst_metric_rtt(dst, RTAX_RTTVAR, var); } - if (tp->snd_ssthresh >= 0xFFFF) { + if (tcp_in_initial_slowstart(tp)) { /* Slow start still did not finish. */ if (dst_metric(dst, RTAX_SSTHRESH) && !dst_metric_locked(dst, RTAX_SSTHRESH) && diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 0543561da99..7cda24b53f6 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1808,7 +1808,7 @@ static int tcp_v4_init_sock(struct sock *sk) /* See draft-stevens-tcpca-spec-01 for discussion of the * initialization of these values. */ - tp->snd_ssthresh = 0x7fffffff; /* Infinity */ + tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; tp->snd_cwnd_clamp = ~0; tp->mss_cache = 536; @@ -2284,7 +2284,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) jiffies_to_clock_t(icsk->icsk_ack.ato), (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, tp->snd_cwnd, - tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh, + tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh, len); } diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index e48c37d74d7..624c3c9b3c2 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -363,7 +363,7 @@ void tcp_twsk_destructor(struct sock *sk) #ifdef CONFIG_TCP_MD5SIG struct tcp_timewait_sock *twsk = tcp_twsk(sk); if (twsk->tw_md5_keylen) - tcp_put_md5sig_pool(); + tcp_free_md5sig_pool(); #endif } @@ -410,7 +410,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, newtp->retrans_out = 0; newtp->sacked_out = 0; newtp->fackets_out = 0; - newtp->snd_ssthresh = 0x7fffffff; + newtp->snd_ssthresh = TCP_INFINITE_SSTHRESH; /* So many TCP implementations out there (incorrectly) count the * initial SYN frame in their delayed-ACK and congestion control diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c index cb1f0e83830..3959e0ca456 100644 --- a/net/ipv4/tunnel4.c +++ b/net/ipv4/tunnel4.c @@ -132,7 +132,7 @@ static void tunnel64_err(struct sk_buff *skb, u32 info) } #endif -static struct net_protocol tunnel4_protocol = { +static const struct net_protocol tunnel4_protocol = { .handler = tunnel4_rcv, .err_handler = tunnel4_err, .no_policy = 1, @@ -140,7 +140,7 @@ static struct net_protocol tunnel4_protocol = { }; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -static struct net_protocol tunnel64_protocol = { +static const struct net_protocol tunnel64_protocol = { .handler = tunnel64_rcv, .err_handler = tunnel64_err, .no_policy = 1, diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c index c784891cb7e..95248d7f75e 100644 --- a/net/ipv4/udplite.c +++ b/net/ipv4/udplite.c @@ -25,7 +25,7 @@ static void udplite_err(struct sk_buff *skb, u32 info) __udp4_lib_err(skb, info, &udplite_table); } -static struct net_protocol udplite_protocol = { +static const struct net_protocol udplite_protocol = { .handler = udplite_rcv, .err_handler = udplite_err, .no_policy = 1, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index c9b369034a4..55f486d89c8 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -137,6 +137,8 @@ static DEFINE_SPINLOCK(addrconf_verify_lock); static void addrconf_join_anycast(struct inet6_ifaddr *ifp); static void addrconf_leave_anycast(struct inet6_ifaddr *ifp); +static void addrconf_bonding_change(struct net_device *dev, + unsigned long event); static int addrconf_ifdown(struct net_device *dev, int how); static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags); @@ -1405,8 +1407,8 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) struct inet6_dev *idev = ifp->idev; if (net_ratelimit()) - printk(KERN_INFO "%s: IPv6 duplicate address detected!\n", - ifp->idev->dev->name); + printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n", + ifp->idev->dev->name, &ifp->addr); if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) { struct in6_addr addr; @@ -2582,6 +2584,10 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, return notifier_from_errno(err); } break; + case NETDEV_BONDING_OLDTYPE: + case NETDEV_BONDING_NEWTYPE: + addrconf_bonding_change(dev, event); + break; } return NOTIFY_OK; @@ -2595,6 +2601,19 @@ static struct notifier_block ipv6_dev_notf = { .priority = 0 }; +static void addrconf_bonding_change(struct net_device *dev, unsigned long event) +{ + struct inet6_dev *idev; + ASSERT_RTNL(); + + idev = __in6_dev_get(dev); + + if (event == NETDEV_BONDING_NEWTYPE) + ipv6_mc_remap(idev); + else if (event == NETDEV_BONDING_OLDTYPE) + ipv6_mc_unmap(idev); +} + static int addrconf_ifdown(struct net_device *dev, int how) { struct inet6_dev *idev; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index a123a328aeb..e127a32f954 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -710,7 +710,7 @@ EXPORT_SYMBOL_GPL(ipv6_opt_accepted); static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto) { - struct inet6_protocol *ops = NULL; + const struct inet6_protocol *ops = NULL; for (;;) { struct ipv6_opt_hdr *opth; @@ -745,7 +745,7 @@ static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto) static int ipv6_gso_send_check(struct sk_buff *skb) { struct ipv6hdr *ipv6h; - struct inet6_protocol *ops; + const struct inet6_protocol *ops; int err = -EINVAL; if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h)))) @@ -773,7 +773,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features) { struct sk_buff *segs = ERR_PTR(-EINVAL); struct ipv6hdr *ipv6h; - struct inet6_protocol *ops; + const struct inet6_protocol *ops; int proto; struct frag_hdr *fptr; unsigned int unfrag_ip6hlen; @@ -840,7 +840,7 @@ struct ipv6_gro_cb { static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, struct sk_buff *skb) { - struct inet6_protocol *ops; + const struct inet6_protocol *ops; struct sk_buff **pp = NULL; struct sk_buff *p; struct ipv6hdr *iph; @@ -926,7 +926,7 @@ out: static int ipv6_gro_complete(struct sk_buff *skb) { - struct inet6_protocol *ops; + const struct inet6_protocol *ops; struct ipv6hdr *iph = ipv6_hdr(skb); int err = -ENOSYS; diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 86f42a288c4..c1589e2f1dc 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -527,7 +527,7 @@ static const struct xfrm_type ah6_type = .hdr_offset = xfrm6_find_1stfragopt, }; -static struct inet6_protocol ah6_protocol = { +static const struct inet6_protocol ah6_protocol = { .handler = xfrm6_rcv, .err_handler = ah6_err, .flags = INET6_PROTO_NOPOLICY, diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 678bb95b152..af597c73ebe 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -558,7 +558,7 @@ static const struct xfrm_type esp6_type = .hdr_offset = xfrm6_find_1stfragopt, }; -static struct inet6_protocol esp6_protocol = { +static const struct inet6_protocol esp6_protocol = { .handler = xfrm6_rcv, .err_handler = esp6_err, .flags = INET6_PROTO_NOPOLICY, diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 4aae658e550..df159fffe4b 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -500,17 +500,17 @@ unknown_rh: return -1; } -static struct inet6_protocol rthdr_protocol = { +static const struct inet6_protocol rthdr_protocol = { .handler = ipv6_rthdr_rcv, .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR, }; -static struct inet6_protocol destopt_protocol = { +static const struct inet6_protocol destopt_protocol = { .handler = ipv6_destopt_rcv, .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR, }; -static struct inet6_protocol nodata_protocol = { +static const struct inet6_protocol nodata_protocol = { .handler = dst_discard, .flags = INET6_PROTO_NOPOLICY, }; diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index e2325f6a05f..f23ebbec063 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -86,7 +86,7 @@ static inline struct sock *icmpv6_sk(struct net *net) static int icmpv6_rcv(struct sk_buff *skb); -static struct inet6_protocol icmpv6_protocol = { +static const struct inet6_protocol icmpv6_protocol = { .handler = icmpv6_rcv, .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, }; @@ -583,7 +583,7 @@ out: static void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) { - struct inet6_protocol *ipprot; + const struct inet6_protocol *ipprot; int inner_offset; int hash; u8 nexthdr; diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 2d9cbaa67ed..237e2dba6e9 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -159,7 +159,7 @@ drop: static int ip6_input_finish(struct sk_buff *skb) { - struct inet6_protocol *ipprot; + const struct inet6_protocol *ipprot; unsigned int nhoff; int nexthdr, raw; u8 hash; diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 5c8d73730c7..3907510c2ce 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -83,10 +83,6 @@ static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt, static int ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm); static void mroute_clean_tables(struct net *net); -#ifdef CONFIG_IPV6_PIMSM_V2 -static struct inet6_protocol pim6_protocol; -#endif - static struct timer_list ipmr_expire_timer; @@ -410,7 +406,7 @@ static int pim6_rcv(struct sk_buff *skb) return 0; } -static struct inet6_protocol pim6_protocol = { +static const struct inet6_protocol pim6_protocol = { .handler = pim6_rcv, }; diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 79c172f1ff0..2f2a5ca2c87 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -178,7 +178,7 @@ static const struct xfrm_type ipcomp6_type = .hdr_offset = xfrm6_find_1stfragopt, }; -static struct inet6_protocol ipcomp6_protocol = +static const struct inet6_protocol ipcomp6_protocol = { .handler = xfrm6_rcv, .err_handler = ipcomp6_err, diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 71c3dacec1e..f9fcf690bd5 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -2249,6 +2249,25 @@ static void igmp6_timer_handler(unsigned long data) ma_put(ma); } +/* Device changing type */ + +void ipv6_mc_unmap(struct inet6_dev *idev) +{ + struct ifmcaddr6 *i; + + /* Install multicast list, except for all-nodes (already installed) */ + + read_lock_bh(&idev->lock); + for (i = idev->mc_list; i; i = i->next) + igmp6_group_dropped(i); + read_unlock_bh(&idev->lock); +} + +void ipv6_mc_remap(struct inet6_dev *idev) +{ + ipv6_mc_up(idev); +} + /* Device going down */ void ipv6_mc_down(struct inet6_dev *idev) diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c index 568864f722c..1fa3468f0f3 100644 --- a/net/ipv6/protocol.c +++ b/net/ipv6/protocol.c @@ -25,11 +25,11 @@ #include <linux/spinlock.h> #include <net/protocol.h> -struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; +const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; static DEFINE_SPINLOCK(inet6_proto_lock); -int inet6_add_protocol(struct inet6_protocol *prot, unsigned char protocol) +int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol) { int ret, hash = protocol & (MAX_INET_PROTOS - 1); @@ -53,7 +53,7 @@ EXPORT_SYMBOL(inet6_add_protocol); * Remove a protocol from the hash tables. */ -int inet6_del_protocol(struct inet6_protocol *prot, unsigned char protocol) +int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol) { int ret, hash = protocol & (MAX_INET_PROTOS - 1); diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 2642a41a853..da5bd0ed83d 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -627,7 +627,7 @@ fail_hdr: return -1; } -static struct inet6_protocol frag_protocol = +static const struct inet6_protocol frag_protocol = { .handler = ipv6_frag_rcv, .flags = INET6_PROTO_NOPOLICY, diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 9ccfef34556..77aecbe8ff6 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -481,7 +481,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, pref = rinfo->route_pref; if (pref == ICMPV6_ROUTER_PREF_INVALID) - pref = ICMPV6_ROUTER_PREF_MEDIUM; + return -EINVAL; lifetime = addrconf_timeout_fixup(ntohl(rinfo->lifetime), HZ); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 3aae0f217d6..21d100b68b1 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1846,7 +1846,7 @@ static int tcp_v6_init_sock(struct sock *sk) /* See draft-stevens-tcpca-spec-01 for discussion of the * initialization of these values. */ - tp->snd_ssthresh = 0x7fffffff; + tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; tp->snd_cwnd_clamp = ~0; tp->mss_cache = 536; @@ -1969,7 +1969,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) jiffies_to_clock_t(icsk->icsk_rto), jiffies_to_clock_t(icsk->icsk_ack.ato), (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, - tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh + tp->snd_cwnd, + tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh ); } @@ -2093,7 +2094,7 @@ struct proto tcpv6_prot = { #endif }; -static struct inet6_protocol tcpv6_protocol = { +static const struct inet6_protocol tcpv6_protocol = { .handler = tcp_v6_rcv, .err_handler = tcp_v6_err, .gso_send_check = tcp_v6_gso_send_check, diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c index 633ad789eff..51e2832d13a 100644 --- a/net/ipv6/tunnel6.c +++ b/net/ipv6/tunnel6.c @@ -133,13 +133,13 @@ static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, break; } -static struct inet6_protocol tunnel6_protocol = { +static const struct inet6_protocol tunnel6_protocol = { .handler = tunnel6_rcv, .err_handler = tunnel6_err, .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, }; -static struct inet6_protocol tunnel46_protocol = { +static const struct inet6_protocol tunnel46_protocol = { .handler = tunnel46_rcv, .err_handler = tunnel6_err, .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 164040613c2..b265b7047d3 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1172,7 +1172,7 @@ out: return segs; } -static struct inet6_protocol udpv6_protocol = { +static const struct inet6_protocol udpv6_protocol = { .handler = udpv6_rcv, .err_handler = udpv6_err, .gso_send_check = udp6_ufo_send_check, diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index 4818c48688f..d737a27ee01 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c @@ -25,7 +25,7 @@ static void udplitev6_err(struct sk_buff *skb, __udp6_lib_err(skb, opt, type, code, offset, info, &udplite_table); } -static struct inet6_protocol udplitev6_protocol = { +static const struct inet6_protocol udplitev6_protocol = { .handler = udplitev6_rcv, .err_handler = udplitev6_err, .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 49c15b48408..d985d163dcf 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -34,7 +34,7 @@ static char iucv_userid[80]; -static struct proto_ops iucv_sock_ops; +static const struct proto_ops iucv_sock_ops; static struct proto iucv_proto = { .name = "AF_IUCV", @@ -59,8 +59,8 @@ do { \ DEFINE_WAIT(__wait); \ long __timeo = timeo; \ ret = 0; \ + prepare_to_wait(sk->sk_sleep, &__wait, TASK_INTERRUPTIBLE); \ while (!(condition)) { \ - prepare_to_wait(sk->sk_sleep, &__wait, TASK_INTERRUPTIBLE); \ if (!__timeo) { \ ret = -EAGAIN; \ break; \ @@ -361,10 +361,9 @@ static void iucv_sock_cleanup_listen(struct sock *parent) } parent->sk_state = IUCV_CLOSED; - sock_set_flag(parent, SOCK_ZAPPED); } -/* Kill socket */ +/* Kill socket (only if zapped and orphaned) */ static void iucv_sock_kill(struct sock *sk) { if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) @@ -426,17 +425,18 @@ static void iucv_sock_close(struct sock *sk) skb_queue_purge(&iucv->send_skb_q); skb_queue_purge(&iucv->backlog_skb_q); - - sock_set_flag(sk, SOCK_ZAPPED); break; default: sock_set_flag(sk, SOCK_ZAPPED); + /* nothing to do here */ break; } + /* mark socket for deletion by iucv_sock_kill() */ + sock_set_flag(sk, SOCK_ZAPPED); + release_sock(sk); - iucv_sock_kill(sk); } static void iucv_sock_init(struct sock *sk, struct sock *parent) @@ -569,6 +569,7 @@ struct sock *iucv_accept_dequeue(struct sock *parent, struct socket *newsock) if (sk->sk_state == IUCV_CONNECTED || sk->sk_state == IUCV_SEVERED || + sk->sk_state == IUCV_DISCONN || /* due to PM restore */ !newsock) { iucv_accept_unlink(sk); if (newsock) @@ -1035,6 +1036,10 @@ out: return err; } +/* iucv_fragment_skb() - Fragment a single IUCV message into multiple skb's + * + * Locking: must be called with message_q.lock held + */ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len) { int dataleft, size, copied = 0; @@ -1069,6 +1074,10 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len) return 0; } +/* iucv_process_message() - Receive a single outstanding IUCV message + * + * Locking: must be called with message_q.lock held + */ static void iucv_process_message(struct sock *sk, struct sk_buff *skb, struct iucv_path *path, struct iucv_message *msg) @@ -1119,6 +1128,10 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb, skb_queue_head(&iucv_sk(sk)->backlog_skb_q, skb); } +/* iucv_process_message_q() - Process outstanding IUCV messages + * + * Locking: must be called with message_q.lock held + */ static void iucv_process_message_q(struct sock *sk) { struct iucv_sock *iucv = iucv_sk(sk); @@ -1209,6 +1222,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, kfree_skb(skb); /* Queue backlog skbs */ + spin_lock_bh(&iucv->message_q.lock); rskb = skb_dequeue(&iucv->backlog_skb_q); while (rskb) { if (sock_queue_rcv_skb(sk, rskb)) { @@ -1220,11 +1234,10 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, } } if (skb_queue_empty(&iucv->backlog_skb_q)) { - spin_lock_bh(&iucv->message_q.lock); if (!list_empty(&iucv->message_q.list)) iucv_process_message_q(sk); - spin_unlock_bh(&iucv->message_q.lock); } + spin_unlock_bh(&iucv->message_q.lock); } done: @@ -1682,7 +1695,7 @@ static void iucv_callback_shutdown(struct iucv_path *path, u8 ipuser[16]) bh_unlock_sock(sk); } -static struct proto_ops iucv_sock_ops = { +static const struct proto_ops iucv_sock_ops = { .family = PF_IUCV, .owner = THIS_MODULE, .release = iucv_sock_release, diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index c833481d32e..3973d0e61e5 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c @@ -79,6 +79,14 @@ static int iucv_bus_match(struct device *dev, struct device_driver *drv) return 0; } +enum iucv_pm_states { + IUCV_PM_INITIAL = 0, + IUCV_PM_FREEZING = 1, + IUCV_PM_THAWING = 2, + IUCV_PM_RESTORING = 3, +}; +static enum iucv_pm_states iucv_pm_state; + static int iucv_pm_prepare(struct device *); static void iucv_pm_complete(struct device *); static int iucv_pm_freeze(struct device *); @@ -354,7 +362,7 @@ static int iucv_query_maxconn(void) " srl %0,28\n" : "=d" (ccode), "+d" (reg0), "+d" (reg1) : : "cc"); if (ccode == 0) - iucv_max_pathid = reg0; + iucv_max_pathid = reg1; kfree(param); return ccode ? -EPERM : 0; } @@ -856,7 +864,7 @@ int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler, int rc; local_bh_disable(); - if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { + if (cpus_empty(iucv_buffer_cpumask)) { rc = -EIO; goto out; } @@ -905,7 +913,7 @@ int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler, spin_lock_bh(&iucv_table_lock); iucv_cleanup_queue(); - if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { + if (cpus_empty(iucv_buffer_cpumask)) { rc = -EIO; goto out; } @@ -965,7 +973,7 @@ int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16]) int rc; local_bh_disable(); - if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { + if (cpus_empty(iucv_buffer_cpumask)) { rc = -EIO; goto out; } @@ -997,7 +1005,7 @@ int iucv_path_resume(struct iucv_path *path, u8 userdata[16]) int rc; local_bh_disable(); - if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { + if (cpus_empty(iucv_buffer_cpumask)) { rc = -EIO; goto out; } @@ -1026,7 +1034,7 @@ int iucv_path_sever(struct iucv_path *path, u8 userdata[16]) int rc; preempt_disable(); - if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { + if (cpus_empty(iucv_buffer_cpumask)) { rc = -EIO; goto out; } @@ -1060,7 +1068,7 @@ int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg, int rc; local_bh_disable(); - if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { + if (cpus_empty(iucv_buffer_cpumask)) { rc = -EIO; goto out; } @@ -1152,7 +1160,7 @@ int __iucv_message_receive(struct iucv_path *path, struct iucv_message *msg, if (msg->flags & IUCV_IPRMDATA) return iucv_message_receive_iprmdata(path, msg, flags, buffer, size, residual); - if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { + if (cpus_empty(iucv_buffer_cpumask)) { rc = -EIO; goto out; } @@ -1225,7 +1233,7 @@ int iucv_message_reject(struct iucv_path *path, struct iucv_message *msg) int rc; local_bh_disable(); - if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { + if (cpus_empty(iucv_buffer_cpumask)) { rc = -EIO; goto out; } @@ -1264,7 +1272,7 @@ int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg, int rc; local_bh_disable(); - if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { + if (cpus_empty(iucv_buffer_cpumask)) { rc = -EIO; goto out; } @@ -1314,7 +1322,7 @@ int __iucv_message_send(struct iucv_path *path, struct iucv_message *msg, union iucv_param *parm; int rc; - if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { + if (cpus_empty(iucv_buffer_cpumask)) { rc = -EIO; goto out; } @@ -1401,7 +1409,7 @@ int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg, int rc; local_bh_disable(); - if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { + if (cpus_empty(iucv_buffer_cpumask)) { rc = -EIO; goto out; } @@ -1875,6 +1883,7 @@ static int iucv_pm_freeze(struct device *dev) #ifdef CONFIG_PM_DEBUG printk(KERN_WARNING "iucv_pm_freeze\n"); #endif + iucv_pm_state = IUCV_PM_FREEZING; for_each_cpu_mask_nr(cpu, iucv_irq_cpumask) smp_call_function_single(cpu, iucv_block_cpu_almost, NULL, 1); if (dev->driver && dev->driver->pm && dev->driver->pm->freeze) @@ -1899,6 +1908,7 @@ static int iucv_pm_thaw(struct device *dev) #ifdef CONFIG_PM_DEBUG printk(KERN_WARNING "iucv_pm_thaw\n"); #endif + iucv_pm_state = IUCV_PM_THAWING; if (!iucv_path_table) { rc = iucv_enable(); if (rc) @@ -1933,6 +1943,10 @@ static int iucv_pm_restore(struct device *dev) #ifdef CONFIG_PM_DEBUG printk(KERN_WARNING "iucv_pm_restore %p\n", iucv_path_table); #endif + if ((iucv_pm_state != IUCV_PM_RESTORING) && iucv_path_table) + pr_warning("Suspending Linux did not completely close all IUCV " + "connections\n"); + iucv_pm_state = IUCV_PM_RESTORING; if (cpus_empty(iucv_irq_cpumask)) { rc = iucv_query_maxconn(); rc = iucv_enable(); diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 7c5142988bb..6e5d68b4e42 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c @@ -418,7 +418,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, /* contention window */ tx_time_single += t_slot + min(cw, mp->cw_max); - cw = (cw + 1) << 1; + cw = (cw << 1) | 1; tx_time += tx_time_single; tx_time_cts += tx_time_single + mi->sp_ack_dur; diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index d0ff382c40c..c5aab6a368c 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -177,9 +177,11 @@ static void netlink_sock_destruct(struct sock *sk) * this, _but_ remember, it adds useless work on UP machines. */ -static void netlink_table_grab(void) +void netlink_table_grab(void) __acquires(nl_table_lock) { + might_sleep(); + write_lock_irq(&nl_table_lock); if (atomic_read(&nl_table_users)) { @@ -200,7 +202,7 @@ static void netlink_table_grab(void) } } -static void netlink_table_ungrab(void) +void netlink_table_ungrab(void) __releases(nl_table_lock) { write_unlock_irq(&nl_table_lock); @@ -1549,37 +1551,21 @@ static void netlink_free_old_listeners(struct rcu_head *rcu_head) kfree(lrh->ptr); } -/** - * netlink_change_ngroups - change number of multicast groups - * - * This changes the number of multicast groups that are available - * on a certain netlink family. Note that it is not possible to - * change the number of groups to below 32. Also note that it does - * not implicitly call netlink_clear_multicast_users() when the - * number of groups is reduced. - * - * @sk: The kernel netlink socket, as returned by netlink_kernel_create(). - * @groups: The new number of groups. - */ -int netlink_change_ngroups(struct sock *sk, unsigned int groups) +int __netlink_change_ngroups(struct sock *sk, unsigned int groups) { unsigned long *listeners, *old = NULL; struct listeners_rcu_head *old_rcu_head; struct netlink_table *tbl = &nl_table[sk->sk_protocol]; - int err = 0; if (groups < 32) groups = 32; - netlink_table_grab(); if (NLGRPSZ(tbl->groups) < NLGRPSZ(groups)) { listeners = kzalloc(NLGRPSZ(groups) + sizeof(struct listeners_rcu_head), GFP_ATOMIC); - if (!listeners) { - err = -ENOMEM; - goto out_ungrab; - } + if (!listeners) + return -ENOMEM; old = tbl->listeners; memcpy(listeners, old, NLGRPSZ(tbl->groups)); rcu_assign_pointer(tbl->listeners, listeners); @@ -1597,8 +1583,29 @@ int netlink_change_ngroups(struct sock *sk, unsigned int groups) } tbl->groups = groups; - out_ungrab: + return 0; +} + +/** + * netlink_change_ngroups - change number of multicast groups + * + * This changes the number of multicast groups that are available + * on a certain netlink family. Note that it is not possible to + * change the number of groups to below 32. Also note that it does + * not implicitly call netlink_clear_multicast_users() when the + * number of groups is reduced. + * + * @sk: The kernel netlink socket, as returned by netlink_kernel_create(). + * @groups: The new number of groups. + */ +int netlink_change_ngroups(struct sock *sk, unsigned int groups) +{ + int err; + + netlink_table_grab(); + err = __netlink_change_ngroups(sk, groups); netlink_table_ungrab(); + return err; } diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 66f6ba0bab1..566941e0336 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -176,9 +176,10 @@ int genl_register_mc_group(struct genl_family *family, if (family->netnsok) { struct net *net; + netlink_table_grab(); rcu_read_lock(); for_each_net_rcu(net) { - err = netlink_change_ngroups(net->genl_sock, + err = __netlink_change_ngroups(net->genl_sock, mc_groups_longs * BITS_PER_LONG); if (err) { /* @@ -188,10 +189,12 @@ int genl_register_mc_group(struct genl_family *family, * increased on some sockets which is ok. */ rcu_read_unlock(); + netlink_table_ungrab(); goto out; } } rcu_read_unlock(); + netlink_table_ungrab(); } else { err = netlink_change_ngroups(init_net.genl_sock, mc_groups_longs * BITS_PER_LONG); diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index 2f65dcaed2f..5f42f30dd16 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c @@ -209,7 +209,14 @@ static int phonet_device_autoconf(struct net_device *dev) SIOCPNGAUTOCONF); if (ret < 0) return ret; - return phonet_address_add(dev, req.ifr_phonet_autoconf.device); + + ASSERT_RTNL(); + ret = phonet_address_add(dev, req.ifr_phonet_autoconf.device); + if (ret) + return ret; + phonet_address_notify(RTM_NEWADDR, dev, + req.ifr_phonet_autoconf.device); + return 0; } /* notify Phonet of device events */ diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index 108ed2e671c..6b58aeff4c7 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c @@ -359,7 +359,7 @@ static struct proto rds_proto = { .obj_size = sizeof(struct rds_sock), }; -static struct proto_ops rds_proto_ops = { +static const struct proto_ops rds_proto_ops = { .family = AF_RDS, .owner = THIS_MODULE, .release = rds_release, diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index e5f478ca3d6..1e166c9685a 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -63,7 +63,7 @@ int sysctl_rose_window_size = ROSE_DEFAULT_WINDOW_SIZE; static HLIST_HEAD(rose_list); static DEFINE_SPINLOCK(rose_list_lock); -static struct proto_ops rose_proto_ops; +static const struct proto_ops rose_proto_ops; ax25_address rose_callsign; @@ -1515,7 +1515,7 @@ static struct net_proto_family rose_family_ops = { .owner = THIS_MODULE, }; -static struct proto_ops rose_proto_ops = { +static const struct proto_ops rose_proto_ops = { .family = PF_ROSE, .owner = THIS_MODULE, .release = rose_release, diff --git a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c index c9f1f0a3a2f..b4a22097703 100644 --- a/net/rxrpc/ar-ack.c +++ b/net/rxrpc/ar-ack.c @@ -40,7 +40,7 @@ static const s8 rxrpc_ack_priority[] = { /* * propose an ACK be sent */ -void __rxrpc_propose_ACK(struct rxrpc_call *call, uint8_t ack_reason, +void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, __be32 serial, bool immediate) { unsigned long expiry; @@ -120,7 +120,7 @@ cancel_timer: /* * propose an ACK be sent, locking the call structure */ -void rxrpc_propose_ACK(struct rxrpc_call *call, uint8_t ack_reason, +void rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, __be32 serial, bool immediate) { s8 prior = rxrpc_ack_priority[ack_reason]; @@ -520,7 +520,7 @@ static void rxrpc_zap_tx_window(struct rxrpc_call *call) struct rxrpc_skb_priv *sp; struct sk_buff *skb; unsigned long _skb, *acks_window; - uint8_t winsz = call->acks_winsz; + u8 winsz = call->acks_winsz; int tail; acks_window = call->acks_window; diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index 3e7318c1343..7043b294bb6 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -229,7 +229,7 @@ struct rxrpc_conn_bundle { int debug_id; /* debug ID for printks */ unsigned short num_conns; /* number of connections in this bundle */ __be16 service_id; /* service ID */ - uint8_t security_ix; /* security type */ + u8 security_ix; /* security type */ }; /* @@ -370,10 +370,10 @@ struct rxrpc_call { u8 channel; /* connection channel occupied by this call */ /* transmission-phase ACK management */ - uint8_t acks_head; /* offset into window of first entry */ - uint8_t acks_tail; /* offset into window of last entry */ - uint8_t acks_winsz; /* size of un-ACK'd window */ - uint8_t acks_unacked; /* lowest unacked packet in last ACK received */ + u8 acks_head; /* offset into window of first entry */ + u8 acks_tail; /* offset into window of last entry */ + u8 acks_winsz; /* size of un-ACK'd window */ + u8 acks_unacked; /* lowest unacked packet in last ACK received */ int acks_latest; /* serial number of latest ACK received */ rxrpc_seq_t acks_hard; /* highest definitively ACK'd msg seq */ unsigned long *acks_window; /* sent packet window @@ -388,7 +388,7 @@ struct rxrpc_call { rxrpc_seq_t rx_first_oos; /* first packet in rx_oos_queue (or 0) */ rxrpc_seq_t ackr_win_top; /* top of ACK window (rx_data_eaten is bottom) */ rxrpc_seq_net_t ackr_prev_seq; /* previous sequence number received */ - uint8_t ackr_reason; /* reason to ACK */ + u8 ackr_reason; /* reason to ACK */ __be32 ackr_serial; /* serial of packet being ACK'd */ atomic_t ackr_not_idle; /* number of packets in Rx queue */ @@ -402,22 +402,6 @@ struct rxrpc_call { }; /* - * RxRPC key for Kerberos (type-2 security) - */ -struct rxkad_key { - u16 security_index; /* RxRPC header security index */ - u16 ticket_len; /* length of ticket[] */ - u32 expiry; /* time at which expires */ - u32 kvno; /* key version number */ - u8 session_key[8]; /* DES session key */ - u8 ticket[0]; /* the encrypted ticket */ -}; - -struct rxrpc_key_payload { - struct rxkad_key k; -}; - -/* * locally abort an RxRPC call */ static inline void rxrpc_abort_call(struct rxrpc_call *call, u32 abort_code) @@ -450,8 +434,8 @@ extern int rxrpc_reject_call(struct rxrpc_sock *); /* * ar-ack.c */ -extern void __rxrpc_propose_ACK(struct rxrpc_call *, uint8_t, __be32, bool); -extern void rxrpc_propose_ACK(struct rxrpc_call *, uint8_t, __be32, bool); +extern void __rxrpc_propose_ACK(struct rxrpc_call *, u8, __be32, bool); +extern void rxrpc_propose_ACK(struct rxrpc_call *, u8, __be32, bool); extern void rxrpc_process_call(struct work_struct *); /* diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c index ad8c7a782da..74697b20049 100644 --- a/net/rxrpc/ar-key.c +++ b/net/rxrpc/ar-key.c @@ -17,6 +17,7 @@ #include <linux/skbuff.h> #include <linux/key-type.h> #include <linux/crypto.h> +#include <linux/ctype.h> #include <net/sock.h> #include <net/af_rxrpc.h> #include <keys/rxrpc-type.h> @@ -28,6 +29,7 @@ static int rxrpc_instantiate_s(struct key *, const void *, size_t); static void rxrpc_destroy(struct key *); static void rxrpc_destroy_s(struct key *); static void rxrpc_describe(const struct key *, struct seq_file *); +static long rxrpc_read(const struct key *, char __user *, size_t); /* * rxrpc defined keys take an arbitrary string as the description and an @@ -39,6 +41,7 @@ struct key_type key_type_rxrpc = { .match = user_match, .destroy = rxrpc_destroy, .describe = rxrpc_describe, + .read = rxrpc_read, }; EXPORT_SYMBOL(key_type_rxrpc); @@ -55,6 +58,595 @@ struct key_type key_type_rxrpc_s = { }; /* + * parse an RxKAD type XDR format token + * - the caller guarantees we have at least 4 words + */ +static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr, + unsigned toklen) +{ + struct rxrpc_key_token *token, **pptoken; + size_t plen; + u32 tktlen; + int ret; + + _enter(",{%x,%x,%x,%x},%u", + ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), + toklen); + + if (toklen <= 8 * 4) + return -EKEYREJECTED; + tktlen = ntohl(xdr[7]); + _debug("tktlen: %x", tktlen); + if (tktlen > AFSTOKEN_RK_TIX_MAX) + return -EKEYREJECTED; + if (8 * 4 + tktlen != toklen) + return -EKEYREJECTED; + + plen = sizeof(*token) + sizeof(*token->kad) + tktlen; + ret = key_payload_reserve(key, key->datalen + plen); + if (ret < 0) + return ret; + + plen -= sizeof(*token); + token = kmalloc(sizeof(*token), GFP_KERNEL); + if (!token) + return -ENOMEM; + + token->kad = kmalloc(plen, GFP_KERNEL); + if (!token->kad) { + kfree(token); + return -ENOMEM; + } + + token->security_index = RXRPC_SECURITY_RXKAD; + token->kad->ticket_len = tktlen; + token->kad->vice_id = ntohl(xdr[0]); + token->kad->kvno = ntohl(xdr[1]); + token->kad->start = ntohl(xdr[4]); + token->kad->expiry = ntohl(xdr[5]); + token->kad->primary_flag = ntohl(xdr[6]); + memcpy(&token->kad->session_key, &xdr[2], 8); + memcpy(&token->kad->ticket, &xdr[8], tktlen); + + _debug("SCIX: %u", token->security_index); + _debug("TLEN: %u", token->kad->ticket_len); + _debug("EXPY: %x", token->kad->expiry); + _debug("KVNO: %u", token->kad->kvno); + _debug("PRIM: %u", token->kad->primary_flag); + _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x", + token->kad->session_key[0], token->kad->session_key[1], + token->kad->session_key[2], token->kad->session_key[3], + token->kad->session_key[4], token->kad->session_key[5], + token->kad->session_key[6], token->kad->session_key[7]); + if (token->kad->ticket_len >= 8) + _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x", + token->kad->ticket[0], token->kad->ticket[1], + token->kad->ticket[2], token->kad->ticket[3], + token->kad->ticket[4], token->kad->ticket[5], + token->kad->ticket[6], token->kad->ticket[7]); + + /* count the number of tokens attached */ + key->type_data.x[0]++; + + /* attach the data */ + for (pptoken = (struct rxrpc_key_token **)&key->payload.data; + *pptoken; + pptoken = &(*pptoken)->next) + continue; + *pptoken = token; + if (token->kad->expiry < key->expiry) + key->expiry = token->kad->expiry; + + _leave(" = 0"); + return 0; +} + +static void rxrpc_free_krb5_principal(struct krb5_principal *princ) +{ + int loop; + + if (princ->name_parts) { + for (loop = princ->n_name_parts - 1; loop >= 0; loop--) + kfree(princ->name_parts[loop]); + kfree(princ->name_parts); + } + kfree(princ->realm); +} + +static void rxrpc_free_krb5_tagged(struct krb5_tagged_data *td) +{ + kfree(td->data); +} + +/* + * free up an RxK5 token + */ +static void rxrpc_rxk5_free(struct rxk5_key *rxk5) +{ + int loop; + + rxrpc_free_krb5_principal(&rxk5->client); + rxrpc_free_krb5_principal(&rxk5->server); + rxrpc_free_krb5_tagged(&rxk5->session); + + if (rxk5->addresses) { + for (loop = rxk5->n_addresses - 1; loop >= 0; loop--) + rxrpc_free_krb5_tagged(&rxk5->addresses[loop]); + kfree(rxk5->addresses); + } + if (rxk5->authdata) { + for (loop = rxk5->n_authdata - 1; loop >= 0; loop--) + rxrpc_free_krb5_tagged(&rxk5->authdata[loop]); + kfree(rxk5->authdata); + } + + kfree(rxk5->ticket); + kfree(rxk5->ticket2); + kfree(rxk5); +} + +/* + * extract a krb5 principal + */ +static int rxrpc_krb5_decode_principal(struct krb5_principal *princ, + const __be32 **_xdr, + unsigned *_toklen) +{ + const __be32 *xdr = *_xdr; + unsigned toklen = *_toklen, n_parts, loop, tmp; + + /* there must be at least one name, and at least #names+1 length + * words */ + if (toklen <= 12) + return -EINVAL; + + _enter(",{%x,%x,%x},%u", + ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), toklen); + + n_parts = ntohl(*xdr++); + toklen -= 4; + if (n_parts <= 0 || n_parts > AFSTOKEN_K5_COMPONENTS_MAX) + return -EINVAL; + princ->n_name_parts = n_parts; + + if (toklen <= (n_parts + 1) * 4) + return -EINVAL; + + princ->name_parts = kcalloc(sizeof(char *), n_parts, GFP_KERNEL); + if (!princ->name_parts) + return -ENOMEM; + + for (loop = 0; loop < n_parts; loop++) { + if (toklen < 4) + return -EINVAL; + tmp = ntohl(*xdr++); + toklen -= 4; + if (tmp <= 0 || tmp > AFSTOKEN_STRING_MAX) + return -EINVAL; + if (tmp > toklen) + return -EINVAL; + princ->name_parts[loop] = kmalloc(tmp + 1, GFP_KERNEL); + if (!princ->name_parts[loop]) + return -ENOMEM; + memcpy(princ->name_parts[loop], xdr, tmp); + princ->name_parts[loop][tmp] = 0; + tmp = (tmp + 3) & ~3; + toklen -= tmp; + xdr += tmp >> 2; + } + + if (toklen < 4) + return -EINVAL; + tmp = ntohl(*xdr++); + toklen -= 4; + if (tmp <= 0 || tmp > AFSTOKEN_K5_REALM_MAX) + return -EINVAL; + if (tmp > toklen) + return -EINVAL; + princ->realm = kmalloc(tmp + 1, GFP_KERNEL); + if (!princ->realm) + return -ENOMEM; + memcpy(princ->realm, xdr, tmp); + princ->realm[tmp] = 0; + tmp = (tmp + 3) & ~3; + toklen -= tmp; + xdr += tmp >> 2; + + _debug("%s/...@%s", princ->name_parts[0], princ->realm); + + *_xdr = xdr; + *_toklen = toklen; + _leave(" = 0 [toklen=%u]", toklen); + return 0; +} + +/* + * extract a piece of krb5 tagged data + */ +static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td, + size_t max_data_size, + const __be32 **_xdr, + unsigned *_toklen) +{ + const __be32 *xdr = *_xdr; + unsigned toklen = *_toklen, len; + + /* there must be at least one tag and one length word */ + if (toklen <= 8) + return -EINVAL; + + _enter(",%zu,{%x,%x},%u", + max_data_size, ntohl(xdr[0]), ntohl(xdr[1]), toklen); + + td->tag = ntohl(*xdr++); + len = ntohl(*xdr++); + toklen -= 8; + if (len > max_data_size) + return -EINVAL; + td->data_len = len; + + if (len > 0) { + td->data = kmalloc(len, GFP_KERNEL); + if (!td->data) + return -ENOMEM; + memcpy(td->data, xdr, len); + len = (len + 3) & ~3; + toklen -= len; + xdr += len >> 2; + } + + _debug("tag %x len %x", td->tag, td->data_len); + + *_xdr = xdr; + *_toklen = toklen; + _leave(" = 0 [toklen=%u]", toklen); + return 0; +} + +/* + * extract an array of tagged data + */ +static int rxrpc_krb5_decode_tagged_array(struct krb5_tagged_data **_td, + u8 *_n_elem, + u8 max_n_elem, + size_t max_elem_size, + const __be32 **_xdr, + unsigned *_toklen) +{ + struct krb5_tagged_data *td; + const __be32 *xdr = *_xdr; + unsigned toklen = *_toklen, n_elem, loop; + int ret; + + /* there must be at least one count */ + if (toklen < 4) + return -EINVAL; + + _enter(",,%u,%zu,{%x},%u", + max_n_elem, max_elem_size, ntohl(xdr[0]), toklen); + + n_elem = ntohl(*xdr++); + toklen -= 4; + if (n_elem < 0 || n_elem > max_n_elem) + return -EINVAL; + *_n_elem = n_elem; + if (n_elem > 0) { + if (toklen <= (n_elem + 1) * 4) + return -EINVAL; + + _debug("n_elem %d", n_elem); + + td = kcalloc(sizeof(struct krb5_tagged_data), n_elem, + GFP_KERNEL); + if (!td) + return -ENOMEM; + *_td = td; + + for (loop = 0; loop < n_elem; loop++) { + ret = rxrpc_krb5_decode_tagged_data(&td[loop], + max_elem_size, + &xdr, &toklen); + if (ret < 0) + return ret; + } + } + + *_xdr = xdr; + *_toklen = toklen; + _leave(" = 0 [toklen=%u]", toklen); + return 0; +} + +/* + * extract a krb5 ticket + */ +static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen, + const __be32 **_xdr, unsigned *_toklen) +{ + const __be32 *xdr = *_xdr; + unsigned toklen = *_toklen, len; + + /* there must be at least one length word */ + if (toklen <= 4) + return -EINVAL; + + _enter(",{%x},%u", ntohl(xdr[0]), toklen); + + len = ntohl(*xdr++); + toklen -= 4; + if (len > AFSTOKEN_K5_TIX_MAX) + return -EINVAL; + *_tktlen = len; + + _debug("ticket len %u", len); + + if (len > 0) { + *_ticket = kmalloc(len, GFP_KERNEL); + if (!*_ticket) + return -ENOMEM; + memcpy(*_ticket, xdr, len); + len = (len + 3) & ~3; + toklen -= len; + xdr += len >> 2; + } + + *_xdr = xdr; + *_toklen = toklen; + _leave(" = 0 [toklen=%u]", toklen); + return 0; +} + +/* + * parse an RxK5 type XDR format token + * - the caller guarantees we have at least 4 words + */ +static int rxrpc_instantiate_xdr_rxk5(struct key *key, const __be32 *xdr, + unsigned toklen) +{ + struct rxrpc_key_token *token, **pptoken; + struct rxk5_key *rxk5; + const __be32 *end_xdr = xdr + (toklen >> 2); + int ret; + + _enter(",{%x,%x,%x,%x},%u", + ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), + toklen); + + /* reserve some payload space for this subkey - the length of the token + * is a reasonable approximation */ + ret = key_payload_reserve(key, key->datalen + toklen); + if (ret < 0) + return ret; + + token = kzalloc(sizeof(*token), GFP_KERNEL); + if (!token) + return -ENOMEM; + + rxk5 = kzalloc(sizeof(*rxk5), GFP_KERNEL); + if (!rxk5) { + kfree(token); + return -ENOMEM; + } + + token->security_index = RXRPC_SECURITY_RXK5; + token->k5 = rxk5; + + /* extract the principals */ + ret = rxrpc_krb5_decode_principal(&rxk5->client, &xdr, &toklen); + if (ret < 0) + goto error; + ret = rxrpc_krb5_decode_principal(&rxk5->server, &xdr, &toklen); + if (ret < 0) + goto error; + + /* extract the session key and the encoding type (the tag field -> + * ENCTYPE_xxx) */ + ret = rxrpc_krb5_decode_tagged_data(&rxk5->session, AFSTOKEN_DATA_MAX, + &xdr, &toklen); + if (ret < 0) + goto error; + + if (toklen < 4 * 8 + 2 * 4) + goto inval; + rxk5->authtime = be64_to_cpup((const __be64 *) xdr); + xdr += 2; + rxk5->starttime = be64_to_cpup((const __be64 *) xdr); + xdr += 2; + rxk5->endtime = be64_to_cpup((const __be64 *) xdr); + xdr += 2; + rxk5->renew_till = be64_to_cpup((const __be64 *) xdr); + xdr += 2; + rxk5->is_skey = ntohl(*xdr++); + rxk5->flags = ntohl(*xdr++); + toklen -= 4 * 8 + 2 * 4; + + _debug("times: a=%llx s=%llx e=%llx rt=%llx", + rxk5->authtime, rxk5->starttime, rxk5->endtime, + rxk5->renew_till); + _debug("is_skey=%x flags=%x", rxk5->is_skey, rxk5->flags); + + /* extract the permitted client addresses */ + ret = rxrpc_krb5_decode_tagged_array(&rxk5->addresses, + &rxk5->n_addresses, + AFSTOKEN_K5_ADDRESSES_MAX, + AFSTOKEN_DATA_MAX, + &xdr, &toklen); + if (ret < 0) + goto error; + + ASSERTCMP((end_xdr - xdr) << 2, ==, toklen); + + /* extract the tickets */ + ret = rxrpc_krb5_decode_ticket(&rxk5->ticket, &rxk5->ticket_len, + &xdr, &toklen); + if (ret < 0) + goto error; + ret = rxrpc_krb5_decode_ticket(&rxk5->ticket2, &rxk5->ticket2_len, + &xdr, &toklen); + if (ret < 0) + goto error; + + ASSERTCMP((end_xdr - xdr) << 2, ==, toklen); + + /* extract the typed auth data */ + ret = rxrpc_krb5_decode_tagged_array(&rxk5->authdata, + &rxk5->n_authdata, + AFSTOKEN_K5_AUTHDATA_MAX, + AFSTOKEN_BDATALN_MAX, + &xdr, &toklen); + if (ret < 0) + goto error; + + ASSERTCMP((end_xdr - xdr) << 2, ==, toklen); + + if (toklen != 0) + goto inval; + + /* attach the payload to the key */ + for (pptoken = (struct rxrpc_key_token **)&key->payload.data; + *pptoken; + pptoken = &(*pptoken)->next) + continue; + *pptoken = token; + if (token->kad->expiry < key->expiry) + key->expiry = token->kad->expiry; + + _leave(" = 0"); + return 0; + +inval: + ret = -EINVAL; +error: + rxrpc_rxk5_free(rxk5); + kfree(token); + _leave(" = %d", ret); + return ret; +} + +/* + * attempt to parse the data as the XDR format + * - the caller guarantees we have more than 7 words + */ +static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datalen) +{ + const __be32 *xdr = data, *token; + const char *cp; + unsigned len, tmp, loop, ntoken, toklen, sec_ix; + int ret; + + _enter(",{%x,%x,%x,%x},%zu", + ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), + datalen); + + if (datalen > AFSTOKEN_LENGTH_MAX) + goto not_xdr; + + /* XDR is an array of __be32's */ + if (datalen & 3) + goto not_xdr; + + /* the flags should be 0 (the setpag bit must be handled by + * userspace) */ + if (ntohl(*xdr++) != 0) + goto not_xdr; + datalen -= 4; + + /* check the cell name */ + len = ntohl(*xdr++); + if (len < 1 || len > AFSTOKEN_CELL_MAX) + goto not_xdr; + datalen -= 4; + tmp = (len + 3) & ~3; + if (tmp > datalen) + goto not_xdr; + + cp = (const char *) xdr; + for (loop = 0; loop < len; loop++) + if (!isprint(cp[loop])) + goto not_xdr; + if (len < tmp) + for (; loop < tmp; loop++) + if (cp[loop]) + goto not_xdr; + _debug("cellname: [%u/%u] '%*.*s'", + len, tmp, len, len, (const char *) xdr); + datalen -= tmp; + xdr += tmp >> 2; + + /* get the token count */ + if (datalen < 12) + goto not_xdr; + ntoken = ntohl(*xdr++); + datalen -= 4; + _debug("ntoken: %x", ntoken); + if (ntoken < 1 || ntoken > AFSTOKEN_MAX) + goto not_xdr; + + /* check each token wrapper */ + token = xdr; + loop = ntoken; + do { + if (datalen < 8) + goto not_xdr; + toklen = ntohl(*xdr++); + sec_ix = ntohl(*xdr); + datalen -= 4; + _debug("token: [%x/%zx] %x", toklen, datalen, sec_ix); + if (toklen < 20 || toklen > datalen) + goto not_xdr; + datalen -= (toklen + 3) & ~3; + xdr += (toklen + 3) >> 2; + + } while (--loop > 0); + + _debug("remainder: %zu", datalen); + if (datalen != 0) + goto not_xdr; + + /* okay: we're going to assume it's valid XDR format + * - we ignore the cellname, relying on the key to be correctly named + */ + do { + xdr = token; + toklen = ntohl(*xdr++); + token = xdr + ((toklen + 3) >> 2); + sec_ix = ntohl(*xdr++); + toklen -= 4; + + _debug("TOKEN type=%u [%p-%p]", sec_ix, xdr, token); + + switch (sec_ix) { + case RXRPC_SECURITY_RXKAD: + ret = rxrpc_instantiate_xdr_rxkad(key, xdr, toklen); + if (ret != 0) + goto error; + break; + + case RXRPC_SECURITY_RXK5: + ret = rxrpc_instantiate_xdr_rxk5(key, xdr, toklen); + if (ret != 0) + goto error; + break; + + default: + ret = -EPROTONOSUPPORT; + goto error; + } + + } while (--ntoken > 0); + + _leave(" = 0"); + return 0; + +not_xdr: + _leave(" = -EPROTO"); + return -EPROTO; +error: + _leave(" = %d", ret); + return ret; +} + +/* * instantiate an rxrpc defined key * data should be of the form: * OFFSET LEN CONTENT @@ -70,8 +662,8 @@ struct key_type key_type_rxrpc_s = { */ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen) { - const struct rxkad_key *tsec; - struct rxrpc_key_payload *upayload; + const struct rxrpc_key_data_v1 *v1; + struct rxrpc_key_token *token, **pp; size_t plen; u32 kver; int ret; @@ -82,6 +674,13 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen) if (!data && datalen == 0) return 0; + /* determine if the XDR payload format is being used */ + if (datalen > 7 * 4) { + ret = rxrpc_instantiate_xdr(key, data, datalen); + if (ret != -EPROTO) + return ret; + } + /* get the key interface version number */ ret = -EINVAL; if (datalen <= 4 || !data) @@ -98,53 +697,67 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen) /* deal with a version 1 key */ ret = -EINVAL; - if (datalen < sizeof(*tsec)) + if (datalen < sizeof(*v1)) goto error; - tsec = data; - if (datalen != sizeof(*tsec) + tsec->ticket_len) + v1 = data; + if (datalen != sizeof(*v1) + v1->ticket_length) goto error; - _debug("SCIX: %u", tsec->security_index); - _debug("TLEN: %u", tsec->ticket_len); - _debug("EXPY: %x", tsec->expiry); - _debug("KVNO: %u", tsec->kvno); + _debug("SCIX: %u", v1->security_index); + _debug("TLEN: %u", v1->ticket_length); + _debug("EXPY: %x", v1->expiry); + _debug("KVNO: %u", v1->kvno); _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x", - tsec->session_key[0], tsec->session_key[1], - tsec->session_key[2], tsec->session_key[3], - tsec->session_key[4], tsec->session_key[5], - tsec->session_key[6], tsec->session_key[7]); - if (tsec->ticket_len >= 8) + v1->session_key[0], v1->session_key[1], + v1->session_key[2], v1->session_key[3], + v1->session_key[4], v1->session_key[5], + v1->session_key[6], v1->session_key[7]); + if (v1->ticket_length >= 8) _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x", - tsec->ticket[0], tsec->ticket[1], - tsec->ticket[2], tsec->ticket[3], - tsec->ticket[4], tsec->ticket[5], - tsec->ticket[6], tsec->ticket[7]); + v1->ticket[0], v1->ticket[1], + v1->ticket[2], v1->ticket[3], + v1->ticket[4], v1->ticket[5], + v1->ticket[6], v1->ticket[7]); ret = -EPROTONOSUPPORT; - if (tsec->security_index != 2) + if (v1->security_index != RXRPC_SECURITY_RXKAD) goto error; - key->type_data.x[0] = tsec->security_index; - - plen = sizeof(*upayload) + tsec->ticket_len; - ret = key_payload_reserve(key, plen); + plen = sizeof(*token->kad) + v1->ticket_length; + ret = key_payload_reserve(key, plen + sizeof(*token)); if (ret < 0) goto error; ret = -ENOMEM; - upayload = kmalloc(plen, GFP_KERNEL); - if (!upayload) + token = kmalloc(sizeof(*token), GFP_KERNEL); + if (!token) goto error; + token->kad = kmalloc(plen, GFP_KERNEL); + if (!token->kad) + goto error_free; + + token->security_index = RXRPC_SECURITY_RXKAD; + token->kad->ticket_len = v1->ticket_length; + token->kad->expiry = v1->expiry; + token->kad->kvno = v1->kvno; + memcpy(&token->kad->session_key, &v1->session_key, 8); + memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length); /* attach the data */ - memcpy(&upayload->k, tsec, sizeof(*tsec)); - memcpy(&upayload->k.ticket, (void *)tsec + sizeof(*tsec), - tsec->ticket_len); - key->payload.data = upayload; - key->expiry = tsec->expiry; + key->type_data.x[0]++; + + pp = (struct rxrpc_key_token **)&key->payload.data; + while (*pp) + pp = &(*pp)->next; + *pp = token; + if (token->kad->expiry < key->expiry) + key->expiry = token->kad->expiry; + token = NULL; ret = 0; +error_free: + kfree(token); error: return ret; } @@ -184,7 +797,26 @@ static int rxrpc_instantiate_s(struct key *key, const void *data, */ static void rxrpc_destroy(struct key *key) { - kfree(key->payload.data); + struct rxrpc_key_token *token; + + while ((token = key->payload.data)) { + key->payload.data = token->next; + switch (token->security_index) { + case RXRPC_SECURITY_RXKAD: + kfree(token->kad); + break; + case RXRPC_SECURITY_RXK5: + if (token->k5) + rxrpc_rxk5_free(token->k5); + break; + default: + printk(KERN_ERR "Unknown token type %x on rxrpc key\n", + token->security_index); + BUG(); + } + + kfree(token); + } } /* @@ -293,7 +925,7 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn, struct { u32 kver; - struct rxkad_key tsec; + struct rxrpc_key_data_v1 v1; } data; _enter(""); @@ -308,13 +940,12 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn, _debug("key %d", key_serial(key)); data.kver = 1; - data.tsec.security_index = 2; - data.tsec.ticket_len = 0; - data.tsec.expiry = expiry; - data.tsec.kvno = 0; + data.v1.security_index = RXRPC_SECURITY_RXKAD; + data.v1.ticket_length = 0; + data.v1.expiry = expiry; + data.v1.kvno = 0; - memcpy(&data.tsec.session_key, session_key, - sizeof(data.tsec.session_key)); + memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key)); ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL); if (ret < 0) @@ -360,3 +991,210 @@ struct key *rxrpc_get_null_key(const char *keyname) return key; } EXPORT_SYMBOL(rxrpc_get_null_key); + +/* + * read the contents of an rxrpc key + * - this returns the result in XDR form + */ +static long rxrpc_read(const struct key *key, + char __user *buffer, size_t buflen) +{ + const struct rxrpc_key_token *token; + const struct krb5_principal *princ; + size_t size; + __be32 __user *xdr, *oldxdr; + u32 cnlen, toksize, ntoks, tok, zero; + u16 toksizes[AFSTOKEN_MAX]; + int loop; + + _enter(""); + + /* we don't know what form we should return non-AFS keys in */ + if (memcmp(key->description, "afs@", 4) != 0) + return -EOPNOTSUPP; + cnlen = strlen(key->description + 4); + +#define RND(X) (((X) + 3) & ~3) + + /* AFS keys we return in XDR form, so we need to work out the size of + * the XDR */ + size = 2 * 4; /* flags, cellname len */ + size += RND(cnlen); /* cellname */ + size += 1 * 4; /* token count */ + + ntoks = 0; + for (token = key->payload.data; token; token = token->next) { + toksize = 4; /* sec index */ + + switch (token->security_index) { + case RXRPC_SECURITY_RXKAD: + toksize += 8 * 4; /* viceid, kvno, key*2, begin, + * end, primary, tktlen */ + toksize += RND(token->kad->ticket_len); + break; + + case RXRPC_SECURITY_RXK5: + princ = &token->k5->client; + toksize += 4 + princ->n_name_parts * 4; + for (loop = 0; loop < princ->n_name_parts; loop++) + toksize += RND(strlen(princ->name_parts[loop])); + toksize += 4 + RND(strlen(princ->realm)); + + princ = &token->k5->server; + toksize += 4 + princ->n_name_parts * 4; + for (loop = 0; loop < princ->n_name_parts; loop++) + toksize += RND(strlen(princ->name_parts[loop])); + toksize += 4 + RND(strlen(princ->realm)); + + toksize += 8 + RND(token->k5->session.data_len); + + toksize += 4 * 8 + 2 * 4; + + toksize += 4 + token->k5->n_addresses * 8; + for (loop = 0; loop < token->k5->n_addresses; loop++) + toksize += RND(token->k5->addresses[loop].data_len); + + toksize += 4 + RND(token->k5->ticket_len); + toksize += 4 + RND(token->k5->ticket2_len); + + toksize += 4 + token->k5->n_authdata * 8; + for (loop = 0; loop < token->k5->n_authdata; loop++) + toksize += RND(token->k5->authdata[loop].data_len); + break; + + default: /* we have a ticket we can't encode */ + BUG(); + continue; + } + + _debug("token[%u]: toksize=%u", ntoks, toksize); + ASSERTCMP(toksize, <=, AFSTOKEN_LENGTH_MAX); + + toksizes[ntoks++] = toksize; + size += toksize + 4; /* each token has a length word */ + } + +#undef RND + + if (!buffer || buflen < size) + return size; + + xdr = (__be32 __user *) buffer; + zero = 0; +#define ENCODE(x) \ + do { \ + __be32 y = htonl(x); \ + if (put_user(y, xdr++) < 0) \ + goto fault; \ + } while(0) +#define ENCODE_DATA(l, s) \ + do { \ + u32 _l = (l); \ + ENCODE(l); \ + if (copy_to_user(xdr, (s), _l) != 0) \ + goto fault; \ + if (_l & 3 && \ + copy_to_user((u8 *)xdr + _l, &zero, 4 - (_l & 3)) != 0) \ + goto fault; \ + xdr += (_l + 3) >> 2; \ + } while(0) +#define ENCODE64(x) \ + do { \ + __be64 y = cpu_to_be64(x); \ + if (copy_to_user(xdr, &y, 8) != 0) \ + goto fault; \ + xdr += 8 >> 2; \ + } while(0) +#define ENCODE_STR(s) \ + do { \ + const char *_s = (s); \ + ENCODE_DATA(strlen(_s), _s); \ + } while(0) + + ENCODE(0); /* flags */ + ENCODE_DATA(cnlen, key->description + 4); /* cellname */ + ENCODE(ntoks); + + tok = 0; + for (token = key->payload.data; token; token = token->next) { + toksize = toksizes[tok++]; + ENCODE(toksize); + oldxdr = xdr; + ENCODE(token->security_index); + + switch (token->security_index) { + case RXRPC_SECURITY_RXKAD: + ENCODE(token->kad->vice_id); + ENCODE(token->kad->kvno); + ENCODE_DATA(8, token->kad->session_key); + ENCODE(token->kad->start); + ENCODE(token->kad->expiry); + ENCODE(token->kad->primary_flag); + ENCODE_DATA(token->kad->ticket_len, token->kad->ticket); + break; + + case RXRPC_SECURITY_RXK5: + princ = &token->k5->client; + ENCODE(princ->n_name_parts); + for (loop = 0; loop < princ->n_name_parts; loop++) + ENCODE_STR(princ->name_parts[loop]); + ENCODE_STR(princ->realm); + + princ = &token->k5->server; + ENCODE(princ->n_name_parts); + for (loop = 0; loop < princ->n_name_parts; loop++) + ENCODE_STR(princ->name_parts[loop]); + ENCODE_STR(princ->realm); + + ENCODE(token->k5->session.tag); + ENCODE_DATA(token->k5->session.data_len, + token->k5->session.data); + + ENCODE64(token->k5->authtime); + ENCODE64(token->k5->starttime); + ENCODE64(token->k5->endtime); + ENCODE64(token->k5->renew_till); + ENCODE(token->k5->is_skey); + ENCODE(token->k5->flags); + + ENCODE(token->k5->n_addresses); + for (loop = 0; loop < token->k5->n_addresses; loop++) { + ENCODE(token->k5->addresses[loop].tag); + ENCODE_DATA(token->k5->addresses[loop].data_len, + token->k5->addresses[loop].data); + } + + ENCODE_DATA(token->k5->ticket_len, token->k5->ticket); + ENCODE_DATA(token->k5->ticket2_len, token->k5->ticket2); + + ENCODE(token->k5->n_authdata); + for (loop = 0; loop < token->k5->n_authdata; loop++) { + ENCODE(token->k5->authdata[loop].tag); + ENCODE_DATA(token->k5->authdata[loop].data_len, + token->k5->authdata[loop].data); + } + break; + + default: + BUG(); + break; + } + + ASSERTCMP((unsigned long)xdr - (unsigned long)oldxdr, ==, + toksize); + } + +#undef ENCODE_STR +#undef ENCODE_DATA +#undef ENCODE64 +#undef ENCODE + + ASSERTCMP(tok, ==, ntoks); + ASSERTCMP((char __user *) xdr - buffer, ==, size); + _leave(" = %zu", size); + return size; + +fault: + _leave(" = -EFAULT"); + return -EFAULT; +} diff --git a/net/rxrpc/ar-security.c b/net/rxrpc/ar-security.c index dc62920ee19..49b3cc31ee1 100644 --- a/net/rxrpc/ar-security.c +++ b/net/rxrpc/ar-security.c @@ -16,6 +16,7 @@ #include <linux/crypto.h> #include <net/sock.h> #include <net/af_rxrpc.h> +#include <keys/rxrpc-type.h> #include "ar-internal.h" static LIST_HEAD(rxrpc_security_methods); @@ -122,6 +123,7 @@ EXPORT_SYMBOL_GPL(rxrpc_unregister_security); */ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn) { + struct rxrpc_key_token *token; struct rxrpc_security *sec; struct key *key = conn->key; int ret; @@ -135,7 +137,11 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn) if (ret < 0) return ret; - sec = rxrpc_security_lookup(key->type_data.x[0]); + if (!key->payload.data) + return -EKEYREJECTED; + token = key->payload.data; + + sec = rxrpc_security_lookup(token->security_index); if (!sec) return -EKEYREJECTED; conn->security = sec; diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c index ef8f91030a1..713ac593e2e 100644 --- a/net/rxrpc/rxkad.c +++ b/net/rxrpc/rxkad.c @@ -18,6 +18,7 @@ #include <linux/ctype.h> #include <net/sock.h> #include <net/af_rxrpc.h> +#include <keys/rxrpc-type.h> #define rxrpc_debug rxkad_debug #include "ar-internal.h" @@ -42,7 +43,7 @@ struct rxkad_level2_hdr { __be32 checksum; /* decrypted data checksum */ }; -MODULE_DESCRIPTION("RxRPC network protocol type-2 security (Kerberos)"); +MODULE_DESCRIPTION("RxRPC network protocol type-2 security (Kerberos 4)"); MODULE_AUTHOR("Red Hat, Inc."); MODULE_LICENSE("GPL"); @@ -59,14 +60,14 @@ static DEFINE_MUTEX(rxkad_ci_mutex); */ static int rxkad_init_connection_security(struct rxrpc_connection *conn) { - struct rxrpc_key_payload *payload; struct crypto_blkcipher *ci; + struct rxrpc_key_token *token; int ret; _enter("{%d},{%x}", conn->debug_id, key_serial(conn->key)); - payload = conn->key->payload.data; - conn->security_ix = payload->k.security_index; + token = conn->key->payload.data; + conn->security_ix = token->security_index; ci = crypto_alloc_blkcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(ci)) { @@ -75,8 +76,8 @@ static int rxkad_init_connection_security(struct rxrpc_connection *conn) goto error; } - if (crypto_blkcipher_setkey(ci, payload->k.session_key, - sizeof(payload->k.session_key)) < 0) + if (crypto_blkcipher_setkey(ci, token->kad->session_key, + sizeof(token->kad->session_key)) < 0) BUG(); switch (conn->security_level) { @@ -110,7 +111,7 @@ error: */ static void rxkad_prime_packet_security(struct rxrpc_connection *conn) { - struct rxrpc_key_payload *payload; + struct rxrpc_key_token *token; struct blkcipher_desc desc; struct scatterlist sg[2]; struct rxrpc_crypt iv; @@ -123,8 +124,8 @@ static void rxkad_prime_packet_security(struct rxrpc_connection *conn) if (!conn->key) return; - payload = conn->key->payload.data; - memcpy(&iv, payload->k.session_key, sizeof(iv)); + token = conn->key->payload.data; + memcpy(&iv, token->kad->session_key, sizeof(iv)); desc.tfm = conn->cipher; desc.info = iv.x; @@ -197,7 +198,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, u32 data_size, void *sechdr) { - const struct rxrpc_key_payload *payload; + const struct rxrpc_key_token *token; struct rxkad_level2_hdr rxkhdr __attribute__((aligned(8))); /* must be all on one page */ struct rxrpc_skb_priv *sp; @@ -219,8 +220,8 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, rxkhdr.checksum = 0; /* encrypt from the session key */ - payload = call->conn->key->payload.data; - memcpy(&iv, payload->k.session_key, sizeof(iv)); + token = call->conn->key->payload.data; + memcpy(&iv, token->kad->session_key, sizeof(iv)); desc.tfm = call->conn->cipher; desc.info = iv.x; desc.flags = 0; @@ -400,7 +401,7 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call, struct sk_buff *skb, u32 *_abort_code) { - const struct rxrpc_key_payload *payload; + const struct rxrpc_key_token *token; struct rxkad_level2_hdr sechdr; struct rxrpc_skb_priv *sp; struct blkcipher_desc desc; @@ -431,8 +432,8 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call, skb_to_sgvec(skb, sg, 0, skb->len); /* decrypt from the session key */ - payload = call->conn->key->payload.data; - memcpy(&iv, payload->k.session_key, sizeof(iv)); + token = call->conn->key->payload.data; + memcpy(&iv, token->kad->session_key, sizeof(iv)); desc.tfm = call->conn->cipher; desc.info = iv.x; desc.flags = 0; @@ -506,7 +507,7 @@ static int rxkad_verify_packet(const struct rxrpc_call *call, if (!call->conn->cipher) return 0; - if (sp->hdr.securityIndex != 2) { + if (sp->hdr.securityIndex != RXRPC_SECURITY_RXKAD) { *_abort_code = RXKADINCONSISTENCY; _leave(" = -EPROTO [not rxkad]"); return -EPROTO; @@ -737,7 +738,7 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn, struct sk_buff *skb, u32 *_abort_code) { - const struct rxrpc_key_payload *payload; + const struct rxrpc_key_token *token; struct rxkad_challenge challenge; struct rxkad_response resp __attribute__((aligned(8))); /* must be aligned for crypto */ @@ -778,7 +779,7 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn, if (conn->security_level < min_level) goto protocol_error; - payload = conn->key->payload.data; + token = conn->key->payload.data; /* build the response packet */ memset(&resp, 0, sizeof(resp)); @@ -797,13 +798,13 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn, (conn->channels[3] ? conn->channels[3]->call_id : 0); resp.encrypted.inc_nonce = htonl(nonce + 1); resp.encrypted.level = htonl(conn->security_level); - resp.kvno = htonl(payload->k.kvno); - resp.ticket_len = htonl(payload->k.ticket_len); + resp.kvno = htonl(token->kad->kvno); + resp.ticket_len = htonl(token->kad->ticket_len); /* calculate the response checksum and then do the encryption */ rxkad_calc_response_checksum(&resp); - rxkad_encrypt_response(conn, &resp, &payload->k); - return rxkad_send_response(conn, &sp->hdr, &resp, &payload->k); + rxkad_encrypt_response(conn, &resp, token->kad); + return rxkad_send_response(conn, &sp->hdr, &resp, token->kad); protocol_error: *_abort_code = abort_code; @@ -1122,7 +1123,7 @@ static void rxkad_clear(struct rxrpc_connection *conn) static struct rxrpc_security rxkad = { .owner = THIS_MODULE, .name = "rxkad", - .security_index = RXKAD_VERSION, + .security_index = RXRPC_SECURITY_RXKAD, .init_connection_security = rxkad_init_connection_security, .prime_packet_security = rxkad_prime_packet_security, .secure_packet = rxkad_secure_packet, diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 692d9a41cd2..903e4188b6c 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -693,13 +693,18 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, if (new && i > 0) atomic_inc(&new->refcnt); - qdisc_destroy(old); + if (!ingress) + qdisc_destroy(old); } - notify_and_destroy(skb, n, classid, dev->qdisc, new); - if (new && !new->ops->attach) - atomic_inc(&new->refcnt); - dev->qdisc = new ? : &noop_qdisc; + if (!ingress) { + notify_and_destroy(skb, n, classid, dev->qdisc, new); + if (new && !new->ops->attach) + atomic_inc(&new->refcnt); + dev->qdisc = new ? : &noop_qdisc; + } else { + notify_and_destroy(skb, n, classid, old, new); + } if (dev->flags & IFF_UP) dev_activate(dev); @@ -804,7 +809,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue, stab = qdisc_get_stab(tca[TCA_STAB]); if (IS_ERR(stab)) { err = PTR_ERR(stab); - goto err_out3; + goto err_out4; } sch->stab = stab; } @@ -833,7 +838,6 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue, return sch; } err_out3: - qdisc_put_stab(sch->stab); dev_put(dev); kfree((char *) sch - sch->padded); err_out2: @@ -847,6 +851,7 @@ err_out4: * Any broken qdiscs that would require a ops->reset() here? * The qdisc was never in action so it shouldn't be necessary. */ + qdisc_put_stab(sch->stab); if (ops->destroy) ops->destroy(sch); goto err_out3; @@ -1111,12 +1116,16 @@ create_n_graft: tcm->tcm_parent, tcm->tcm_parent, tca, &err); else { - unsigned int ntx = 0; + struct netdev_queue *dev_queue; if (p && p->ops->cl_ops && p->ops->cl_ops->select_queue) - ntx = p->ops->cl_ops->select_queue(p, tcm); + dev_queue = p->ops->cl_ops->select_queue(p, tcm); + else if (p) + dev_queue = p->dev_queue; + else + dev_queue = netdev_get_tx_queue(dev, 0); - q = qdisc_create(dev, netdev_get_tx_queue(dev, ntx), p, + q = qdisc_create(dev, dev_queue, p, tcm->tcm_parent, tcm->tcm_handle, tca, &err); } diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index 12b2fb04b29..5a888af7e5d 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c @@ -274,8 +274,10 @@ static int drr_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct tc_drr_stats xstats; memset(&xstats, 0, sizeof(xstats)); - if (cl->qdisc->q.qlen) + if (cl->qdisc->q.qlen) { xstats.deficit = cl->deficit; + cl->qdisc->qstats.qlen = cl->qdisc->q.qlen; + } if (gnet_stats_copy_basic(d, &cl->bstats) < 0 || gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 || diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c index dd5ee022f1f..d1dea3d5dc9 100644 --- a/net/sched/sch_mq.c +++ b/net/sched/sch_mq.c @@ -125,13 +125,18 @@ static struct netdev_queue *mq_queue_get(struct Qdisc *sch, unsigned long cl) return netdev_get_tx_queue(dev, ntx); } -static unsigned int mq_select_queue(struct Qdisc *sch, struct tcmsg *tcm) +static struct netdev_queue *mq_select_queue(struct Qdisc *sch, + struct tcmsg *tcm) { unsigned int ntx = TC_H_MIN(tcm->tcm_parent); + struct netdev_queue *dev_queue = mq_queue_get(sch, ntx); - if (!mq_queue_get(sch, ntx)) - return 0; - return ntx - 1; + if (!dev_queue) { + struct net_device *dev = qdisc_dev(sch); + + return netdev_get_tx_queue(dev, 0); + } + return dev_queue; } static int mq_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new, @@ -188,6 +193,7 @@ static int mq_dump_class_stats(struct Qdisc *sch, unsigned long cl, struct netdev_queue *dev_queue = mq_queue_get(sch, cl); sch = dev_queue->qdisc_sleeping; + sch->qstats.qlen = sch->q.qlen; if (gnet_stats_copy_basic(d, &sch->bstats) < 0 || gnet_stats_copy_queue(d, &sch->qstats) < 0) return -1; diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c index 069f81c9727..7db2c88ce58 100644 --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c @@ -359,6 +359,7 @@ static int multiq_dump_class_stats(struct Qdisc *sch, unsigned long cl, struct Qdisc *cl_q; cl_q = q->queues[cl - 1]; + cl_q->qstats.qlen = cl_q->q.qlen; if (gnet_stats_copy_basic(d, &cl_q->bstats) < 0 || gnet_stats_copy_queue(d, &cl_q->qstats) < 0) return -1; diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 0f73c412d04..93285cecb24 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -322,6 +322,7 @@ static int prio_dump_class_stats(struct Qdisc *sch, unsigned long cl, struct Qdisc *cl_q; cl_q = q->queues[cl - 1]; + cl_q->qstats.qlen = cl_q->q.qlen; if (gnet_stats_copy_basic(d, &cl_q->bstats) < 0 || gnet_stats_copy_queue(d, &cl_q->qstats) < 0) return -1; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 6a4b1909414..bb280e60e00 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -949,7 +949,7 @@ static int sctp6_rcv(struct sk_buff *skb) return sctp_rcv(skb) ? -1 : 0; } -static struct inet6_protocol sctpv6_protocol = { +static const struct inet6_protocol sctpv6_protocol = { .handler = sctp6_rcv, .err_handler = sctp_v6_err, .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL, diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 60093be8385..c557f1fb1c6 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -924,7 +924,7 @@ static struct inet_protosw sctp_stream_protosw = { }; /* Register with IP layer. */ -static struct net_protocol sctp_protocol = { +static const struct net_protocol sctp_protocol = { .handler = sctp_rcv, .err_handler = sctp_v4_err, .no_policy = 1, diff --git a/net/socket.c b/net/socket.c index 6d471655904..2a022c00d85 100644 --- a/net/socket.c +++ b/net/socket.c @@ -489,6 +489,7 @@ static struct socket *sock_alloc(void) sock = SOCKET_I(inode); + kmemcheck_annotate_bitfield(sock, type); inode->i_mode = S_IFSOCK | S_IRWXUGO; inode->i_uid = current_fsuid(); inode->i_gid = current_fsgid(); diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 4c210c2debc..e5f92ee758f 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -662,7 +662,7 @@ int cfg80211_wext_siwscan(struct net_device *dev, int k; int wiphy_freq = wiphy->bands[band]->channels[j].center_freq; for (k = 0; k < wreq->num_channels; k++) { - int wext_freq = wreq->channel_list[k].m / 100000; + int wext_freq = cfg80211_wext_freq(wiphy, &wreq->channel_list[k]); if (wext_freq == wiphy_freq) goto wext_freq_found; } @@ -675,6 +675,11 @@ int cfg80211_wext_siwscan(struct net_device *dev, wext_freq_not_found: ; } } + /* No channels found? */ + if (!i) { + err = -EINVAL; + goto out; + } /* Set real number of channels specified in creq->channels[] */ creq->n_channels = i; diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 68307883ec8..7fae7eee65d 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -188,7 +188,7 @@ void cfg80211_conn_work(struct work_struct *work) rtnl_unlock(); } -static bool cfg80211_get_conn_bss(struct wireless_dev *wdev) +static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) { struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); struct cfg80211_bss *bss; @@ -205,7 +205,7 @@ static bool cfg80211_get_conn_bss(struct wireless_dev *wdev) WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY, capa); if (!bss) - return false; + return NULL; memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN); wdev->conn->params.bssid = wdev->conn->bssid; @@ -213,14 +213,14 @@ static bool cfg80211_get_conn_bss(struct wireless_dev *wdev) wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; schedule_work(&rdev->conn_work); - cfg80211_put_bss(bss); - return true; + return bss; } static void __cfg80211_sme_scan_done(struct net_device *dev) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); + struct cfg80211_bss *bss; ASSERT_WDEV_LOCK(wdev); @@ -234,7 +234,10 @@ static void __cfg80211_sme_scan_done(struct net_device *dev) wdev->conn->state != CFG80211_CONN_SCAN_AGAIN) return; - if (!cfg80211_get_conn_bss(wdev)) { + bss = cfg80211_get_conn_bss(wdev); + if (bss) { + cfg80211_put_bss(bss); + } else { /* not found */ if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN) schedule_work(&rdev->conn_work); @@ -670,6 +673,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, { struct wireless_dev *wdev = dev->ieee80211_ptr; struct ieee80211_channel *chan; + struct cfg80211_bss *bss = NULL; int err; ASSERT_WDEV_LOCK(wdev); @@ -760,7 +764,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, /* don't care about result -- but fill bssid & channel */ if (!wdev->conn->params.bssid || !wdev->conn->params.channel) - cfg80211_get_conn_bss(wdev); + bss = cfg80211_get_conn_bss(wdev); wdev->sme_state = CFG80211_SME_CONNECTING; wdev->connect_keys = connkeys; @@ -770,10 +774,11 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, wdev->conn->prev_bssid_valid = true; } - /* we're good if we have both BSSID and channel */ - if (wdev->conn->params.bssid && wdev->conn->params.channel) { + /* we're good if we have a matching bss struct */ + if (bss) { wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; err = cfg80211_conn_do_work(wdev); + cfg80211_put_bss(bss); } else { /* otherwise we'll need to scan for the AP first */ err = cfg80211_conn_scan(wdev); diff --git a/scripts/Makefile b/scripts/Makefile index 9dd5b25a1d5..842dbc2d5ae 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -10,7 +10,6 @@ hostprogs-$(CONFIG_KALLSYMS) += kallsyms hostprogs-$(CONFIG_LOGO) += pnmtologo hostprogs-$(CONFIG_VT) += conmakehash -hostprogs-$(CONFIG_PROM_CONSOLE) += conmakehash hostprogs-$(CONFIG_IKCONFIG) += bin2c always := $(hostprogs-y) $(hostprogs-m) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7ed47f66ddd..12960581956 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7927,8 +7927,9 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = { static struct snd_kcontrol_new alc883_targa_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), @@ -7947,8 +7948,9 @@ static struct snd_kcontrol_new alc883_targa_mixer[] = { static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -7960,6 +7962,15 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { + HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + { } /* end */ +}; + static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), @@ -9167,7 +9178,8 @@ static struct alc_config_preset alc882_presets[] = { .init_hook = alc882_targa_automute, }, [ALC883_TARGA_8ch_DIG] = { - .mixers = { alc883_base_mixer, alc883_chmode_mixer }, + .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer, + alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, alc883_targa_verbs }, .num_dacs = ARRAY_SIZE(alc883_dac_nids), @@ -13370,7 +13382,8 @@ static const char *alc269_models[ALC269_MODEL_LAST] = { [ALC269_ASUS_EEEPC_P703] = "eeepc-p703", [ALC269_ASUS_EEEPC_P901] = "eeepc-p901", [ALC269_FUJITSU] = "fujitsu", - [ALC269_LIFEBOOK] = "lifebook" + [ALC269_LIFEBOOK] = "lifebook", + [ALC269_AUTO] = "auto", }; static struct snd_pci_quirk alc269_cfg_tbl[] = { diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index e31e53dc696..826137ec300 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -864,10 +864,6 @@ static struct hda_verb stac92hd73xx_core_init[] = { }; static struct hda_verb stac92hd83xxx_core_init[] = { - { 0xa, AC_VERB_SET_CONNECT_SEL, 0x1}, - { 0xb, AC_VERB_SET_CONNECT_SEL, 0x1}, - { 0xd, AC_VERB_SET_CONNECT_SEL, 0x0}, - /* power state controls amps */ { 0x01, AC_VERB_SET_EAPD, 1 << 2}, {} @@ -1590,8 +1586,8 @@ static unsigned int ref92hd83xxx_pin_configs[10] = { }; static unsigned int dell_s14_pin_configs[10] = { - 0x02214030, 0x02211010, 0x02a19020, 0x01014050, - 0x40f000f0, 0x01819040, 0x40f000f0, 0x90a60160, + 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110, + 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160, 0x40f000f0, 0x40f000f0, }; @@ -1690,6 +1686,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { "HP mini 1000", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b, "HP HDX", STAC_HP_HDX), /* HDX16 */ + SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620, + "HP dv6", STAC_HP_DV5), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, "HP", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, @@ -4166,7 +4164,10 @@ static int stac92xx_init(struct hda_codec *codec) stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], AC_PINCTL_OUT_EN); /* fake event to set up pins */ - stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]); + if (cfg->hp_pins[0]) + stac_issue_unsol_event(codec, cfg->hp_pins[0]); + else if (cfg->line_out_pins[0]) + stac_issue_unsol_event(codec, cfg->line_out_pins[0]); } else { stac92xx_auto_init_multi_out(codec); stac92xx_auto_init_hp_out(codec); @@ -4688,8 +4689,13 @@ static int stac92xx_resume(struct hda_codec *codec) snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); /* fake event to set up pins again to override cached values */ - if (spec->hp_detect) - stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]); + if (spec->hp_detect) { + if (spec->autocfg.hp_pins[0]) + stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]); + else if (spec->autocfg.line_out_pins[0]) + stac_issue_unsol_event(codec, + spec->autocfg.line_out_pins[0]); + } return 0; } @@ -5016,7 +5022,7 @@ again: spec->eapd_switch = 1; break; } - if (spec->board_config > STAC_92HD73XX_REF) { + if (spec->board_config != STAC_92HD73XX_REF) { /* GPIO0 High = Enable EAPD */ spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; spec->gpio_data = 0x01; @@ -5066,7 +5072,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) codec->spec = spec; codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; - spec->mono_nid = 0x19; spec->digbeep_nid = 0x21; spec->mux_nids = stac92hd83xxx_mux_nids; spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids); @@ -5242,7 +5247,7 @@ again: stac92xx_set_config_regs(codec, stac92hd71bxx_brd_tbl[spec->board_config]); - if (spec->board_config > STAC_92HD71BXX_REF) { + if (spec->board_config != STAC_92HD71BXX_REF) { /* GPIO0 = EAPD */ spec->gpio_mask = 0x01; spec->gpio_dir = 0x01; @@ -5375,6 +5380,11 @@ again: case STAC_HP_DV5: snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); + /* HP dv6 gives the headphone pin as a line-out. Thus we + * need to set hp_detect flag here to force to enable HP + * detection. + */ + spec->hp_detect = 1; break; case STAC_HP_HDX: spec->num_dmics = 1; @@ -5557,14 +5567,17 @@ static int patch_stac927x(struct hda_codec *codec) spec->dac_list = stac927x_dac_nids; spec->multiout.dac_nids = spec->dac_nids; + if (spec->board_config != STAC_D965_REF) { + /* GPIO0 High = Enable EAPD */ + spec->eapd_mask = spec->gpio_mask = 0x01; + spec->gpio_dir = spec->gpio_data = 0x01; + } + switch (spec->board_config) { case STAC_D965_3ST: case STAC_D965_5ST: /* GPIO0 High = Enable EAPD */ - spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x01; - spec->gpio_data = 0x01; spec->num_dmics = 0; - spec->init = d965_core_init; break; case STAC_DELL_BIOS: @@ -5583,16 +5596,11 @@ static int patch_stac927x(struct hda_codec *codec) snd_hda_codec_set_pincfg(codec, 0x0e, 0x02a79130); /* fallthru */ case STAC_DELL_3ST: - /* GPIO2 High = Enable EAPD */ - spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x04; - spec->gpio_data = 0x04; - switch (codec->subsystem_id) { - case 0x1028022f: - /* correct EAPD to be GPIO0 */ - spec->eapd_mask = spec->gpio_mask = 0x01; - spec->gpio_dir = spec->gpio_data = 0x01; - break; - }; + if (codec->subsystem_id != 0x1028022f) { + /* GPIO2 High = Enable EAPD */ + spec->eapd_mask = spec->gpio_mask = 0x04; + spec->gpio_dir = spec->gpio_data = 0x04; + } spec->dmic_nids = stac927x_dmic_nids; spec->num_dmics = STAC927X_NUM_DMICS; @@ -5601,14 +5609,9 @@ static int patch_stac927x(struct hda_codec *codec) spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); break; default: - if (spec->board_config > STAC_D965_REF) { - /* GPIO0 High = Enable EAPD */ - spec->eapd_mask = spec->gpio_mask = 0x01; - spec->gpio_dir = spec->gpio_data = 0x01; - } spec->num_dmics = 0; - spec->init = stac927x_core_init; + break; } spec->num_caps = STAC927X_NUM_CAPS; diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 3612bb92df9..01343dc984f 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -18,7 +18,6 @@ #include <linux/init.h> #include <linux/module.h> -#include <linux/version.h> #include <linux/kernel.h> #include <linux/device.h> #include <sound/core.h> diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c index e62b27701a4..9a049a1995a 100644 --- a/sound/soc/codecs/ad1938.c +++ b/sound/soc/codecs/ad1938.c @@ -28,7 +28,6 @@ #include <linux/init.h> #include <linux/module.h> -#include <linux/version.h> #include <linux/kernel.h> #include <linux/device.h> #include <sound/core.h> diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index d8a013ab317..98d663afc97 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -12,7 +12,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> -#include <linux/version.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/delay.h> diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index 9ff62e3a9b1..6096d22283e 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -447,6 +447,7 @@ int mpc5200_audio_dma_create(struct of_device *op) int size, irq, rc; const __be32 *prop; void __iomem *regs; + int ret; /* Fetch the registers and IRQ of the PSC */ irq = irq_of_parse_and_map(op->node, 0); @@ -463,14 +464,16 @@ int mpc5200_audio_dma_create(struct of_device *op) /* Allocate and initialize the driver private data */ psc_dma = kzalloc(sizeof *psc_dma, GFP_KERNEL); if (!psc_dma) { - iounmap(regs); - return -ENOMEM; + ret = -ENOMEM; + goto out_unmap; } /* Get the PSC ID */ prop = of_get_property(op->node, "cell-index", &size); - if (!prop || size < sizeof *prop) - return -ENODEV; + if (!prop || size < sizeof *prop) { + ret = -ENODEV; + goto out_free; + } spin_lock_init(&psc_dma->lock); mutex_init(&psc_dma->mutex); @@ -493,9 +496,8 @@ int mpc5200_audio_dma_create(struct of_device *op) if (!psc_dma->capture.bcom_task || !psc_dma->playback.bcom_task) { dev_err(&op->dev, "Could not allocate bestcomm tasks\n"); - iounmap(regs); - kfree(psc_dma); - return -ENODEV; + ret = -ENODEV; + goto out_free; } /* Disable all interrupts and reset the PSC */ @@ -537,12 +539,8 @@ int mpc5200_audio_dma_create(struct of_device *op) &psc_dma_bcom_irq_tx, IRQF_SHARED, "psc-dma-playback", &psc_dma->playback); if (rc) { - free_irq(psc_dma->irq, psc_dma); - free_irq(psc_dma->capture.irq, - &psc_dma->capture); - free_irq(psc_dma->playback.irq, - &psc_dma->playback); - return -ENODEV; + ret = -ENODEV; + goto out_irq; } /* Save what we've done so it can be found again later */ @@ -550,6 +548,15 @@ int mpc5200_audio_dma_create(struct of_device *op) /* Tell the ASoC OF helpers about it */ return snd_soc_register_platform(&mpc5200_audio_dma_platform); +out_irq: + free_irq(psc_dma->irq, psc_dma); + free_irq(psc_dma->capture.irq, &psc_dma->capture); + free_irq(psc_dma->playback.irq, &psc_dma->playback); +out_free: + kfree(psc_dma); +out_unmap: + iounmap(regs); + return ret; } EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create); diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index aa7af0b8d42..9bc4aa35caa 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -230,6 +230,8 @@ static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); } +#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) + /* * Wait for the LR signal to allow synchronisation to the L/R clock * from the codec. May only be needed for slave mode. @@ -237,19 +239,21 @@ static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s) { u32 iiscon; - unsigned long timeout = jiffies + msecs_to_jiffies(5); + unsigned long loops = msecs_to_loops(5); pr_debug("Entered %s\n", __func__); - while (1) { + while (--loops) { iiscon = readl(i2s->regs + S3C2412_IISCON); if (iiscon & S3C2412_IISCON_LRINDEX) break; - if (timeout < jiffies) { - printk(KERN_ERR "%s: timeout\n", __func__); - return -ETIMEDOUT; - } + cpu_relax(); + } + + if (!loops) { + printk(KERN_ERR "%s: timeout\n", __func__); + return -ETIMEDOUT; } return 0; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 0d8b08ef873..f79711b9fa5 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1131,9 +1131,10 @@ static ssize_t dapm_widget_power_read_file(struct file *file, ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d\n", w->name, w->power ? "On" : "Off", in, out); - if (w->active && w->sname) - ret += snprintf(buf, PAGE_SIZE - ret, " stream %s active\n", - w->sname); + if (w->sname) + ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n", + w->sname, + w->active ? "active" : "inactive"); list_for_each_entry(p, &w->sources, list_sink) { if (p->connect) |