source:
clfs-embedded/patches/linux-2.6.30.5-openwrt-bcm47xx-fixes-1.patch@
b71d8ca
Last change on this file since b71d8ca was ffc7663, checked in by , 15 years ago | |
---|---|
|
|
File size: 103.8 KB |
-
arch/mips/Kconfig
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 25f3b0a..868126c 100644
a b config BCM47XX 53 53 select SSB_DRIVER_MIPS 54 54 select SSB_DRIVER_EXTIF 55 55 select SSB_EMBEDDED 56 select SSB_B43_PCI_BRIDGE if PCI 56 57 select SSB_PCICORE_HOSTMODE if PCI 57 58 select GENERIC_GPIO 58 select SYS_HAS_EARLY_PRINTK59 59 select CFE 60 60 help 61 61 Support for BCM47XX based boards … … config MIPS_MALTA 195 195 select I8259 196 196 select MIPS_BOARDS_GEN 197 197 select MIPS_BONITO64 198 select MIPS_CPU_SCACHE199 198 select PCI_GT64XXX_PCI0 200 199 select MIPS_MSC 201 200 select SWAP_IO_SPACE … … config IP22_CPU_SCACHE 1455 1454 bool 1456 1455 select BOARD_SCACHE 1457 1456 1458 #1459 # Support for a MIPS32 / MIPS64 style S-caches1460 #1461 config MIPS_CPU_SCACHE1462 bool1463 select BOARD_SCACHE1464 1465 1457 config R5000_CPU_SCACHE 1466 1458 bool 1467 1459 select BOARD_SCACHE -
arch/mips/bcm47xx/Makefile
diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile index 35294b1..9e62430 100644
a b 3 3 # under Linux. 4 4 # 5 5 6 obj-y := gpio.o irq.o prom.o serial.o setup.o time.o wgt634u.o6 obj-y := cfe_env.o gpio.o irq.o nvram.o prom.o serial.o setup.o time.o -
new file arch/mips/bcm47xx/cfe_env.c
diff --git a/arch/mips/bcm47xx/cfe_env.c b/arch/mips/bcm47xx/cfe_env.c new file mode 100644 index 0000000..c1d5eee
- + 1 /* 2 * CFE environment variable access 3 * 4 * Copyright 2001-2003, Broadcom Corporation 5 * Copyright 2006, Felix Fietkau <nbd@openwrt.org> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2 of the License, or (at your 10 * option) any later version. 11 */ 12 13 #include <linux/init.h> 14 #include <linux/module.h> 15 #include <linux/kernel.h> 16 #include <linux/string.h> 17 #include <asm/io.h> 18 #include <asm/uaccess.h> 19 20 #define NVRAM_SIZE (0x1ff0) 21 static char _nvdata[NVRAM_SIZE]; 22 static char _valuestr[256]; 23 24 /* 25 * TLV types. These codes are used in the "type-length-value" 26 * encoding of the items stored in the NVRAM device (flash or EEPROM) 27 * 28 * The layout of the flash/nvram is as follows: 29 * 30 * <type> <length> <data ...> <type> <length> <data ...> <type_end> 31 * 32 * The type code of "ENV_TLV_TYPE_END" marks the end of the list. 33 * The "length" field marks the length of the data section, not 34 * including the type and length fields. 35 * 36 * Environment variables are stored as follows: 37 * 38 * <type_env> <length> <flags> <name> = <value> 39 * 40 * If bit 0 (low bit) is set, the length is an 8-bit value. 41 * If bit 0 (low bit) is clear, the length is a 16-bit value 42 * 43 * Bit 7 set indicates "user" TLVs. In this case, bit 0 still 44 * indicates the size of the length field. 45 * 46 * Flags are from the constants below: 47 * 48 */ 49 #define ENV_LENGTH_16BITS 0x00 /* for low bit */ 50 #define ENV_LENGTH_8BITS 0x01 51 52 #define ENV_TYPE_USER 0x80 53 54 #define ENV_CODE_SYS(n,l) (((n)<<1)|(l)) 55 #define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER) 56 57 /* 58 * The actual TLV types we support 59 */ 60 61 #define ENV_TLV_TYPE_END 0x00 62 #define ENV_TLV_TYPE_ENV ENV_CODE_SYS(0,ENV_LENGTH_8BITS) 63 64 /* 65 * Environment variable flags 66 */ 67 68 #define ENV_FLG_NORMAL 0x00 /* normal read/write */ 69 #define ENV_FLG_BUILTIN 0x01 /* builtin - not stored in flash */ 70 #define ENV_FLG_READONLY 0x02 /* read-only - cannot be changed */ 71 72 #define ENV_FLG_MASK 0xFF /* mask of attributes we keep */ 73 #define ENV_FLG_ADMIN 0x100 /* lets us internally override permissions */ 74 75 76 /* ********************************************************************* 77 * _nvram_read(buffer,offset,length) 78 * 79 * Read data from the NVRAM device 80 * 81 * Input parameters: 82 * buffer - destination buffer 83 * offset - offset of data to read 84 * length - number of bytes to read 85 * 86 * Return value: 87 * number of bytes read, or <0 if error occured 88 ********************************************************************* */ 89 static int 90 _nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length) 91 { 92 int i; 93 if (offset > NVRAM_SIZE) 94 return -1; 95 96 for ( i = 0; i < length; i++) { 97 buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i]; 98 } 99 return length; 100 } 101 102 103 static char* 104 _strnchr(const char *dest,int c,size_t cnt) 105 { 106 while (*dest && (cnt > 0)) { 107 if (*dest == c) return (char *) dest; 108 dest++; 109 cnt--; 110 } 111 return NULL; 112 } 113 114 115 116 /* 117 * Core support API: Externally visible. 118 */ 119 120 /* 121 * Get the value of an NVRAM variable 122 * @param name name of variable to get 123 * @return value of variable or NULL if undefined 124 */ 125 126 char* 127 cfe_env_get(unsigned char *nv_buf, char* name) 128 { 129 int size; 130 unsigned char *buffer; 131 unsigned char *ptr; 132 unsigned char *envval; 133 unsigned int reclen; 134 unsigned int rectype; 135 int offset; 136 int flg; 137 138 if (!strcmp(name, "nvram_type")) 139 return "cfe"; 140 141 size = NVRAM_SIZE; 142 buffer = &_nvdata[0]; 143 144 ptr = buffer; 145 offset = 0; 146 147 /* Read the record type and length */ 148 if (_nvram_read(nv_buf, ptr,offset,1) != 1) { 149 goto error; 150 } 151 152 while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) { 153 154 /* Adjust pointer for TLV type */ 155 rectype = *(ptr); 156 offset++; 157 size--; 158 159 /* 160 * Read the length. It can be either 1 or 2 bytes 161 * depending on the code 162 */ 163 if (rectype & ENV_LENGTH_8BITS) { 164 /* Read the record type and length - 8 bits */ 165 if (_nvram_read(nv_buf, ptr,offset,1) != 1) { 166 goto error; 167 } 168 reclen = *(ptr); 169 size--; 170 offset++; 171 } 172 else { 173 /* Read the record type and length - 16 bits, MSB first */ 174 if (_nvram_read(nv_buf, ptr,offset,2) != 2) { 175 goto error; 176 } 177 reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1); 178 size -= 2; 179 offset += 2; 180 } 181 182 if (reclen > size) 183 break; /* should not happen, bad NVRAM */ 184 185 switch (rectype) { 186 case ENV_TLV_TYPE_ENV: 187 /* Read the TLV data */ 188 if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen) 189 goto error; 190 flg = *ptr++; 191 envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1)); 192 if (envval) { 193 *envval++ = '\0'; 194 memcpy(_valuestr,envval,(reclen-1)-(envval-ptr)); 195 _valuestr[(reclen-1)-(envval-ptr)] = '\0'; 196 #if 0 197 printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr); 198 #endif 199 if(!strcmp(ptr, name)){ 200 return _valuestr; 201 } 202 if((strlen(ptr) > 1) && !strcmp(&ptr[1], name)) 203 return _valuestr; 204 } 205 break; 206 207 default: 208 /* Unknown TLV type, skip it. */ 209 break; 210 } 211 212 /* 213 * Advance to next TLV 214 */ 215 216 size -= (int)reclen; 217 offset += reclen; 218 219 /* Read the next record type */ 220 ptr = buffer; 221 if (_nvram_read(nv_buf, ptr,offset,1) != 1) 222 goto error; 223 } 224 225 error: 226 return NULL; 227 228 } 229 -
new file arch/mips/bcm47xx/include/nvram.h
diff --git a/arch/mips/bcm47xx/include/nvram.h b/arch/mips/bcm47xx/include/nvram.h new file mode 100644 index 0000000..6bb18e8
- + 1 /* 2 * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License as published by the 6 * Free Software Foundation; either version 2 of the License, or (at your 7 * option) any later version. 8 */ 9 10 #ifndef __NVRAM_H 11 #define __NVRAM_H 12 13 struct nvram_header { 14 u32 magic; 15 u32 len; 16 u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ 17 u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ 18 u32 config_ncdl; /* ncdl values for memc */ 19 }; 20 21 struct nvram_tuple { 22 char *name; 23 char *value; 24 struct nvram_tuple *next; 25 }; 26 27 #define NVRAM_HEADER 0x48534C46 /* 'FLSH' */ 28 #define NVRAM_VERSION 1 29 #define NVRAM_HEADER_SIZE 20 30 #define NVRAM_SPACE 0x8000 31 32 #define NVRAM_MAX_VALUE_LEN 255 33 #define NVRAM_MAX_PARAM_LEN 64 34 35 char *nvram_get(const char *name); 36 37 #endif -
arch/mips/bcm47xx/irq.c
diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c index 325757a..f087cf6 100644
a b 1 1 /* 2 2 * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> 3 * Copyright (C) 2008 Michael Buesch <mb@bu3sch.de> 3 4 * 4 5 * This program is free software; you can redistribute it and/or modify it 5 6 * under the terms of the GNU General Public License as published by the … … 23 24 */ 24 25 25 26 #include <linux/types.h> 27 #include <linux/errno.h> 28 #include <linux/init.h> 26 29 #include <linux/interrupt.h> 27 30 #include <linux/irq.h> 31 #include <linux/pci.h> 32 #include <linux/ssb/ssb.h> 33 28 34 #include <asm/irq_cpu.h> 29 35 36 37 extern struct ssb_bus ssb_bcm47xx; 38 39 30 40 void plat_irq_dispatch(void) 31 41 { 32 42 u32 cause; -
new file arch/mips/bcm47xx/nvram.c
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c new file mode 100644 index 0000000..71a2106
- + 1 /* 2 * BCM947xx nvram variable access 3 * 4 * Copyright 2005, Broadcom Corporation 5 * Copyright 2006, Felix Fietkau <nbd@openwrt.org> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2 of the License, or (at your 10 * option) any later version. 11 */ 12 13 #include <linux/init.h> 14 #include <linux/module.h> 15 #include <linux/ssb/ssb.h> 16 #include <linux/kernel.h> 17 #include <linux/string.h> 18 #include <linux/interrupt.h> 19 #include <linux/spinlock.h> 20 #include <linux/slab.h> 21 #include <asm/byteorder.h> 22 #include <asm/bootinfo.h> 23 #include <asm/addrspace.h> 24 #include <asm/io.h> 25 #include <asm/uaccess.h> 26 27 #include "include/nvram.h" 28 29 #define MB * 1048576 30 extern struct ssb_bus ssb_bcm47xx; 31 32 static char nvram_buf[NVRAM_SPACE]; 33 static int cfe_env; 34 extern char *cfe_env_get(char *nv_buf, const char *name); 35 36 /* Probe for NVRAM header */ 37 static void __init early_nvram_init(void) 38 { 39 struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore; 40 struct nvram_header *header; 41 int i; 42 u32 base, lim, off; 43 u32 *src, *dst; 44 45 base = mcore->flash_window; 46 lim = mcore->flash_window_size; 47 cfe_env = 0; 48 49 50 /* XXX: hack for supporting the CFE environment stuff on WGT634U */ 51 if (lim >= 8 MB) { 52 src = (u32 *) KSEG1ADDR(base + 8 MB - 0x2000); 53 dst = (u32 *) nvram_buf; 54 55 if ((*src & 0xff00ff) == 0x000001) { 56 printk("early_nvram_init: WGT634U NVRAM found.\n"); 57 58 for (i = 0; i < 0x1ff0; i++) { 59 if (*src == 0xFFFFFFFF) 60 break; 61 *dst++ = *src++; 62 } 63 cfe_env = 1; 64 return; 65 } 66 } 67 68 off = 0x20000; 69 while (off <= lim) { 70 /* Windowed flash access */ 71 header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE); 72 if (header->magic == NVRAM_HEADER) 73 goto found; 74 off <<= 1; 75 } 76 77 /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ 78 header = (struct nvram_header *) KSEG1ADDR(base + 4096); 79 if (header->magic == NVRAM_HEADER) 80 goto found; 81 82 header = (struct nvram_header *) KSEG1ADDR(base + 1024); 83 if (header->magic == NVRAM_HEADER) 84 goto found; 85 86 return; 87 88 found: 89 src = (u32 *) header; 90 dst = (u32 *) nvram_buf; 91 for (i = 0; i < sizeof(struct nvram_header); i += 4) 92 *dst++ = *src++; 93 for (; i < header->len && i < NVRAM_SPACE; i += 4) 94 *dst++ = le32_to_cpu(*src++); 95 } 96 97 char *nvram_get(const char *name) 98 { 99 char *var, *value, *end, *eq; 100 101 if (!name) 102 return NULL; 103 104 if (!nvram_buf[0]) 105 early_nvram_init(); 106 107 if (cfe_env) 108 return cfe_env_get(nvram_buf, name); 109 110 /* Look for name=value and return value */ 111 var = &nvram_buf[sizeof(struct nvram_header)]; 112 end = nvram_buf + sizeof(nvram_buf) - 2; 113 end[0] = end[1] = '\0'; 114 for (; *var; var = value + strlen(value) + 1) { 115 if (!(eq = strchr(var, '='))) 116 break; 117 value = eq + 1; 118 if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0) 119 return value; 120 } 121 122 return NULL; 123 } 124 125 EXPORT_SYMBOL(nvram_get); -
arch/mips/bcm47xx/prom.c
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c index 079e33d..75132cf 100644
a b 32 32 #include <asm/fw/cfe/cfe_error.h> 33 33 34 34 static int cfe_cons_handle; 35 static void (* __prom_putchar)(char c); 35 36 36 37 const char *get_system_type(void) 37 38 { … … const char *get_system_type(void) 40 41 41 42 void prom_putchar(char c) 42 43 { 44 if (__prom_putchar) 45 __prom_putchar(c); 46 } 47 48 void prom_putchar_cfe(char c) 49 { 43 50 while (cfe_write(cfe_cons_handle, &c, 1) == 0) 44 51 ; 45 52 } 46 53 47 static __init voidprom_init_cfe(void)54 static __init int prom_init_cfe(void) 48 55 { 49 56 uint32_t cfe_ept; 50 57 uint32_t cfe_handle; 51 58 uint32_t cfe_eptseal; 52 int argc = fw_arg0;53 char **envp = (char **) fw_arg2;54 int *prom_vec = (int *) fw_arg3;55 59 56 /* 57 * Check if a loader was used; if NOT, the 4 arguments are 58 * what CFE gives us (handle, 0, EPT and EPTSEAL) 59 */ 60 if (argc < 0) { 61 cfe_handle = (uint32_t)argc; 62 cfe_ept = (uint32_t)envp; 63 cfe_eptseal = (uint32_t)prom_vec; 64 } else { 65 if ((int)prom_vec < 0) { 66 /* 67 * Old loader; all it gives us is the handle, 68 * so use the "known" entrypoint and assume 69 * the seal. 70 */ 71 cfe_handle = (uint32_t)prom_vec; 72 cfe_ept = 0xBFC00500; 73 cfe_eptseal = CFE_EPTSEAL; 74 } else { 75 /* 76 * Newer loaders bundle the handle/ept/eptseal 77 * Note: prom_vec is in the loader's useg 78 * which is still alive in the TLB. 79 */ 80 cfe_handle = prom_vec[0]; 81 cfe_ept = prom_vec[2]; 82 cfe_eptseal = prom_vec[3]; 83 } 84 } 60 cfe_eptseal = (uint32_t) fw_arg3; 61 cfe_handle = (uint32_t) fw_arg0; 62 cfe_ept = (uint32_t) fw_arg2; 85 63 86 if (cfe_eptseal != CFE_EPTSEAL) { 87 /* too early for panic to do any good */ 88 printk(KERN_ERR "CFE's entrypoint seal doesn't match."); 89 while (1) ; 90 } 64 if (cfe_eptseal != CFE_EPTSEAL) 65 return -1; 91 66 92 67 cfe_init(cfe_handle, cfe_ept); 68 return 0; 93 69 } 94 70 95 static __init void prom_init_console (void)71 static __init void prom_init_console_cfe(void) 96 72 { 97 73 /* Initialize CFE console */ 98 74 cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); 99 75 } 100 76 101 static __init void prom_init_cmdline (void)77 static __init void prom_init_cmdline_cfe(void) 102 78 { 103 79 char buf[CL_SIZE]; 104 80 … … static __init void prom_init_mem(void) 146 122 147 123 void __init prom_init(void) 148 124 { 149 prom_init_cfe(); 150 prom_init_console(); 151 prom_init_cmdline(); 125 if (prom_init_cfe() == 0) { 126 //prom_init_console_cfe(); 127 //prom_init_cmdline_cfe(); 128 __prom_putchar = prom_putchar_cfe; 129 } 130 152 131 prom_init_mem(); 153 132 } 154 133 -
arch/mips/bcm47xx/setup.c
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 2f580fa..0a7bd49 100644
a b 2 2 * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> 3 3 * Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org> 4 4 * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> 5 * Copyright (C) 2006 Michael Buesch <mb@bu3sch.de>5 * Copyright (C) 2006-2008 Michael Buesch <mb@bu3sch.de> 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify it 8 8 * under the terms of the GNU General Public License as published by the … … 25 25 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 26 */ 27 27 28 #include <linux/init.h> 28 29 #include <linux/types.h> 29 30 #include <linux/ssb/ssb.h> 30 31 #include <linux/ssb/ssb_embedded.h> 32 #include <linux/tty.h> 33 #include <linux/serial.h> 34 #include <linux/serial_core.h> 35 #include <linux/serial_reg.h> 36 #include <linux/serial_8250.h> 31 37 #include <asm/bootinfo.h> 32 38 #include <asm/reboot.h> 33 39 #include <asm/time.h> 34 #include <bcm47xx.h>35 40 #include <asm/fw/cfe/cfe_api.h> 41 #include <linux/pm.h> 42 43 #include "include/nvram.h" 36 44 37 45 struct ssb_bus ssb_bcm47xx; 38 46 EXPORT_SYMBOL(ssb_bcm47xx); 39 47 48 extern void bcm47xx_pci_init(void); 49 40 50 static void bcm47xx_machine_restart(char *command) 41 51 { 42 52 printk(KERN_ALERT "Please stand by while rebooting the system...\n"); … … static void bcm47xx_machine_halt(void) 56 66 cpu_relax(); 57 67 } 58 68 59 static void str2eaddr(char *str, char *dest)69 static void e_aton(char *str, char *dest) 60 70 { 61 71 int i = 0; 62 72 … … static void str2eaddr(char *str, char *dest) 73 83 } 74 84 } 75 85 76 static int bcm47xx_get_invariants(struct ssb_bus *bus, 77 struct ssb_init_invariants *iv) 86 static void bcm47xx_fill_sprom(struct ssb_sprom *sprom) 87 { 88 char *s; 89 90 memset(sprom, 0xFF, sizeof(struct ssb_sprom)); 91 92 sprom->revision = 1; 93 if ((s = nvram_get("il0macaddr"))) 94 e_aton(s, sprom->il0mac); 95 if ((s = nvram_get("et0macaddr"))) 96 e_aton(s, sprom->et0mac); 97 if ((s = nvram_get("et1macaddr"))) 98 e_aton(s, sprom->et1mac); 99 if ((s = nvram_get("et0phyaddr"))) 100 sprom->et0phyaddr = simple_strtoul(s, NULL, 0); 101 if ((s = nvram_get("et1phyaddr"))) 102 sprom->et1phyaddr = simple_strtoul(s, NULL, 0); 103 if ((s = nvram_get("et0mdcport"))) 104 sprom->et0mdcport = !!simple_strtoul(s, NULL, 10); 105 if ((s = nvram_get("et1mdcport"))) 106 sprom->et1mdcport = !!simple_strtoul(s, NULL, 10); 107 if ((s = nvram_get("pa0b0"))) 108 sprom->pa0b0 = simple_strtoul(s, NULL, 0); 109 if ((s = nvram_get("pa0b1"))) 110 sprom->pa0b1 = simple_strtoul(s, NULL, 0); 111 if ((s = nvram_get("pa0b2"))) 112 sprom->pa0b2 = simple_strtoul(s, NULL, 0); 113 if ((s = nvram_get("pa1b0"))) 114 sprom->pa1b0 = simple_strtoul(s, NULL, 0); 115 if ((s = nvram_get("pa1b1"))) 116 sprom->pa1b1 = simple_strtoul(s, NULL, 0); 117 if ((s = nvram_get("pa1b2"))) 118 sprom->pa1b2 = simple_strtoul(s, NULL, 0); 119 if ((s = nvram_get("wl0gpio0"))) 120 sprom->gpio0 = simple_strtoul(s, NULL, 0); 121 if ((s = nvram_get("wl0gpio1"))) 122 sprom->gpio1 = simple_strtoul(s, NULL, 0); 123 if ((s = nvram_get("wl0gpio2"))) 124 sprom->gpio2 = simple_strtoul(s, NULL, 0); 125 if ((s = nvram_get("wl0gpio3"))) 126 sprom->gpio3 = simple_strtoul(s, NULL, 0); 127 if ((s = nvram_get("pa0maxpwr"))) 128 sprom->maxpwr_bg = simple_strtoul(s, NULL, 0); 129 if ((s = nvram_get("pa1maxpwr"))) 130 sprom->maxpwr_a = simple_strtoul(s, NULL, 0); 131 if ((s = nvram_get("pa0itssit"))) 132 sprom->itssi_bg = simple_strtoul(s, NULL, 0); 133 if ((s = nvram_get("pa1itssit"))) 134 sprom->itssi_a = simple_strtoul(s, NULL, 0); 135 sprom->boardflags_lo = 0; 136 if ((s = nvram_get("boardflags"))) 137 sprom->boardflags_lo = simple_strtoul(s, NULL, 0); 138 sprom->boardflags_hi = 0; 139 if ((s = nvram_get("boardflags2"))) 140 sprom->boardflags_hi = simple_strtoul(s, NULL, 0); 141 } 142 143 static int bcm47xx_get_invariants(struct ssb_bus *bus, struct ssb_init_invariants *iv) 78 144 { 79 char buf[100]; 80 81 /* Fill boardinfo structure */ 82 memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo)); 83 84 if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0) 85 iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); 86 if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0) 87 iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); 88 if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0) 89 iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0); 90 91 /* Fill sprom structure */ 92 memset(&(iv->sprom), 0, sizeof(struct ssb_sprom)); 93 iv->sprom.revision = 3; 94 95 if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0) 96 str2eaddr(buf, iv->sprom.et0mac); 97 if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0) 98 str2eaddr(buf, iv->sprom.et1mac); 99 if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0) 100 iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 10); 101 if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0) 102 iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 10); 103 if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0) 104 iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10); 105 if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0) 106 iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10); 145 char *s; 146 147 iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM; 148 if ((s = nvram_get("boardtype"))) 149 iv->boardinfo.type = (u16)simple_strtoul(s, NULL, 0); 150 if ((s = nvram_get("boardrev"))) 151 iv->boardinfo.rev = (u16)simple_strtoul(s, NULL, 0); 152 153 bcm47xx_fill_sprom(&iv->sprom); 154 155 if ((s = nvram_get("cardbus"))) 156 iv->has_cardbus_slot = !!simple_strtoul(s, NULL, 10); 107 157 108 158 return 0; 109 159 } 110 160 111 161 void __init plat_mem_setup(void) 112 162 { 113 int err; 163 int i, err; 164 char *s; 165 struct ssb_mipscore *mcore; 166 167 err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, bcm47xx_get_invariants); 168 if (err) { 169 const char *msg = "Failed to initialize SSB bus (err %d)\n"; 170 printk(msg, err); /* Make sure the message gets out of the box. */ 171 panic(msg, err); 172 } 173 mcore = &ssb_bcm47xx.mipscore; 114 174 115 err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, 116 bcm47xx_get_invariants); 117 if (err) 118 panic("Failed to initialize SSB bus (err %d)\n", err); 175 s = nvram_get("kernel_args"); 176 if (s && !strncmp(s, "console=ttyS1", 13)) { 177 struct ssb_serial_port port; 178 179 printk("Swapping serial ports!\n"); 180 /* swap serial ports */ 181 memcpy(&port, &mcore->serial_ports[0], sizeof(port)); 182 memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1], sizeof(port)); 183 memcpy(&mcore->serial_ports[1], &port, sizeof(port)); 184 } 185 186 for (i = 0; i < mcore->nr_serial_ports; i++) { 187 struct ssb_serial_port *port = &(mcore->serial_ports[i]); 188 struct uart_port s; 189 190 memset(&s, 0, sizeof(s)); 191 s.line = i; 192 s.mapbase = (unsigned int) port->regs; 193 s.membase = port->regs; 194 s.irq = port->irq + 2; 195 s.uartclk = port->baud_base; 196 s.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; 197 s.iotype = SERIAL_IO_MEM; 198 s.regshift = port->reg_shift; 199 200 early_serial_setup(&s); 201 } 202 printk("Serial init done.\n"); 119 203 120 204 _machine_restart = bcm47xx_machine_restart; 121 205 _machine_halt = bcm47xx_machine_halt; 122 206 pm_power_off = bcm47xx_machine_halt; 123 207 } 124 208 209 static int __init bcm47xx_register_gpiodev(void) 210 { 211 static struct resource res = { 212 .start = 0xFFFFFFFF, 213 }; 214 struct platform_device *pdev; 215 216 pdev = platform_device_register_simple("GPIODEV", 0, &res, 1); 217 if (!pdev) { 218 printk(KERN_ERR "bcm47xx: GPIODEV init failed\n"); 219 return -ENODEV; 220 } 221 222 return 0; 223 } 224 device_initcall(bcm47xx_register_gpiodev); -
arch/mips/bcm47xx/time.c
diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c index 0c6f47b..08c23ad 100644
a b 22 22 * 675 Mass Ave, Cambridge, MA 02139, USA. 23 23 */ 24 24 25 26 25 #include <linux/init.h> 26 #include <linux/kernel.h> 27 #include <linux/sched.h> 28 #include <linux/serial_reg.h> 29 #include <linux/interrupt.h> 27 30 #include <linux/ssb/ssb.h> 31 #include <asm/addrspace.h> 32 #include <asm/io.h> 28 33 #include <asm/time.h> 29 #include <bcm47xx.h> 34 35 extern struct ssb_bus ssb_bcm47xx; 30 36 31 37 void __init plat_time_init(void) 32 38 { -
deleted file rch/mips/bcm47xx/wgt634u.c
diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c deleted file mode 100644 index ef00e7f..0000000
+ - 1 /*2 * This file is subject to the terms and conditions of the GNU General Public3 * License. See the file "COPYING" in the main directory of this archive4 * for more details.5 *6 * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>7 */8 9 #include <linux/platform_device.h>10 #include <linux/module.h>11 #include <linux/leds.h>12 #include <linux/mtd/physmap.h>13 #include <linux/ssb/ssb.h>14 #include <linux/interrupt.h>15 #include <linux/reboot.h>16 #include <linux/gpio.h>17 #include <asm/mach-bcm47xx/bcm47xx.h>18 19 /* GPIO definitions for the WGT634U */20 #define WGT634U_GPIO_LED 321 #define WGT634U_GPIO_RESET 222 #define WGT634U_GPIO_TP1 723 #define WGT634U_GPIO_TP2 624 #define WGT634U_GPIO_TP3 525 #define WGT634U_GPIO_TP4 426 #define WGT634U_GPIO_TP5 127 28 static struct gpio_led wgt634u_leds[] = {29 {30 .name = "power",31 .gpio = WGT634U_GPIO_LED,32 .active_low = 1,33 .default_trigger = "heartbeat",34 },35 };36 37 static struct gpio_led_platform_data wgt634u_led_data = {38 .num_leds = ARRAY_SIZE(wgt634u_leds),39 .leds = wgt634u_leds,40 };41 42 static struct platform_device wgt634u_gpio_leds = {43 .name = "leds-gpio",44 .id = -1,45 .dev = {46 .platform_data = &wgt634u_led_data,47 }48 };49 50 51 /* 8MiB flash. The struct mtd_partition matches original Netgear WGT634U52 firmware. */53 static struct mtd_partition wgt634u_partitions[] = {54 {55 .name = "cfe",56 .offset = 0,57 .size = 0x60000, /* 384k */58 .mask_flags = MTD_WRITEABLE /* force read-only */59 },60 {61 .name = "config",62 .offset = 0x60000,63 .size = 0x20000 /* 128k */64 },65 {66 .name = "linux",67 .offset = 0x80000,68 .size = 0x140000 /* 1280k */69 },70 {71 .name = "jffs",72 .offset = 0x1c0000,73 .size = 0x620000 /* 6272k */74 },75 {76 .name = "nvram",77 .offset = 0x7e0000,78 .size = 0x20000 /* 128k */79 },80 };81 82 static struct physmap_flash_data wgt634u_flash_data = {83 .parts = wgt634u_partitions,84 .nr_parts = ARRAY_SIZE(wgt634u_partitions)85 };86 87 static struct resource wgt634u_flash_resource = {88 .flags = IORESOURCE_MEM,89 };90 91 static struct platform_device wgt634u_flash = {92 .name = "physmap-flash",93 .id = 0,94 .dev = { .platform_data = &wgt634u_flash_data, },95 .resource = &wgt634u_flash_resource,96 .num_resources = 1,97 };98 99 /* Platform devices */100 static struct platform_device *wgt634u_devices[] __initdata = {101 &wgt634u_flash,102 &wgt634u_gpio_leds,103 };104 105 static irqreturn_t gpio_interrupt(int irq, void *ignored)106 {107 int state;108 109 /* Interrupts are shared, check if the current one is110 a GPIO interrupt. */111 if (!ssb_chipco_irq_status(&ssb_bcm47xx.chipco,112 SSB_CHIPCO_IRQ_GPIO))113 return IRQ_NONE;114 115 state = gpio_get_value(WGT634U_GPIO_RESET);116 117 /* Interrupt are level triggered, revert the interrupt polarity118 to clear the interrupt. */119 gpio_polarity(WGT634U_GPIO_RESET, state);120 121 if (!state) {122 printk(KERN_INFO "Reset button pressed");123 ctrl_alt_del();124 }125 126 return IRQ_HANDLED;127 }128 129 static int __init wgt634u_init(void)130 {131 /* There is no easy way to detect that we are running on a WGT634U132 * machine. Use the MAC address as an heuristic. Netgear Inc. has133 * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.134 */135 136 u8 *et0mac = ssb_bcm47xx.sprom.et0mac;137 138 if (et0mac[0] == 0x00 &&139 ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||140 (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {141 struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;142 143 printk(KERN_INFO "WGT634U machine detected.\n");144 145 if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),146 gpio_interrupt, IRQF_SHARED,147 "WGT634U GPIO", &ssb_bcm47xx.chipco)) {148 gpio_direction_input(WGT634U_GPIO_RESET);149 gpio_intmask(WGT634U_GPIO_RESET, 1);150 ssb_chipco_irq_mask(&ssb_bcm47xx.chipco,151 SSB_CHIPCO_IRQ_GPIO,152 SSB_CHIPCO_IRQ_GPIO);153 }154 155 wgt634u_flash_data.width = mcore->flash_buswidth;156 wgt634u_flash_resource.start = mcore->flash_window;157 wgt634u_flash_resource.end = mcore->flash_window158 + mcore->flash_window_size159 - 1;160 return platform_add_devices(wgt634u_devices,161 ARRAY_SIZE(wgt634u_devices));162 } else163 return -ENODEV;164 }165 166 module_init(wgt634u_init);167 -
arch/mips/include/asm/bootinfo.h
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index 610fe3a..35d7d8f 100644
a b 57 57 #define MACH_MIKROTIK_RB532 0 /* Mikrotik RouterBoard 532 */ 58 58 #define MACH_MIKROTIK_RB532A 1 /* Mikrotik RouterBoard 532A */ 59 59 60 /* 61 * Valid machtype for group Broadcom 62 */ 63 #define MACH_GROUP_BRCM 23 /* Broadcom */ 64 #define MACH_BCM47XX 1 /* Broadcom BCM47xx */ 65 60 66 #define CL_SIZE COMMAND_LINE_SIZE 61 67 62 68 extern char *system_type; -
arch/mips/include/asm/cacheflush.h
diff --git a/arch/mips/include/asm/cacheflush.h b/arch/mips/include/asm/cacheflush.h index 03b1d69..517bb16 100644
a b 32 32 extern void (*flush_cache_all)(void); 33 33 extern void (*__flush_cache_all)(void); 34 34 extern void (*flush_cache_mm)(struct mm_struct *mm); 35 #define flush_cache_dup_mm(mm) do { (void) (mm); } while (0)35 #define flush_cache_dup_mm(mm) flush_cache_mm(mm) 36 36 extern void (*flush_cache_range)(struct vm_area_struct *vma, 37 37 unsigned long start, unsigned long end); 38 38 extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); -
arch/mips/include/asm/cpu-features.h
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index c0047f8..e7591aa 100644
a b 104 104 #ifndef cpu_has_pindexed_dcache 105 105 #define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX) 106 106 #endif 107 #ifndef cpu_use_kmap_coherent 108 #define cpu_use_kmap_coherent 1 109 #endif 107 110 108 111 /* 109 112 * I-Cache snoops remote store. This only matters on SMP. Some multiprocessors -
new file arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h
diff --git a/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h new file mode 100644 index 0000000..b4fe0c3
- + 1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) 7 */ 8 #ifndef __ASM_MACH_BCM47XX_CPU_FEATURE_OVERRIDES_H 9 #define __ASM_MACH_BCM47XX_CPU_FEATURE_OVERRIDES_H 10 11 #define cpu_use_kmap_coherent 0 12 13 #endif /* __ASM_MACH_BCM47XX_CPU_FEATURE_OVERRIDES_H */ -
new file arch/mips/include/asm/mach-bcm47xx/kernel-entry-init.h
diff --git a/arch/mips/include/asm/mach-bcm47xx/kernel-entry-init.h b/arch/mips/include/asm/mach-bcm47xx/kernel-entry-init.h new file mode 100644 index 0000000..7df0dc2
- + 1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2005 Embedded Alley Solutions, Inc 7 * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) 8 * Copyright (C) 2006 Michael Buesch 9 */ 10 #ifndef __ASM_MACH_GENERIC_KERNEL_ENTRY_H 11 #define __ASM_MACH_GENERIC_KERNEL_ENTRY_H 12 13 /* Intentionally empty macro, used in head.S. Override in 14 * arch/mips/mach-xxx/kernel-entry-init.h when necessary. 15 */ 16 .macro kernel_entry_setup 17 .endm 18 19 /* 20 * Do SMP slave processor setup necessary before we can savely execute C code. 21 */ 22 .macro smp_slave_setup 23 .endm 24 25 26 #endif /* __ASM_MACH_GENERIC_KERNEL_ENTRY_H */ -
arch/mips/include/asm/page.h
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index 9f946e4..65ccdf2 100644
a b 35 35 #ifndef __ASSEMBLY__ 36 36 37 37 #include <linux/pfn.h> 38 #include <asm/cpu-features.h> 38 39 #include <asm/io.h> 39 40 40 41 extern void build_clear_page(void); … … static inline void clear_user_page(void *addr, unsigned long vaddr, 70 71 flush_data_cache_page((unsigned long)addr); 71 72 } 72 73 73 extern void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, 74 struct page *to); 75 struct vm_area_struct; 76 extern void copy_user_highpage(struct page *to, struct page *from, 77 unsigned long vaddr, struct vm_area_struct *vma); 74 static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, 75 struct page *to) 76 { 77 extern void (*flush_data_cache_page)(unsigned long addr); 78 78 79 #define __HAVE_ARCH_COPY_USER_HIGHPAGE 79 copy_page(vto, vfrom); 80 if (!cpu_has_ic_fills_f_dc || 81 pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK)) 82 flush_data_cache_page((unsigned long)vto); 83 } 80 84 81 85 /* 82 86 * These are used to make use of C type-checking.. -
arch/mips/include/asm/r4kcache.h
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h index 4c140db..befb69e 100644
a b 17 17 #include <asm/cpu-features.h> 18 18 #include <asm/mipsmtregs.h> 19 19 20 #ifdef CONFIG_BCM47XX 21 #include <asm/paccess.h> 22 #include <linux/ssb/ssb.h> 23 #define BCM4710_DUMMY_RREG() bcm4710_dummy_rreg() 24 25 static inline unsigned long bcm4710_dummy_rreg(void) { 26 return (*(volatile unsigned long *)(KSEG1ADDR(SSB_ENUM_BASE + SSB_IMSTATE))); 27 } 28 29 #define BCM4710_FILL_TLB(addr) bcm4710_fill_tlb((void*)(addr)) 30 31 static inline unsigned long bcm4710_fill_tlb(void *addr) { 32 return (*(unsigned long *)addr); 33 } 34 35 #define BCM4710_PROTECTED_FILL_TLB(addr) bcm4710_protected_fill_tlb((void*)(addr)) 36 37 static inline void bcm4710_protected_fill_tlb(void *addr) { 38 unsigned long x; 39 get_dbe(x, (unsigned long *)addr);; 40 } 41 42 #else 43 #define BCM4710_DUMMY_RREG() 44 45 #define BCM4710_FILL_TLB(addr) 46 #define BCM4710_PROTECTED_FILL_TLB(addr) 47 #endif 48 20 49 /* 21 50 * This macro return a properly sign-extended address suitable as base address 22 51 * for indexed cache operations. Two issues here: … … static inline void flush_icache_line_indexed(unsigned long addr) 150 179 static inline void flush_dcache_line_indexed(unsigned long addr) 151 180 { 152 181 __dflush_prologue 182 BCM4710_DUMMY_RREG(); 153 183 cache_op(Index_Writeback_Inv_D, addr); 154 184 __dflush_epilogue 155 185 } … … static inline void flush_icache_line(unsigned long addr) 169 199 static inline void flush_dcache_line(unsigned long addr) 170 200 { 171 201 __dflush_prologue 202 BCM4710_DUMMY_RREG(); 172 203 cache_op(Hit_Writeback_Inv_D, addr); 173 204 __dflush_epilogue 174 205 } … … static inline void flush_dcache_line(unsigned long addr) 176 207 static inline void invalidate_dcache_line(unsigned long addr) 177 208 { 178 209 __dflush_prologue 210 BCM4710_DUMMY_RREG(); 179 211 cache_op(Hit_Invalidate_D, addr); 180 212 __dflush_epilogue 181 213 } … … static inline void flush_scache_line(unsigned long addr) 208 240 */ 209 241 static inline void protected_flush_icache_line(unsigned long addr) 210 242 { 243 BCM4710_DUMMY_RREG(); 211 244 protected_cache_op(Hit_Invalidate_I, addr); 212 245 } 213 246 … … static inline void protected_flush_icache_line(unsigned long addr) 219 252 */ 220 253 static inline void protected_writeback_dcache_line(unsigned long addr) 221 254 { 255 BCM4710_DUMMY_RREG(); 222 256 protected_cache_op(Hit_Writeback_Inv_D, addr); 223 257 } 224 258 … … static inline void invalidate_tcache_page(unsigned long addr) 339 373 : "r" (base), \ 340 374 "i" (op)); 341 375 376 static inline void blast_dcache(void) 377 { 378 unsigned long start = KSEG0; 379 unsigned long dcache_size = current_cpu_data.dcache.waysize * current_cpu_data.dcache.ways; 380 unsigned long end = (start + dcache_size); 381 382 do { 383 BCM4710_DUMMY_RREG(); 384 cache_op(Index_Writeback_Inv_D, start); 385 start += current_cpu_data.dcache.linesz; 386 } while(start < end); 387 } 388 389 static inline void blast_dcache_page(unsigned long page) 390 { 391 unsigned long start = page; 392 unsigned long end = start + PAGE_SIZE; 393 394 BCM4710_FILL_TLB(start); 395 do { 396 BCM4710_DUMMY_RREG(); 397 cache_op(Hit_Writeback_Inv_D, start); 398 start += current_cpu_data.dcache.linesz; 399 } while(start < end); 400 } 401 402 static inline void blast_dcache_page_indexed(unsigned long page) 403 { 404 unsigned long start = page; 405 unsigned long end = start + PAGE_SIZE; 406 unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; 407 unsigned long ws_end = current_cpu_data.dcache.ways << 408 current_cpu_data.dcache.waybit; 409 unsigned long ws, addr; 410 for (ws = 0; ws < ws_end; ws += ws_inc) { 411 start = page + ws; 412 for (addr = start; addr < end; addr += current_cpu_data.dcache.linesz) { 413 BCM4710_DUMMY_RREG(); 414 cache_op(Index_Writeback_Inv_D, addr); 415 } 416 } 417 } 418 419 342 420 /* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */ 343 #define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize ) \421 #define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize, war) \ 344 422 static inline void blast_##pfx##cache##lsize(void) \ 345 423 { \ 346 424 unsigned long start = INDEX_BASE; \ … … static inline void blast_##pfx##cache##lsize(void) \ 352 430 \ 353 431 __##pfx##flush_prologue \ 354 432 \ 433 war \ 355 434 for (ws = 0; ws < ws_end; ws += ws_inc) \ 356 435 for (addr = start; addr < end; addr += lsize * 32) \ 357 436 cache##lsize##_unroll32(addr|ws, indexop); \ … … static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \ 366 445 \ 367 446 __##pfx##flush_prologue \ 368 447 \ 448 war \ 369 449 do { \ 370 450 cache##lsize##_unroll32(start, hitop); \ 371 451 start += lsize * 32; \ … … static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) 384 464 current_cpu_data.desc.waybit; \ 385 465 unsigned long ws, addr; \ 386 466 \ 467 war \ 468 \ 387 469 __##pfx##flush_prologue \ 388 470 \ 389 471 for (ws = 0; ws < ws_end; ws += ws_inc) \ … … static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) 393 475 __##pfx##flush_epilogue \ 394 476 } 395 477 396 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16 )397 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16 )398 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16 )399 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32 )400 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32 )401 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32 )402 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64 )403 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64 )404 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128 )405 406 __BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16 )407 __BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32 )408 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16 )409 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32 )410 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64 )411 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128 )478 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, ) 479 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16, BCM4710_FILL_TLB(start);) 480 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16, ) 481 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32, ) 482 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32, BCM4710_FILL_TLB(start);) 483 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32, ) 484 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, BCM4710_FILL_TLB(start);) 485 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, ) 486 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, ) 487 488 __BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, ) 489 __BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32, ) 490 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16, ) 491 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32, ) 492 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64, ) 493 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128, ) 412 494 413 495 /* build blast_xxx_range, protected_blast_xxx_range */ 414 #define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot ) \496 #define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot, war, war2) \ 415 497 static inline void prot##blast_##pfx##cache##_range(unsigned long start, \ 416 498 unsigned long end) \ 417 499 { \ 418 500 unsigned long lsize = cpu_##desc##_line_size(); \ 419 501 unsigned long addr = start & ~(lsize - 1); \ 420 502 unsigned long aend = (end - 1) & ~(lsize - 1); \ 503 war \ 421 504 \ 422 505 __##pfx##flush_prologue \ 423 506 \ 424 507 while (1) { \ 508 war2 \ 425 509 prot##cache_op(hitop, addr); \ 426 510 if (addr == aend) \ 427 511 break; \ … … static inline void prot##blast_##pfx##cache##_range(unsigned long start, \ 431 515 __##pfx##flush_epilogue \ 432 516 } 433 517 434 __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_ )435 __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_ )436 __BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_ )437 __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, 438 __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, )518 __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_, BCM4710_PROTECTED_FILL_TLB(addr); BCM4710_PROTECTED_FILL_TLB(aend);, BCM4710_DUMMY_RREG();) 519 __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_,, ) 520 __BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_,, ) 521 __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D,, BCM4710_FILL_TLB(addr); BCM4710_FILL_TLB(aend);, BCM4710_DUMMY_RREG();) 522 __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD,,, ) 439 523 /* blast_inv_dcache_range */ 440 __BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, 441 __BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, )524 __BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D,,,BCM4710_DUMMY_RREG();) 525 __BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD,,, ) 442 526 443 527 #endif /* _ASM_R4KCACHE_H */ -
arch/mips/include/asm/stackframe.h
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index db0fa7b..fd23784 100644
a b 426 426 .macro RESTORE_SP_AND_RET 427 427 LONG_L sp, PT_R29(sp) 428 428 .set mips3 429 #ifdef CONFIG_BCM47XX 430 nop 431 nop 432 #endif 429 433 eret 430 434 .set mips0 431 435 .endm -
arch/mips/kernel/cpu-probe.c
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index b13b8eb..8141700 100644
a b static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) 753 753 case PRID_IMP_25KF: 754 754 c->cputype = CPU_25KF; 755 755 __cpu_name[cpu] = "MIPS 25Kc"; 756 /* Probe for L2 cache */ 757 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; 756 758 break; 757 759 case PRID_IMP_34K: 758 760 c->cputype = CPU_34K; -
arch/mips/kernel/genex.S
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 8882e57..e6ddba2 100644
a b 22 22 #include <asm/page.h> 23 23 #include <asm/thread_info.h> 24 24 25 #ifdef CONFIG_BCM47XX 26 # ifdef eret 27 # undef eret 28 # endif 29 # define eret \ 30 .set push; \ 31 .set noreorder; \ 32 nop; \ 33 nop; \ 34 eret; \ 35 .set pop; 36 #endif 37 25 38 #define PANIC_PIC(msg) \ 26 39 .set push; \ 27 40 .set reorder; \ … … NESTED(except_vec1_generic, 0, sp) 52 65 NESTED(except_vec3_generic, 0, sp) 53 66 .set push 54 67 .set noat 68 #ifdef CONFIG_BCM47XX 69 nop 70 #endif 55 71 #if R5432_CP0_INTERRUPT_WAR 56 72 mfc0 k0, CP0_INDEX 57 73 #endif … … NESTED(except_vec3_r4000, 0, sp) 75 91 .set push 76 92 .set mips3 77 93 .set noat 94 #ifdef CONFIG_BCM47XX 95 nop 96 #endif 78 97 mfc0 k1, CP0_CAUSE 79 98 li k0, 31<<2 80 99 andi k1, k1, 0x7c -
arch/mips/mm/Makefile
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index d7ec955..d666c4e 100644
a b obj-$(CONFIG_CPU_CAVIUM_OCTEON) += c-octeon.o cex-oct.o tlb-r4k.o 32 32 obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o 33 33 obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o 34 34 obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o 35 obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o36 35 37 36 EXTRA_CFLAGS += -Werror -
arch/mips/mm/c-r4k.c
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 171951d..258f8ca 100644
a b 34 34 #include <asm/cacheflush.h> /* for run_uncached() */ 35 35 36 36 37 /* For enabling BCM4710 cache workarounds */ 38 int bcm4710 = 0; 39 37 40 /* 38 41 * Special Variant of smp_call_function for use by cache functions: 39 42 * … … static void __cpuinit r4k_blast_dcache_page_setup(void) 104 107 { 105 108 unsigned long dc_lsize = cpu_dcache_line_size(); 106 109 110 if (bcm4710) 111 r4k_blast_dcache_page = blast_dcache_page; 112 else 107 113 if (dc_lsize == 0) 108 114 r4k_blast_dcache_page = (void *)cache_noop; 109 115 else if (dc_lsize == 16) … … static void __cpuinit r4k_blast_dcache_page_indexed_setup(void) 118 124 { 119 125 unsigned long dc_lsize = cpu_dcache_line_size(); 120 126 127 if (bcm4710) 128 r4k_blast_dcache_page_indexed = blast_dcache_page_indexed; 129 else 121 130 if (dc_lsize == 0) 122 131 r4k_blast_dcache_page_indexed = (void *)cache_noop; 123 132 else if (dc_lsize == 16) … … static void __cpuinit r4k_blast_dcache_setup(void) 132 141 { 133 142 unsigned long dc_lsize = cpu_dcache_line_size(); 134 143 144 if (bcm4710) 145 r4k_blast_dcache = blast_dcache; 146 else 135 147 if (dc_lsize == 0) 136 148 r4k_blast_dcache = (void *)cache_noop; 137 149 else if (dc_lsize == 16) … … static inline void local_r4k___flush_cache_all(void * args) 348 360 } 349 361 } 350 362 351 staticvoid r4k___flush_cache_all(void)363 void r4k___flush_cache_all(void) 352 364 { 353 365 r4k_on_each_cpu(local_r4k___flush_cache_all, NULL, 1); 354 366 } … … static inline void local_r4k_flush_cache_page(void *args) 482 494 */ 483 495 map_coherent = (cpu_has_dc_aliases && 484 496 page_mapped(page) && !Page_dcache_dirty(page)); 485 if (map_coherent )497 if (map_coherent && cpu_use_kmap_coherent) 486 498 vaddr = kmap_coherent(page, addr); 487 499 else 488 500 vaddr = kmap_atomic(page, KM_USER0); … … static inline void local_r4k_flush_cache_page(void *args) 505 517 } 506 518 507 519 if (vaddr) { 508 if (map_coherent )520 if (map_coherent && cpu_use_kmap_coherent) 509 521 kunmap_coherent(); 510 522 else 511 523 kunmap_atomic(vaddr, KM_USER0); 512 524 } 513 525 } 514 526 515 staticvoid r4k_flush_cache_page(struct vm_area_struct *vma,527 void r4k_flush_cache_page(struct vm_area_struct *vma, 516 528 unsigned long addr, unsigned long pfn) 517 529 { 518 530 struct flush_cache_page_args args; … … static void local_r4k_flush_cache_sigtramp(void * arg) 667 679 unsigned long addr = (unsigned long) arg; 668 680 669 681 R4600_HIT_CACHEOP_WAR_IMPL; 682 BCM4710_PROTECTED_FILL_TLB(addr); 683 BCM4710_PROTECTED_FILL_TLB(addr + 4); 670 684 if (dc_lsize) 671 685 protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); 672 686 if (!cpu_icache_snoops_remote_store && scache_size) … … static void __init loongson2_sc_init(void) 1135 1149 1136 1150 extern int r5k_sc_init(void); 1137 1151 extern int rm7k_sc_init(void); 1138 extern int mips_sc_init(void);1139 1152 1140 1153 static void __cpuinit setup_scache(void) 1141 1154 { … … static void __cpuinit setup_scache(void) 1189 1202 #endif 1190 1203 1191 1204 default: 1192 if (c->isa_level == MIPS_CPU_ISA_M32R1 ||1193 c->isa_level == MIPS_CPU_ISA_M32R2 ||1194 c->isa_level == MIPS_CPU_ISA_M64R1 ||1195 c->isa_level == MIPS_CPU_ISA_M64R2) {1196 #ifdef CONFIG_MIPS_CPU_SCACHE1197 if (mips_sc_init ()) {1198 scache_size = c->scache.ways * c->scache.sets * c->scache.linesz;1199 printk("MIPS secondary cache %ldkB, %s, linesize %d bytes.\n",1200 scache_size >> 10,1201 way_string[c->scache.ways], c->scache.linesz);1202 }1203 #else1204 if (!(c->scache.flags & MIPS_CACHE_NOT_PRESENT))1205 panic("Dunno how to handle MIPS32 / MIPS64 second level cache");1206 #endif1207 return;1208 }1209 1205 sc_present = 0; 1210 1206 } 1211 1207 1212 1208 if (!sc_present) 1213 1209 return; 1214 1210 1211 if ((c->isa_level == MIPS_CPU_ISA_M32R1 || 1212 c->isa_level == MIPS_CPU_ISA_M64R1) && 1213 !(c->scache.flags & MIPS_CACHE_NOT_PRESENT)) 1214 panic("Dunno how to handle MIPS32 / MIPS64 second level cache"); 1215 1215 1216 /* compute a couple of other cache variables */ 1216 1217 c->scache.waysize = scache_size / c->scache.ways; 1217 1218 … … static void __cpuinit coherency_setup(void) 1298 1299 * silly idea of putting something else there ... 1299 1300 */ 1300 1301 switch (current_cpu_type()) { 1302 case CPU_BCM3302: 1303 { 1304 u32 cm; 1305 cm = read_c0_diag(); 1306 /* Enable icache */ 1307 cm |= (1 << 31); 1308 /* Enable dcache */ 1309 cm |= (1 << 30); 1310 write_c0_diag(cm); 1311 } 1312 break; 1301 1313 case CPU_R4000PC: 1302 1314 case CPU_R4000SC: 1303 1315 case CPU_R4000MC: … … void __cpuinit r4k_cache_init(void) 1354 1366 break; 1355 1367 } 1356 1368 1369 /* Check if special workarounds are required */ 1370 #ifdef CONFIG_BCM47XX 1371 if (current_cpu_data.cputype == CPU_BCM4710 && (current_cpu_data.processor_id & 0xff) == 0) { 1372 printk("Enabling BCM4710A0 cache workarounds.\n"); 1373 bcm4710 = 1; 1374 } else 1375 #endif 1376 bcm4710 = 0; 1377 1357 1378 probe_pcache(); 1358 1379 setup_scache(); 1359 1380 … … void __cpuinit r4k_cache_init(void) 1412 1433 #if !defined(CONFIG_MIPS_CMP) 1413 1434 local_r4k___flush_cache_all(NULL); 1414 1435 #endif 1436 #ifdef CONFIG_BCM47XX 1437 { 1438 static void (*_coherency_setup)(void); 1439 _coherency_setup = (void (*)(void)) KSEG1ADDR(coherency_setup); 1440 _coherency_setup(); 1441 } 1442 #else 1415 1443 coherency_setup(); 1444 #endif 1416 1445 } 1446 1447 // fuse package DCACHE BUG patch exports 1448 void (*fuse_flush_cache_all)(void) = r4k___flush_cache_all; 1449 void (*fuse_flush_cache_page)(struct vm_area_struct *vma, unsigned long page, 1450 unsigned long pfn) = r4k_flush_cache_page; 1451 EXPORT_SYMBOL(fuse_flush_cache_page); 1452 EXPORT_SYMBOL(fuse_flush_cache_all); -
arch/mips/mm/init.c
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index c551129..e733f78 100644
a b void kunmap_coherent(void) 198 198 preempt_check_resched(); 199 199 } 200 200 201 void copy_user_highpage(struct page *to, struct page *from,202 unsigned long vaddr, struct vm_area_struct *vma)203 {204 void *vfrom, *vto;205 206 vto = kmap_atomic(to, KM_USER1);207 if (cpu_has_dc_aliases &&208 page_mapped(from) && !Page_dcache_dirty(from)) {209 vfrom = kmap_coherent(from, vaddr);210 copy_page(vto, vfrom);211 kunmap_coherent();212 } else {213 vfrom = kmap_atomic(from, KM_USER0);214 copy_page(vto, vfrom);215 kunmap_atomic(vfrom, KM_USER0);216 }217 if ((!cpu_has_ic_fills_f_dc) ||218 pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))219 flush_data_cache_page((unsigned long)vto);220 kunmap_atomic(vto, KM_USER1);221 /* Make sure this page is cleared on other CPU's too before using it */222 smp_wmb();223 }224 225 201 void copy_to_user_page(struct vm_area_struct *vma, 226 202 struct page *page, unsigned long vaddr, void *dst, const void *src, 227 203 unsigned long len) 228 204 { 229 if (cpu_has_dc_aliases && 205 if (cpu_has_dc_aliases && cpu_use_kmap_coherent && 230 206 page_mapped(page) && !Page_dcache_dirty(page)) { 231 207 void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); 232 208 memcpy(vto, src, len); … … void copy_from_user_page(struct vm_area_struct *vma, 244 220 struct page *page, unsigned long vaddr, void *dst, const void *src, 245 221 unsigned long len) 246 222 { 247 if (cpu_has_dc_aliases && 223 if (cpu_has_dc_aliases && cpu_use_kmap_coherent && 248 224 page_mapped(page) && !Page_dcache_dirty(page)) { 249 225 void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); 250 226 memcpy(dst, vfrom, len); -
arch/mips/mm/tlbex.c
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 0615b62..b0d64df 100644
a b build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) 544 544 #endif 545 545 uasm_i_addu(p, ptr, tmp, ptr); 546 546 #else 547 #ifdef CONFIG_BCM47XX 548 uasm_i_nop(p); 549 #endif 547 550 UASM_i_LA_mostly(p, ptr, pgdc); 548 551 #endif 549 552 uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */ … … static void __cpuinit build_r4000_tlb_refill_handler(void) 677 680 #ifdef CONFIG_64BIT 678 681 build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */ 679 682 #else 683 # ifdef CONFIG_BCM47XX 684 uasm_i_nop(&p); 685 # endif 680 686 build_get_pgde32(&p, K0, K1); /* get pgd in K1 */ 681 687 #endif 682 688 … … static void __cpuinit build_r4000_tlb_refill_handler(void) 684 690 build_update_entries(&p, K0, K1); 685 691 build_tlb_write_entry(&p, &l, &r, tlb_random); 686 692 uasm_l_leave(&l, p); 693 #ifdef CONFIG_BCM47XX 694 uasm_i_nop(&p); 695 #endif 687 696 uasm_i_eret(&p); /* return from trap */ 688 697 689 698 #ifdef CONFIG_64BIT … … build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l, 1084 1093 #ifdef CONFIG_64BIT 1085 1094 build_get_pmde64(p, l, r, pte, ptr); /* get pmd in ptr */ 1086 1095 #else 1096 # ifdef CONFIG_BCM47XX 1097 uasm_i_nop(p); 1098 # endif 1087 1099 build_get_pgde32(p, pte, ptr); /* get pgd in ptr */ 1088 1100 #endif 1089 1101 … … build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l, 1111 1123 build_update_entries(p, tmp, ptr); 1112 1124 build_tlb_write_entry(p, l, r, tlb_indexed); 1113 1125 uasm_l_leave(l, *p); 1126 #ifdef CONFIG_BCM47XX 1127 uasm_i_nop(p); 1128 #endif 1114 1129 uasm_i_eret(p); /* return from trap */ 1115 1130 1116 1131 #ifdef CONFIG_64BIT -
arch/mips/pci/pci.c
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index b0eb9e7..85c152a 100644
a b static int pcibios_enable_resources(struct pci_dev *dev, int mask) 185 185 if ((idx == PCI_ROM_RESOURCE) && 186 186 (!(r->flags & IORESOURCE_ROM_ENABLE))) 187 187 continue; 188 if (!r->start && r->end) {189 printk(KERN_ ERR "PCI: Device %s not available"190 " because of resource collisions\n",188 if (!r->start && r->end) 189 printk(KERN_WARNING "PCI: Device %s resource" 190 "collisions detected. Ignoring...\n", 191 191 pci_name(dev)); 192 return -EINVAL;193 }194 192 if (r->flags & IORESOURCE_IO) 195 193 cmd |= PCI_COMMAND_IO; 196 194 if (r->flags & IORESOURCE_MEM) -
drivers/mtd/maps/Kconfig
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 82923bd..4fa8a05 100644
a b config MTD_CFI_FLAGADM 343 343 Mapping for the Flaga digital module. If you don't have one, ignore 344 344 this setting. 345 345 346 config MTD_BCM47XX 347 tristate "BCM47xx flash device" 348 depends on MIPS && MTD_CFI && BCM47XX 349 help 350 Support for the flash chips on the BCM947xx board. 351 346 352 config MTD_REDWOOD 347 353 tristate "CFI Flash devices mapped on IBM Redwood" 348 354 depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 ) -
drivers/mtd/maps/Makefile
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 2dbc1be..d45138c 100644
a b obj-$(CONFIG_MTD_PMC_MSP_RAMROOT)+= pmcmsp-ramroot.o 29 29 obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o 30 30 obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o 31 31 obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o 32 obj-$(CONFIG_MTD_BCM47XX) += bcm47xx-flash.o 32 33 obj-$(CONFIG_MTD_SA1100) += sa1100-flash.o 33 34 obj-$(CONFIG_MTD_IPAQ) += ipaq-flash.o 34 35 obj-$(CONFIG_MTD_SBC_GXX) += sbc_gxx.o -
new file drivers/mtd/maps/bcm47xx-flash.c
diff --git a/drivers/mtd/maps/bcm47xx-flash.c b/drivers/mtd/maps/bcm47xx-flash.c new file mode 100644 index 0000000..3ceec40
- + 1 /* 2 * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> 3 * Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org> 4 * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) 5 * 6 * original functions for finding root filesystem from Mike Baker 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 16 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 19 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 * You should have received a copy of the GNU General Public License along 25 * with this program; if not, write to the Free Software Foundation, Inc., 26 * 675 Mass Ave, Cambridge, MA 02139, USA. 27 * 28 * Copyright 2001-2003, Broadcom Corporation 29 * All Rights Reserved. 30 * 31 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 32 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 33 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 34 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 35 * 36 * Flash mapping for BCM947XX boards 37 */ 38 39 #include <linux/init.h> 40 #include <linux/module.h> 41 #include <linux/types.h> 42 #include <linux/kernel.h> 43 #include <linux/sched.h> 44 #include <linux/wait.h> 45 #include <linux/mtd/mtd.h> 46 #include <linux/mtd/map.h> 47 #ifdef CONFIG_MTD_PARTITIONS 48 #include <linux/mtd/partitions.h> 49 #endif 50 #include <linux/crc32.h> 51 #ifdef CONFIG_SSB 52 #include <linux/ssb/ssb.h> 53 #endif 54 #include <asm/io.h> 55 56 57 #define TRX_MAGIC 0x30524448 /* "HDR0" */ 58 #define TRX_VERSION 1 59 #define TRX_MAX_LEN 0x3A0000 60 #define TRX_NO_HEADER 1 /* Do not write TRX header */ 61 #define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ 62 #define TRX_MAX_OFFSET 3 63 64 struct trx_header { 65 u32 magic; /* "HDR0" */ 66 u32 len; /* Length of file including header */ 67 u32 crc32; /* 32-bit CRC from flag_version to end of file */ 68 u32 flag_version; /* 0:15 flags, 16:31 version */ 69 u32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ 70 }; 71 72 #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) 73 #define NVRAM_SPACE 0x8000 74 #define WINDOW_ADDR 0x1fc00000 75 #define WINDOW_SIZE 0x400000 76 #define BUSWIDTH 2 77 78 #ifdef CONFIG_SSB 79 extern struct ssb_bus ssb_bcm47xx; 80 #endif 81 static struct mtd_info *bcm47xx_mtd; 82 83 static void bcm47xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) 84 { 85 if (len==1) { 86 memcpy_fromio(to, map->virt + from, len); 87 } else { 88 int i; 89 u16 *dest = (u16 *) to; 90 u16 *src = (u16 *) (map->virt + from); 91 for (i = 0; i < (len / 2); i++) { 92 dest[i] = src[i]; 93 } 94 if (len & 1) 95 *((u8 *)dest+len-1) = src[i] & 0xff; 96 } 97 } 98 99 static struct map_info bcm47xx_map = { 100 name: "Physically mapped flash", 101 size: WINDOW_SIZE, 102 bankwidth: BUSWIDTH, 103 phys: WINDOW_ADDR, 104 }; 105 106 #ifdef CONFIG_MTD_PARTITIONS 107 108 static struct mtd_partition bcm47xx_parts[] = { 109 { name: "cfe", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, }, 110 { name: "linux", offset: 0, size: 0, }, 111 { name: "rootfs", offset: 0, size: 0, }, 112 { name: "nvram", offset: 0, size: 0, }, 113 { name: NULL, }, 114 }; 115 116 static int __init 117 find_cfe_size(struct mtd_info *mtd, size_t size) 118 { 119 struct trx_header *trx; 120 unsigned char buf[512]; 121 int off; 122 size_t len; 123 int blocksize; 124 125 trx = (struct trx_header *) buf; 126 127 blocksize = mtd->erasesize; 128 if (blocksize < 0x10000) 129 blocksize = 0x10000; 130 131 for (off = (128*1024); off < size; off += blocksize) { 132 memset(buf, 0xe5, sizeof(buf)); 133 134 /* 135 * Read into buffer 136 */ 137 if (mtd->read(mtd, off, sizeof(buf), &len, buf) || 138 len != sizeof(buf)) 139 continue; 140 141 /* found a TRX header */ 142 if (le32_to_cpu(trx->magic) == TRX_MAGIC) { 143 goto found; 144 } 145 } 146 147 printk(KERN_NOTICE 148 "%s: Couldn't find bootloader size\n", 149 mtd->name); 150 return -1; 151 152 found: 153 printk(KERN_NOTICE "bootloader size: %d\n", off); 154 return off; 155 156 } 157 158 /* 159 * Copied from mtdblock.c 160 * 161 * Cache stuff... 162 * 163 * Since typical flash erasable sectors are much larger than what Linux's 164 * buffer cache can handle, we must implement read-modify-write on flash 165 * sectors for each block write requests. To avoid over-erasing flash sectors 166 * and to speed things up, we locally cache a whole flash sector while it is 167 * being written to until a different sector is required. 168 */ 169 170 static void erase_callback(struct erase_info *done) 171 { 172 wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv; 173 wake_up(wait_q); 174 } 175 176 static int erase_write (struct mtd_info *mtd, unsigned long pos, 177 int len, const char *buf) 178 { 179 struct erase_info erase; 180 DECLARE_WAITQUEUE(wait, current); 181 wait_queue_head_t wait_q; 182 size_t retlen; 183 int ret; 184 185 /* 186 * First, let's erase the flash block. 187 */ 188 189 init_waitqueue_head(&wait_q); 190 erase.mtd = mtd; 191 erase.callback = erase_callback; 192 erase.addr = pos; 193 erase.len = len; 194 erase.priv = (u_long)&wait_q; 195 196 set_current_state(TASK_INTERRUPTIBLE); 197 add_wait_queue(&wait_q, &wait); 198 199 ret = mtd->erase(mtd, &erase); 200 if (ret) { 201 set_current_state(TASK_RUNNING); 202 remove_wait_queue(&wait_q, &wait); 203 printk (KERN_WARNING "erase of region [0x%lx, 0x%x] " 204 "on \"%s\" failed\n", 205 pos, len, mtd->name); 206 return ret; 207 } 208 209 schedule(); /* Wait for erase to finish. */ 210 remove_wait_queue(&wait_q, &wait); 211 212 /* 213 * Next, writhe data to flash. 214 */ 215 216 ret = mtd->write (mtd, pos, len, &retlen, buf); 217 if (ret) 218 return ret; 219 if (retlen != len) 220 return -EIO; 221 return 0; 222 } 223 224 225 226 227 static int __init 228 find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part) 229 { 230 struct trx_header trx, *trx2; 231 unsigned char buf[512], *block; 232 int off, blocksize; 233 u32 i, crc = ~0; 234 size_t len; 235 struct squashfs_super_block *sb = (struct squashfs_super_block *) buf; 236 237 blocksize = mtd->erasesize; 238 if (blocksize < 0x10000) 239 blocksize = 0x10000; 240 241 for (off = (128*1024); off < size; off += blocksize) { 242 memset(&trx, 0xe5, sizeof(trx)); 243 244 /* 245 * Read into buffer 246 */ 247 if (mtd->read(mtd, off, sizeof(trx), &len, (char *) &trx) || 248 len != sizeof(trx)) 249 continue; 250 251 /* found a TRX header */ 252 if (le32_to_cpu(trx.magic) == TRX_MAGIC) { 253 part->offset = le32_to_cpu(trx.offsets[2]) ? : 254 le32_to_cpu(trx.offsets[1]); 255 part->size = le32_to_cpu(trx.len); 256 257 part->size -= part->offset; 258 part->offset += off; 259 260 goto found; 261 } 262 } 263 264 printk(KERN_NOTICE 265 "%s: Couldn't find root filesystem\n", 266 mtd->name); 267 return -1; 268 269 found: 270 if (part->size == 0) 271 return 0; 272 273 if (mtd->read(mtd, part->offset, sizeof(buf), &len, buf) || len != sizeof(buf)) 274 return 0; 275 276 /* Move the fs outside of the trx */ 277 part->size = 0; 278 279 if (trx.len != part->offset + part->size - off) { 280 /* Update the trx offsets and length */ 281 trx.len = part->offset + part->size - off; 282 283 /* Update the trx crc32 */ 284 for (i = (u32) &(((struct trx_header *)NULL)->flag_version); i <= trx.len; i += sizeof(buf)) { 285 if (mtd->read(mtd, off + i, sizeof(buf), &len, buf) || len != sizeof(buf)) 286 return 0; 287 crc = crc32_le(crc, buf, min(sizeof(buf), trx.len - i)); 288 } 289 trx.crc32 = crc; 290 291 /* read first eraseblock from the trx */ 292 block = kmalloc(mtd->erasesize, GFP_KERNEL); 293 trx2 = (struct trx_header *) block; 294 if (mtd->read(mtd, off, mtd->erasesize, &len, block) || len != mtd->erasesize) { 295 printk("Error accessing the first trx eraseblock\n"); 296 return 0; 297 } 298 299 printk("Updating TRX offsets and length:\n"); 300 printk("old trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx2->offsets[0], trx2->offsets[1], trx2->offsets[2], trx2->len, trx2->crc32); 301 printk("new trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx.offsets[0], trx.offsets[1], trx.offsets[2], trx.len, trx.crc32); 302 303 /* Write updated trx header to the flash */ 304 memcpy(block, &trx, sizeof(trx)); 305 if (mtd->unlock) 306 mtd->unlock(mtd, off, mtd->erasesize); 307 erase_write(mtd, off, mtd->erasesize, block); 308 if (mtd->sync) 309 mtd->sync(mtd); 310 kfree(block); 311 printk("Done\n"); 312 } 313 314 return part->size; 315 } 316 317 struct mtd_partition * __init 318 init_mtd_partitions(struct mtd_info *mtd, size_t size) 319 { 320 int cfe_size; 321 322 if ((cfe_size = find_cfe_size(mtd,size)) < 0) 323 return NULL; 324 325 /* boot loader */ 326 bcm47xx_parts[0].offset = 0; 327 bcm47xx_parts[0].size = cfe_size; 328 329 /* nvram */ 330 if (cfe_size != 384 * 1024) { 331 bcm47xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize); 332 bcm47xx_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize); 333 } else { 334 /* nvram (old 128kb config partition on netgear wgt634u) */ 335 bcm47xx_parts[3].offset = bcm47xx_parts[0].size; 336 bcm47xx_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize); 337 } 338 339 /* linux (kernel and rootfs) */ 340 if (cfe_size != 384 * 1024) { 341 bcm47xx_parts[1].offset = bcm47xx_parts[0].size; 342 bcm47xx_parts[1].size = bcm47xx_parts[3].offset - 343 bcm47xx_parts[1].offset; 344 } else { 345 /* do not count the elf loader, which is on one block */ 346 bcm47xx_parts[1].offset = bcm47xx_parts[0].size + 347 bcm47xx_parts[3].size + mtd->erasesize; 348 bcm47xx_parts[1].size = size - 349 bcm47xx_parts[0].size - 350 (2*bcm47xx_parts[3].size) - 351 mtd->erasesize; 352 } 353 354 /* find and size rootfs */ 355 find_root(mtd,size,&bcm47xx_parts[2]); 356 bcm47xx_parts[2].size = size - bcm47xx_parts[2].offset - bcm47xx_parts[3].size; 357 358 return bcm47xx_parts; 359 } 360 #endif 361 362 int __init init_bcm47xx_map(void) 363 { 364 #ifdef CONFIG_SSB 365 struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore; 366 #endif 367 size_t size; 368 int ret = 0; 369 #ifdef CONFIG_MTD_PARTITIONS 370 struct mtd_partition *parts; 371 int i; 372 #endif 373 374 #ifdef CONFIG_SSB 375 u32 window = mcore->flash_window; 376 u32 window_size = mcore->flash_window_size; 377 378 printk("flash init: 0x%08x 0x%08x\n", window, window_size); 379 bcm47xx_map.phys = window; 380 bcm47xx_map.size = window_size; 381 bcm47xx_map.bankwidth = mcore->flash_buswidth; 382 bcm47xx_map.virt = ioremap_nocache(window, window_size); 383 #else 384 printk("flash init: 0x%08x 0x%08x\n", WINDOW_ADDR, WINDOW_SIZE); 385 bcm47xx_map.virt = ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE); 386 #endif 387 388 if (!bcm47xx_map.virt) { 389 printk("Failed to ioremap\n"); 390 return -EIO; 391 } 392 393 simple_map_init(&bcm47xx_map); 394 395 if (!(bcm47xx_mtd = do_map_probe("cfi_probe", &bcm47xx_map))) { 396 printk("Failed to do_map_probe\n"); 397 iounmap((void *)bcm47xx_map.virt); 398 return -ENXIO; 399 } 400 401 /* override copy_from routine */ 402 bcm47xx_map.copy_from = bcm47xx_map_copy_from; 403 404 bcm47xx_mtd->owner = THIS_MODULE; 405 406 size = bcm47xx_mtd->size; 407 408 printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, WINDOW_ADDR); 409 410 #ifdef CONFIG_MTD_PARTITIONS 411 parts = init_mtd_partitions(bcm47xx_mtd, size); 412 for (i = 0; parts[i].name; i++); 413 ret = add_mtd_partitions(bcm47xx_mtd, parts, i); 414 if (ret) { 415 printk(KERN_ERR "Flash: add_mtd_partitions failed\n"); 416 goto fail; 417 } 418 #endif 419 return 0; 420 421 fail: 422 if (bcm47xx_mtd) 423 map_destroy(bcm47xx_mtd); 424 if (bcm47xx_map.virt) 425 iounmap((void *)bcm47xx_map.virt); 426 bcm47xx_map.virt = 0; 427 return ret; 428 } 429 430 void __exit cleanup_bcm47xx_map(void) 431 { 432 #ifdef CONFIG_MTD_PARTITIONS 433 del_mtd_partitions(bcm47xx_mtd); 434 #endif 435 map_destroy(bcm47xx_mtd); 436 iounmap((void *)bcm47xx_map.virt); 437 } 438 439 module_init(init_bcm47xx_map); 440 module_exit(cleanup_bcm47xx_map); -
drivers/net/b44.c
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index b70b81e..2508e77 100644
a b static int b44_phy_reset(struct b44 *bp) 339 339 } 340 340 } 341 341 342 return 0;342 return err; 343 343 } 344 344 345 345 static void __b44_set_flow_ctrl(struct b44 *bp, u32 pause_flags) … … static int b44_rx(struct b44 *bp, int budget) 815 815 struct sk_buff *copy_skb; 816 816 817 817 b44_recycle_rx(bp, cons, bp->rx_prod); 818 copy_skb = dev_alloc_skb(len + 2);818 copy_skb = netdev_alloc_skb(bp->dev, len + 2); 819 819 if (copy_skb == NULL) 820 820 goto drop_it_no_recycle; 821 821 … … static int __devinit b44_init_one(struct ssb_device *sdev, 2220 2220 */ 2221 2221 b44_chip_reset(bp, B44_CHIP_RESET_FULL); 2222 2222 2223 /* do a phy reset to test if there is an active phy */ 2224 if (b44_phy_reset(bp) < 0) 2225 bp->phy_addr = B44_PHY_ADDR_NO_PHY; 2226 2223 2227 printk(KERN_INFO "%s: Broadcom 44xx/47xx 10/100BaseT Ethernet %pM\n", 2224 2228 dev->name, dev->dev_addr); 2225 2229 -
drivers/net/tg3.c
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 201be42..70b7c7b 100644
a b 41 41 #include <linux/prefetch.h> 42 42 #include <linux/dma-mapping.h> 43 43 #include <linux/firmware.h> 44 #include <linux/ssb/ssb_driver_gige.h> 44 45 45 46 #include <net/checksum.h> 46 47 #include <net/ip.h> … … static void _tw32_flush(struct tg3 *tp, u32 off, u32 val, u32 usec_wait) 446 447 static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val) 447 448 { 448 449 tp->write32_mbox(tp, off, val); 449 if (!(tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) && 450 !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND)) 450 if ((tp->tg3_flags3 & TG3_FLG3_FLUSH_POSTED_WRITES) || 451 (!(tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) && 452 !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))) 451 453 tp->read32_mbox(tp, off); 452 454 } 453 455 … … static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val) 457 459 writel(val, mbox); 458 460 if (tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) 459 461 writel(val, mbox); 460 if ( tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)462 if ((tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) || (tp->tg3_flags3 & TG3_FLG3_FLUSH_POSTED_WRITES)) 461 463 readl(mbox); 462 464 } 463 465 … … static void tg3_switch_clocks(struct tg3 *tp) 729 731 730 732 #define PHY_BUSY_LOOPS 5000 731 733 732 static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)734 static int __tg3_readphy(struct tg3 *tp, unsigned int phy_addr, int reg, u32 *val) 733 735 { 734 736 u32 frame_val; 735 737 unsigned int loops; … … static int tg3_readphy(struct tg3 *tp, int reg, u32 *val) 743 745 744 746 *val = 0x0; 745 747 746 frame_val = (( PHY_ADDR<< MI_COM_PHY_ADDR_SHIFT) &748 frame_val = ((phy_addr << MI_COM_PHY_ADDR_SHIFT) & 747 749 MI_COM_PHY_ADDR_MASK); 748 750 frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) & 749 751 MI_COM_REG_ADDR_MASK); … … static int tg3_readphy(struct tg3 *tp, int reg, u32 *val) 778 780 return ret; 779 781 } 780 782 781 static int tg3_writephy(struct tg3 *tp, int reg, u32 val) 783 static int tg3_readphy(struct tg3 *tp, int reg, u32 *val) 784 { 785 return __tg3_readphy(tp, PHY_ADDR, reg, val); 786 } 787 788 static int __tg3_writephy(struct tg3 *tp, unsigned int phy_addr, int reg, u32 val) 782 789 { 783 790 u32 frame_val; 784 791 unsigned int loops; … … static int tg3_writephy(struct tg3 *tp, int reg, u32 val) 794 801 udelay(80); 795 802 } 796 803 797 frame_val = (( PHY_ADDR<< MI_COM_PHY_ADDR_SHIFT) &804 frame_val = ((phy_addr << MI_COM_PHY_ADDR_SHIFT) & 798 805 MI_COM_PHY_ADDR_MASK); 799 806 frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) & 800 807 MI_COM_REG_ADDR_MASK); … … static int tg3_writephy(struct tg3 *tp, int reg, u32 val) 827 834 return ret; 828 835 } 829 836 837 static int tg3_writephy(struct tg3 *tp, int reg, u32 val) 838 { 839 return __tg3_writephy(tp, PHY_ADDR, reg, val); 840 } 841 830 842 static int tg3_bmcr_reset(struct tg3 *tp) 831 843 { 832 844 u32 phy_control; … … static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val) 2262 2274 { 2263 2275 int ret; 2264 2276 2277 if (tp->tg3_flags3 & TG3_FLG3_IS_SSB_CORE) 2278 return -ENODEV; 2279 2265 2280 if (!(tp->tg3_flags & TG3_FLAG_NVRAM)) 2266 2281 return tg3_nvram_read_using_eeprom(tp, offset, val); 2267 2282 … … static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) 2595 2610 tg3_frob_aux_power(tp); 2596 2611 2597 2612 /* Workaround for unstable PLL clock */ 2598 if ((GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX) || 2599 (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX)) { 2613 if ((tp->phy_id & PHY_ID_MASK != PHY_ID_BCM5750_2) && 2614 /* !!! FIXME !!! */ 2615 ((GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX) || 2616 (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX))) { 2600 2617 u32 val = tr32(0x7d00); 2601 2618 2602 2619 val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1); … … relink: 3088 3105 3089 3106 tg3_phy_copper_begin(tp); 3090 3107 3108 if (tp->tg3_flags3 & TG3_FLG3_ROBOSWITCH) { 3109 current_link_up = 1; 3110 current_speed = SPEED_1000; //FIXME 3111 current_duplex = DUPLEX_FULL; 3112 tp->link_config.active_speed = current_speed; 3113 tp->link_config.active_duplex = current_duplex; 3114 } 3115 3091 3116 tg3_readphy(tp, MII_BMSR, &tmp); 3092 3117 if (!tg3_readphy(tp, MII_BMSR, &tmp) && 3093 3118 (tmp & BMSR_LSTATUS)) … … static int tg3_poll_fw(struct tg3 *tp) 6000 6025 int i; 6001 6026 u32 val; 6002 6027 6028 if (tp->tg3_flags3 & TG3_FLG3_IS_SSB_CORE) { 6029 /* We don't use firmware. */ 6030 return 0; 6031 } 6032 6003 6033 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { 6004 6034 /* Wait up to 20ms for init done. */ 6005 6035 for (i = 0; i < 200; i++) { … … static int tg3_chip_reset(struct tg3 *tp) 6256 6286 tw32(0x5000, 0x400); 6257 6287 } 6258 6288 6289 if (tp->tg3_flags3 & TG3_FLG3_IS_SSB_CORE) { 6290 /* BCM4785: In order to avoid repercussions from using potentially 6291 * defective internal ROM, stop the Rx RISC CPU, which is not 6292 * required. */ 6293 tg3_stop_fw(tp); 6294 tg3_halt_cpu(tp, RX_CPU_BASE); 6295 } 6296 6259 6297 tw32(GRC_MODE, tp->grc_mode); 6260 6298 6261 6299 if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A0) { … … static int tg3_halt_cpu(struct tg3 *tp, u32 offset) 6406 6444 return -ENODEV; 6407 6445 } 6408 6446 6409 /* Clear firmware's nvram arbitration. */ 6410 if (tp->tg3_flags & TG3_FLAG_NVRAM) 6411 tw32(NVRAM_SWARB, SWARB_REQ_CLR0); 6447 if (!(tp->tg3_flags3 & TG3_FLG3_IS_SSB_CORE)) { 6448 /* Clear firmware's nvram arbitration. */ 6449 if (tp->tg3_flags & TG3_FLAG_NVRAM) 6450 tw32(NVRAM_SWARB, SWARB_REQ_CLR0); 6451 } 6452 6412 6453 return 0; 6413 6454 } 6414 6455 … … static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) 6471 6512 const __be32 *fw_data; 6472 6513 int err, i; 6473 6514 6515 if (tp->tg3_flags3 & TG3_FLG3_IS_SSB_CORE) { 6516 /* We don't use firmware. */ 6517 return 0; 6518 } 6519 6474 6520 fw_data = (void *)tp->fw->data; 6475 6521 6476 6522 /* Firmware blob starts with version numbers, followed by … … static int tg3_load_tso_firmware(struct tg3 *tp) 6530 6576 unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size; 6531 6577 int err, i; 6532 6578 6579 if (tp->tg3_flags3 & TG3_FLG3_IS_SSB_CORE) { 6580 /* We don't use firmware. */ 6581 return 0; 6582 } 6583 6533 6584 if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) 6534 6585 return 0; 6535 6586 … … static void tg3_timer(unsigned long __opaque) 7435 7486 7436 7487 spin_lock(&tp->lock); 7437 7488 7489 if (tp->tg3_flags3 & TG3_FLG3_FLUSH_POSTED_WRITES) { 7490 /* BCM4785: Flush posted writes from GbE to host memory. */ 7491 tr32(HOSTCC_MODE); 7492 } 7493 7438 7494 if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) { 7439 7495 /* All of this garbage is because when using non-tagged 7440 7496 * IRQ status the mailbox/status_block protocol the chip … … static int tg3_test_nvram(struct tg3 *tp) 9201 9257 __be32 *buf; 9202 9258 int i, j, k, err = 0, size; 9203 9259 9260 if (tp->tg3_flags3 & TG3_FLG3_IS_SSB_CORE) { 9261 /* We don't have NVRAM. */ 9262 return 0; 9263 } 9264 9204 9265 if (tg3_nvram_read(tp, 0, &magic) != 0) 9205 9266 return -EIO; 9206 9267 … … static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 9994 10055 return -EAGAIN; 9995 10056 9996 10057 spin_lock_bh(&tp->lock); 9997 err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval);10058 err = __tg3_readphy(tp, data->phy_id & 0x1f, data->reg_num & 0x1f, &mii_regval); 9998 10059 spin_unlock_bh(&tp->lock); 9999 10060 10000 10061 data->val_out = mii_regval; … … static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 10013 10074 return -EAGAIN; 10014 10075 10015 10076 spin_lock_bh(&tp->lock); 10016 err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in);10077 err = __tg3_writephy(tp, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in); 10017 10078 spin_unlock_bh(&tp->lock); 10018 10079 10019 10080 return err; … … static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp) 10601 10662 /* Chips other than 5700/5701 use the NVRAM for fetching info. */ 10602 10663 static void __devinit tg3_nvram_init(struct tg3 *tp) 10603 10664 { 10665 if (tp->tg3_flags3 & TG3_FLG3_IS_SSB_CORE) { 10666 /* No NVRAM and EEPROM on the SSB Broadcom GigE core. */ 10667 tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED); 10668 return; 10669 } 10670 10604 10671 tw32_f(GRC_EEPROM_ADDR, 10605 10672 (EEPROM_ADDR_FSM_RESET | 10606 10673 (EEPROM_DEFAULT_CLOCK_PERIOD << … … static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf) 10859 10926 { 10860 10927 int ret; 10861 10928 10929 if (tp->tg3_flags3 & TG3_FLG3_IS_SSB_CORE) 10930 return -ENODEV; 10931 10862 10932 if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) { 10863 10933 tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl & 10864 10934 ~GRC_LCLCTRL_GPIO_OUTPUT1); … … static int __devinit tg3_get_invariants(struct tg3 *tp) 12063 12133 tp->write32 = tg3_write_flush_reg32; 12064 12134 } 12065 12135 12066 12067 12136 if ((tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) || 12068 12137 (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)) { 12069 12138 tp->write32_tx_mbox = tg3_write32_tx_mbox; … … static int __devinit tg3_get_invariants(struct tg3 *tp) 12099 12168 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701))) 12100 12169 tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG; 12101 12170 12171 if (tp->tg3_flags3 & TG3_FLG3_FLUSH_POSTED_WRITES) { 12172 tp->write32_tx_mbox = tg3_write_flush_reg32; 12173 tp->write32_rx_mbox = tg3_write_flush_reg32; 12174 } 12175 12102 12176 /* Get eeprom hw config before calling tg3_set_power_state(). 12103 12177 * In particular, the TG3_FLG2_IS_NIC flag must be 12104 12178 * determined before calling tg3_set_power_state() so that … … static int __devinit tg3_get_device_address(struct tg3 *tp) 12474 12548 } 12475 12549 12476 12550 if (!is_valid_ether_addr(&dev->dev_addr[0])) { 12551 if (tp->tg3_flags3 & TG3_FLG3_IS_SSB_CORE) 12552 ssb_gige_get_macaddr(tp->pdev, &dev->dev_addr[0]); 12553 } 12554 if (!is_valid_ether_addr(&dev->dev_addr[0])) { 12477 12555 #ifdef CONFIG_SPARC 12478 12556 if (!tg3_get_default_macaddr_sparc(tp)) 12479 12557 return 0; … … static char * __devinit tg3_phy_string(struct tg3 *tp) 12965 13043 case PHY_ID_BCM5704: return "5704"; 12966 13044 case PHY_ID_BCM5705: return "5705"; 12967 13045 case PHY_ID_BCM5750: return "5750"; 13046 case PHY_ID_BCM5750_2: return "5750-2"; 12968 13047 case PHY_ID_BCM5752: return "5752"; 12969 13048 case PHY_ID_BCM5714: return "5714"; 12970 13049 case PHY_ID_BCM5780: return "5780"; … … static int __devinit tg3_init_one(struct pci_dev *pdev, 13175 13254 tp->msg_enable = tg3_debug; 13176 13255 else 13177 13256 tp->msg_enable = TG3_DEF_MSG_ENABLE; 13257 if (pdev_is_ssb_gige_core(pdev)) { 13258 tp->tg3_flags3 |= TG3_FLG3_IS_SSB_CORE; 13259 if (ssb_gige_must_flush_posted_writes(pdev)) 13260 tp->tg3_flags3 |= TG3_FLG3_FLUSH_POSTED_WRITES; 13261 if (ssb_gige_have_roboswitch(pdev)) 13262 tp->tg3_flags3 |= TG3_FLG3_ROBOSWITCH; 13263 } 13178 13264 13179 13265 /* The word/byte swap controls here control register access byte 13180 13266 * swapping. DMA data byte swapping is controlled in the GRC_MODE -
drivers/net/tg3.h
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index cb4c62a..5364876 100644
a b 1849 1849 #define NIC_SRAM_RGMII_STD_IBND_DISABLE 0x00000004 1850 1850 #define NIC_SRAM_RGMII_EXT_IBND_RX_EN 0x00000008 1851 1851 #define NIC_SRAM_RGMII_EXT_IBND_TX_EN 0x00000010 1852 #define TG3_FLG3_IS_SSB_CORE 0x00000800 1853 #define TG3_FLG3_FLUSH_POSTED_WRITES 0x00001000 1854 #define TG3_FLG3_ROBOSWITCH 0x00002000 1852 1855 1853 1856 #define NIC_SRAM_RX_MINI_BUFFER_DESC 0x00001000 1854 1857 … … struct tg3 { 2695 2698 #define PHY_ID_BCM5714 0x60008340 2696 2699 #define PHY_ID_BCM5780 0x60008350 2697 2700 #define PHY_ID_BCM5755 0xbc050cc0 2701 #define PHY_ID_BCM5750_2 0xbc050cd0 2698 2702 #define PHY_ID_BCM5787 0xbc050ce0 2699 2703 #define PHY_ID_BCM5756 0xbc050ed0 2700 2704 #define PHY_ID_BCM5784 0xbc050fa0 … … struct tg3 { 2739 2743 (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \ 2740 2744 (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM5756 || \ 2741 2745 (X) == PHY_ID_BCM5906 || (X) == PHY_ID_BCM5761 || \ 2742 (X) == PHY_ID_BCM8002 )2746 (X) == PHY_ID_BCM8002 || (X) == PHY_ID_BCM5750_2) 2743 2747 2744 2748 struct tg3_hw_stats *hw_stats; 2745 2749 dma_addr_t stats_mapping; -
drivers/ssb/Kconfig
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig index 540a294..6c2f443 100644
a b config SSB_DRIVER_MIPS 126 126 config SSB_EMBEDDED 127 127 bool 128 128 depends on SSB_DRIVER_MIPS 129 select USB_EHCI_HCD_SSB 130 select USB_OHCI_HCD_SSB 129 131 default y 130 132 131 133 config SSB_DRIVER_EXTIF -
drivers/ssb/driver_chipcommon.c
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 9681536..7a26028 100644
a b void ssb_chipco_resume(struct ssb_chipcommon *cc) 258 258 void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc, 259 259 u32 *plltype, u32 *n, u32 *m) 260 260 { 261 if ((chipco_read32(cc, SSB_CHIPCO_CHIPID) & SSB_CHIPCO_IDMASK) == 0x5354) 262 return; 261 263 *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N); 262 264 *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT); 263 265 switch (*plltype) { … … void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc, 281 283 void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc, 282 284 u32 *plltype, u32 *n, u32 *m) 283 285 { 286 if ((chipco_read32(cc, SSB_CHIPCO_CHIPID) & SSB_CHIPCO_IDMASK) == 0x5354) 287 return; 284 288 *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N); 285 289 *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT); 286 290 switch (*plltype) { -
drivers/ssb/driver_mipscore.c
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c index 3fd3e3b..f30186d 100644
a b static const u32 ipsflag_irq_shift[] = { 49 49 50 50 static inline u32 ssb_irqflag(struct ssb_device *dev) 51 51 { 52 return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG; 52 u32 tpsflag = ssb_read32(dev, SSB_TPSFLAG); 53 if (tpsflag) 54 return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG; 55 else 56 /* not irq supported */ 57 return 0x3f; 58 } 59 60 static struct ssb_device *find_device(struct ssb_device *rdev, int irqflag) 61 { 62 struct ssb_bus *bus = rdev->bus; 63 int i; 64 for (i = 0; i < bus->nr_devices; i++) { 65 struct ssb_device *dev; 66 dev = &(bus->devices[i]); 67 if (ssb_irqflag(dev) == irqflag) 68 return dev; 69 } 70 return NULL; 53 71 } 54 72 55 73 /* Get the MIPS IRQ assignment for a specified device. 56 74 * If unassigned, 0 is returned. 75 * If disabled, 5 is returned. 76 * If not supported, 6 is returned. 57 77 */ 58 78 unsigned int ssb_mips_irq(struct ssb_device *dev) 59 79 { 60 80 struct ssb_bus *bus = dev->bus; 81 struct ssb_device *mdev = bus->mipscore.dev; 61 82 u32 irqflag; 62 83 u32 ipsflag; 63 84 u32 tmp; 64 85 unsigned int irq; 65 86 66 87 irqflag = ssb_irqflag(dev); 88 if (irqflag == 0x3f) 89 return 6; 67 90 ipsflag = ssb_read32(bus->mipscore.dev, SSB_IPSFLAG); 68 91 for (irq = 1; irq <= 4; irq++) { 69 92 tmp = ((ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]); 70 93 if (tmp == irqflag) 71 94 break; 72 95 } 73 if (irq == 5) 74 irq = 0; 96 if (irq == 5) { 97 if ((1 << irqflag) & ssb_read32(mdev, SSB_INTVEC)) 98 irq = 0; 99 } 75 100 76 101 return irq; 77 102 } … … static void set_irq(struct ssb_device *dev, unsigned int irq) 97 122 struct ssb_device *mdev = bus->mipscore.dev; 98 123 u32 irqflag = ssb_irqflag(dev); 99 124 125 BUG_ON(oldirq == 6); 126 100 127 dev->irq = irq + 2; 101 128 102 ssb_dprintk(KERN_INFO PFX103 "set_irq: core 0x%04x, irq %d => %d\n",104 dev->id.coreid, oldirq, irq);105 129 /* clear the old irq */ 106 130 if (oldirq == 0) 107 131 ssb_write32(mdev, SSB_INTVEC, (~(1 << irqflag) & ssb_read32(mdev, SSB_INTVEC))); 108 else 132 else if (oldirq != 5) 109 133 clear_irq(bus, oldirq); 110 134 111 135 /* assign the new one */ 112 136 if (irq == 0) { 113 137 ssb_write32(mdev, SSB_INTVEC, ((1 << irqflag) | ssb_read32(mdev, SSB_INTVEC))); 114 138 } else { 139 u32 ipsflag = ssb_read32(mdev, SSB_IPSFLAG); 140 if ((ipsflag & ipsflag_irq_mask[irq]) != ipsflag_irq_mask[irq]) { 141 u32 oldipsflag = (ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]; 142 struct ssb_device *olddev = find_device(dev, oldipsflag); 143 if (olddev) 144 set_irq(olddev, 0); 145 } 115 146 irqflag <<= ipsflag_irq_shift[irq]; 116 irqflag |= ( ssb_read32(mdev, SSB_IPSFLAG)& ~ipsflag_irq_mask[irq]);147 irqflag |= (ipsflag & ~ipsflag_irq_mask[irq]); 117 148 ssb_write32(mdev, SSB_IPSFLAG, irqflag); 118 149 } 150 ssb_dprintk(KERN_INFO PFX 151 "set_irq: core 0x%04x, irq %d => %d\n", 152 dev->id.coreid, oldirq+2, irq+2); 153 } 154 155 static void print_irq(struct ssb_device *dev, unsigned int irq) 156 { 157 int i; 158 static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"}; 159 ssb_dprintk(KERN_INFO PFX 160 "core 0x%04x, irq :", dev->id.coreid); 161 for (i = 0; i <= 6; i++) { 162 ssb_dprintk(" %s%s", irq_name[i], i==irq?"*":" "); 163 } 164 ssb_dprintk("\n"); 165 } 166 167 static void dump_irq(struct ssb_bus *bus) 168 { 169 int i; 170 for (i = 0; i < bus->nr_devices; i++) { 171 struct ssb_device *dev; 172 dev = &(bus->devices[i]); 173 print_irq(dev, ssb_mips_irq(dev)); 174 } 119 175 } 120 176 121 177 static void ssb_mips_serial_init(struct ssb_mipscore *mcore) … … u32 ssb_cpu_clock(struct ssb_mipscore *mcore) 161 217 162 218 if ((pll_type == SSB_PLLTYPE_5) || (bus->chip_id == 0x5365)) { 163 219 rate = 200000000; 220 } else if (bus->chip_id == 0x5354) { 221 rate = 240000000; 164 222 } else { 165 223 rate = ssb_calc_clock_rate(pll_type, n, m); 166 224 } … … void ssb_mipscore_init(struct ssb_mipscore *mcore) 195 253 else if (bus->chipco.dev) 196 254 ssb_chipco_timing_init(&bus->chipco, ns); 197 255 256 dump_irq(bus); 198 257 /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */ 199 258 for (irq = 2, i = 0; i < bus->nr_devices; i++) { 259 int mips_irq; 200 260 dev = &(bus->devices[i]); 201 dev->irq = ssb_mips_irq(dev) + 2; 261 mips_irq = ssb_mips_irq(dev); 262 if (mips_irq > 4) 263 dev->irq = 0; 264 else 265 dev->irq = mips_irq + 2; 266 if (dev->irq > 5) 267 continue; 202 268 switch (dev->id.coreid) { 203 269 case SSB_DEV_USB11_HOST: 204 270 /* shouldn't need a separate irq line for non-4710, most of them have a proper 205 271 * external usb controller on the pci */ 206 272 if ((bus->chip_id == 0x4710) && (irq <= 4)) { 207 273 set_irq(dev, irq++); 208 break;209 274 } 275 break; 210 276 /* fallthrough */ 211 277 case SSB_DEV_PCI: 212 278 case SSB_DEV_ETHERNET: … … void ssb_mipscore_init(struct ssb_mipscore *mcore) 220 286 } 221 287 } 222 288 } 289 ssb_dprintk(KERN_INFO PFX "after irq reconfiguration\n"); 290 dump_irq(bus); 223 291 224 292 ssb_mips_serial_init(mcore); 225 293 ssb_mips_flash_detect(mcore); -
drivers/ssb/main.c
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 65a1ed9..4705122 100644
a b u32 ssb_clockspeed(struct ssb_bus *bus) 1010 1010 1011 1011 if (bus->chip_id == 0x5365) { 1012 1012 rate = 100000000; 1013 } else if (bus->chip_id == 0x5354) { 1014 rate = 120000000; 1013 1015 } else { 1014 1016 rate = ssb_calc_clock_rate(plltype, clkctl_n, clkctl_m); 1015 1017 if (plltype == SSB_PLLTYPE_3) /* 25Mhz, 2 dividers */ -
drivers/usb/host/Kconfig
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 845479f..59f8079 100644
a b config USB_OXU210HP_HCD 106 106 To compile this driver as a module, choose M here: the 107 107 module will be called oxu210hp-hcd. 108 108 109 config USB_EHCI_HCD_SSB 110 bool "EHCI support for Broadcom SSB EHCI core" 111 depends on USB_EHCI_HCD && SSB && EXPERIMENTAL 112 default n 113 ---help--- 114 Support for the Sonics Silicon Backplane (SSB) attached 115 Broadcom USB EHCI core. 116 117 This device is present in some embedded devices with 118 Broadcom based SSB bus. 119 120 If unsure, say N. 121 109 122 config USB_ISP116X_HCD 110 123 tristate "ISP116X HCD support" 111 124 depends on USB -
drivers/usb/host/ehci-hcd.c
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c637207..5c248d9 100644
a b MODULE_LICENSE ("GPL"); 1072 1072 #define PLATFORM_DRIVER ixp4xx_ehci_driver 1073 1073 #endif 1074 1074 1075 #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ 1076 !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) 1075 #ifdef CONFIG_USB_EHCI_HCD_SSB 1076 #include "ehci-ssb.c" 1077 #define SSB_EHCI_DRIVER ssb_ehci_driver 1078 #endif 1079 1080 #if !defined(PCI_DRIVER) && \ 1081 !defined(PLATFORM_DRIVER) && \ 1082 !defined(PS3_SYSTEM_BUS_DRIVER) && \ 1083 !defined(OF_PLATFORM_DRIVER) && \ 1084 !defined(SSB_EHCI_DRIVER) 1077 1085 #error "missing bus glue for ehci-hcd" 1078 1086 #endif 1079 1087 -
new file drivers/usb/host/ehci-ssb.c
diff --git a/drivers/usb/host/ehci-ssb.c b/drivers/usb/host/ehci-ssb.c new file mode 100644 index 0000000..be90a5c
- + 1 /* 2 * Sonics Silicon Backplane 3 * Broadcom USB-core EHCI driver (SSB bus glue) 4 * 5 * Copyright 2007 Steven Brown <sbrown@cortland.com> 6 * 7 * Derived from the OHCI-SSB driver 8 * Copyright 2007 Michael Buesch <mb@bu3sch.de> 9 * 10 * Derived from the EHCI-PCI driver 11 * Copyright (c) 2000-2004 by David Brownell 12 * 13 * Derived from the OHCI-PCI driver 14 * Copyright 1999 Roman Weissgaerber 15 * Copyright 2000-2002 David Brownell 16 * Copyright 1999 Linus Torvalds 17 * Copyright 1999 Gregory P. Smith 18 * 19 * Derived from the USBcore related parts of Broadcom-SB 20 * Copyright 2005 Broadcom Corporation 21 * 22 * Licensed under the GNU/GPL. See COPYING for details. 23 */ 24 #include <linux/ssb/ssb.h> 25 26 #define SSB_OHCI_TMSLOW_HOSTMODE (1 << 29) 27 28 struct ssb_ehci_device { 29 struct ehci_hcd ehci; /* _must_ be at the beginning. */ 30 31 u32 enable_flags; 32 }; 33 34 static inline 35 struct ssb_ehci_device *hcd_to_ssb_ehci(struct usb_hcd *hcd) 36 { 37 return (struct ssb_ehci_device *)(hcd->hcd_priv); 38 } 39 40 41 static int ssb_ehci_reset(struct usb_hcd *hcd) 42 { 43 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 44 int err; 45 46 ehci->caps = hcd->regs; 47 ehci->regs = hcd->regs + 48 HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); 49 50 dbg_hcs_params(ehci, "reset"); 51 dbg_hcc_params(ehci, "reset"); 52 53 ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); 54 55 err = ehci_halt(ehci); 56 57 if (err) 58 return err; 59 60 err = ehci_init(hcd); 61 62 if (err) 63 return err; 64 65 ehci_port_power(ehci, 0); 66 67 return err; 68 } 69 70 static int ssb_ehci_start(struct usb_hcd *hcd) 71 { 72 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 73 int err; 74 75 err = ehci_run(hcd); 76 if (err < 0) { 77 ehci_err(ehci, "can't start\n"); 78 ehci_stop(hcd); 79 } 80 81 return err; 82 } 83 84 #ifdef CONFIG_PM 85 static int ssb_ehci_hcd_suspend(struct usb_hcd *hcd, pm_message_t message) 86 { 87 struct ssb_ehci_device *ehcidev = hcd_to_ssb_ehci(hcd); 88 struct ehci_hcd *ehci = &ehcidev->ehci; 89 unsigned long flags; 90 91 spin_lock_irqsave(&ehci->lock, flags); 92 93 ehci_writel(ehci, EHCI_INTR_MIE, &ehci->regs->intrdisable); 94 ehci_readl(ehci, &ehci->regs->intrdisable); /* commit write */ 95 96 /* make sure snapshot being resumed re-enumerates everything */ 97 if (message.event == PM_EVENT_PRETHAW) 98 ehci_usb_reset(ehci); 99 100 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 101 102 spin_unlock_irqrestore(&ehci->lock, flags); 103 return 0; 104 } 105 106 static int ssb_ehci_hcd_resume(struct usb_hcd *hcd) 107 { 108 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 109 usb_hcd_resume_root_hub(hcd); 110 return 0; 111 } 112 #endif /* CONFIG_PM */ 113 114 static const struct hc_driver ssb_ehci_hc_driver = { 115 .description = "ssb-usb-ehci", 116 .product_desc = "SSB EHCI Controller", 117 .hcd_priv_size = sizeof(struct ssb_ehci_device), 118 119 .irq = ehci_irq, 120 .flags = HCD_MEMORY | HCD_USB2, 121 122 .reset = ssb_ehci_reset, 123 .start = ssb_ehci_start, 124 .stop = ehci_stop, 125 .shutdown = ehci_shutdown, 126 127 #ifdef CONFIG_PM 128 .suspend = ssb_ehci_hcd_suspend, 129 .resume = ssb_ehci_hcd_resume, 130 #endif 131 132 .urb_enqueue = ehci_urb_enqueue, 133 .urb_dequeue = ehci_urb_dequeue, 134 .endpoint_disable = ehci_endpoint_disable, 135 136 .get_frame_number = ehci_get_frame, 137 138 .hub_status_data = ehci_hub_status_data, 139 .hub_control = ehci_hub_control, 140 #ifdef CONFIG_PM 141 .bus_suspend = ehci_bus_suspend, 142 .bus_resume = ehci_bus_resume, 143 #endif 144 145 }; 146 147 static void ssb_ehci_detach(struct ssb_device *dev, struct usb_hcd *hcd) 148 { 149 150 usb_remove_hcd(hcd); 151 iounmap(hcd->regs); 152 usb_put_hcd(hcd); 153 } 154 EXPORT_SYMBOL_GPL(ssb_ehci_detach); 155 156 static int ssb_ehci_attach(struct ssb_device *dev, struct usb_hcd **ehci_hcd) 157 { 158 struct ssb_ehci_device *ehcidev; 159 struct usb_hcd *hcd; 160 int err = -ENOMEM; 161 u32 tmp, flags = 0; 162 163 hcd = usb_create_hcd(&ssb_ehci_hc_driver, dev->dev, 164 dev_name(dev->dev)); 165 if (!hcd) 166 goto err_dev_disable; 167 168 ehcidev = hcd_to_ssb_ehci(hcd); 169 ehcidev->enable_flags = flags; 170 tmp = ssb_read32(dev, SSB_ADMATCH0); 171 hcd->rsrc_start = ssb_admatch_base(tmp) + 0x800; /* ehci core offset */ 172 hcd->rsrc_len = 0x100; /* ehci reg block size */ 173 /* 174 * start & size modified per sbutils.c 175 */ 176 hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); 177 if (!hcd->regs) 178 goto err_put_hcd; 179 err = usb_add_hcd(hcd, dev->irq, IRQF_SHARED | IRQF_DISABLED); 180 if (err) 181 goto err_iounmap; 182 183 *ehci_hcd = hcd; 184 185 return err; 186 187 err_iounmap: 188 iounmap(hcd->regs); 189 err_put_hcd: 190 usb_put_hcd(hcd); 191 err_dev_disable: 192 ssb_device_disable(dev, flags); 193 return err; 194 } 195 EXPORT_SYMBOL_GPL(ssb_ehci_attach); 196 197 static const struct ssb_device_id ssb_ehci_table[] = { 198 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV), 199 SSB_DEVTABLE_END 200 }; 201 MODULE_DEVICE_TABLE(ssb, ssb_ehci_table); -
drivers/usb/host/ohci-ssb.c
diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c index 23fd6a8..599f7b5 100644
a b 17 17 */ 18 18 #include <linux/ssb/ssb.h> 19 19 20 extern int ssb_ehci_attach(struct ssb_device *dev, struct usb_hcd **hcd); 21 extern void ssb_ehci_detach(struct ssb_device *dev, struct usb_hcd *hcd); 20 22 21 23 #define SSB_OHCI_TMSLOW_HOSTMODE (1 << 29) 22 24 … … struct ssb_ohci_device { 24 26 struct ohci_hcd ohci; /* _must_ be at the beginning. */ 25 27 26 28 u32 enable_flags; 29 struct usb_hcd *ehci_hcd; 27 30 }; 28 31 29 32 static inline … … static const struct hc_driver ssb_ohci_hc_driver = { 92 95 static void ssb_ohci_detach(struct ssb_device *dev) 93 96 { 94 97 struct usb_hcd *hcd = ssb_get_drvdata(dev); 98 #ifdef CONFIG_USB_EHCI_HCD_SSB 99 struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); 100 #endif 95 101 96 102 usb_remove_hcd(hcd); 97 103 iounmap(hcd->regs); 98 104 usb_put_hcd(hcd); 105 106 #ifdef CONFIG_USB_EHCI_HCD_SSB 107 /* 108 * Also detach ehci function 109 */ 110 if (dev->id.coreid == SSB_DEV_USB20_HOST) 111 ssb_ehci_detach(dev, ohcidev->ehci_hcd); 112 #endif 99 113 ssb_device_disable(dev, 0); 100 114 } 101 115 116 102 117 static int ssb_ohci_attach(struct ssb_device *dev) 103 118 { 104 119 struct ssb_ohci_device *ohcidev; … … static int ssb_ohci_attach(struct ssb_device *dev) 106 121 int err = -ENOMEM; 107 122 u32 tmp, flags = 0; 108 123 109 if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV) 124 /* 125 * THE FOLLOWING COMMENTS PRESERVED FROM GPL SOURCE RELEASE 126 * 127 * The USB core requires a special bit to be set during core 128 * reset to enable host (OHCI) mode. Resetting the SB core in 129 * pcibios_enable_device() is a hack for compatibility with 130 * vanilla usb-ohci so that it does not have to know about 131 * SB. A driver that wants to use the USB core in device mode 132 * should know about SB and should reset the bit back to 0 133 * after calling pcibios_enable_device(). 134 */ 135 136 if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV) { 110 137 flags |= SSB_OHCI_TMSLOW_HOSTMODE; 138 ssb_device_enable(dev, flags); 139 } 140 141 /* 142 * USB 2.0 special considerations: 143 * 144 * 1. Since the core supports both OHCI and EHCI functions, it must 145 * only be reset once. 146 * 147 * 2. In addition to the standard SB reset sequence, the Host Control 148 * Register must be programmed to bring the USB core and various 149 * phy components out of reset. 150 */ 151 152 else if (dev->id.coreid == SSB_DEV_USB20_HOST) { 153 #warning FIX ME need test for core being up & exit 154 ssb_device_enable(dev, 0); 155 ssb_write32(dev, 0x200, 0x7ff); 156 udelay(1); 157 if (dev->id.revision == 1) { // bug in rev 1 158 159 /* Change Flush control reg */ 160 tmp = ssb_read32(dev, 0x400); 161 tmp &= ~8; 162 ssb_write32(dev, 0x400, tmp); 163 tmp = ssb_read32(dev, 0x400); 164 printk("USB20H fcr: 0x%0x\n", tmp); 165 166 /* Change Shim control reg */ 167 tmp = ssb_read32(dev, 0x304); 168 tmp &= ~0x100; 169 ssb_write32(dev, 0x304, tmp); 170 tmp = ssb_read32(dev, 0x304); 171 printk("USB20H shim: 0x%0x\n", tmp); 172 } 173 } 174 else 175 ssb_device_enable(dev, 0); 111 176 112 ssb_device_enable(dev, flags); 177 /* 178 * Set dma mask - 32 bit mask is just an assumption 179 */ 180 if (ssb_dma_set_mask(dev, DMA_32BIT_MASK)) 181 return -EOPNOTSUPP; 113 182 114 183 hcd = usb_create_hcd(&ssb_ohci_hc_driver, dev->dev, 115 184 dev_name(dev->dev)); … … static int ssb_ohci_attach(struct ssb_device *dev) 130 199 131 200 ssb_set_drvdata(dev, hcd); 132 201 202 #ifdef CONFIG_USB_EHCI_HCD_SSB 203 /* 204 * attach ehci function in this core 205 */ 206 if (dev->id.coreid == SSB_DEV_USB20_HOST) 207 err = ssb_ehci_attach(dev, &(ohcidev->ehci_hcd)); 208 #endif 209 133 210 return err; 134 211 135 212 err_iounmap: … … static int ssb_ohci_resume(struct ssb_device *dev) 200 277 static const struct ssb_device_id ssb_ohci_table[] = { 201 278 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV), 202 279 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV), 280 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV), 203 281 SSB_DEVTABLE_END 204 282 }; 205 283 MODULE_DEVICE_TABLE(ssb, ssb_ohci_table); -
drivers/watchdog/Kconfig
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 5eb8f21..fadc751 100644
a b config TXX9_WDT 764 764 help 765 765 Hardware driver for the built-in watchdog timer on TXx9 MIPS SoCs. 766 766 767 config BCM47XX_WDT 768 tristate "Broadcom BCM47xx Watchdog Timer" 769 depends on BCM47XX 770 help 771 Hardware driver for the Broadcom BCM47xx Watchog Timer. 772 767 773 # PARISC Architecture 768 774 769 775 # POWERPC Architecture -
drivers/watchdog/Makefile
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 7f8c56b..99eab0f 100644
a b obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o 105 105 obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o 106 106 obj-$(CONFIG_AR7_WDT) += ar7_wdt.o 107 107 obj-$(CONFIG_TXX9_WDT) += txx9wdt.o 108 obj-$(CONFIG_BCM47XX_WDT) += bcm47xx_wdt.o 108 109 109 110 # PARISC Architecture 110 111 -
new file drivers/watchdog/bcm47xx_wdt.c
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c new file mode 100644 index 0000000..3a192c7
- + 1 /* 2 * Watchdog driver for Broadcom BCM47XX 3 * 4 * Copyright (C) 2008 Aleksandar Radovanovic <biblbroks@sezampro.rs> 5 * Copyright (C) 2009 Matthieu CASTET <castet.matthieu@free.fr> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 10 * 2 of the License, or (at your option) any later version. 11 */ 12 13 #include <linux/bitops.h> 14 #include <linux/errno.h> 15 #include <linux/fs.h> 16 #include <linux/init.h> 17 #include <linux/kernel.h> 18 #include <linux/miscdevice.h> 19 #include <linux/module.h> 20 #include <linux/moduleparam.h> 21 #include <linux/reboot.h> 22 #include <linux/types.h> 23 #include <linux/uaccess.h> 24 #include <linux/watchdog.h> 25 #include <linux/timer.h> 26 #include <linux/jiffies.h> 27 #include <linux/ssb/ssb_embedded.h> 28 #include <asm/mach-bcm47xx/bcm47xx.h> 29 30 #define DRV_NAME "bcm47xx_wdt" 31 32 #define WDT_DEFAULT_TIME 30 /* seconds */ 33 #define WDT_MAX_TIME 256 /* seconds */ 34 35 static int wdt_time = WDT_DEFAULT_TIME; 36 static int nowayout = WATCHDOG_NOWAYOUT; 37 38 module_param(wdt_time, int, 0); 39 MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default=" 40 __MODULE_STRING(WDT_DEFAULT_TIME) ")"); 41 42 #ifdef CONFIG_WATCHDOG_NOWAYOUT 43 module_param(nowayout, int, 0); 44 MODULE_PARM_DESC(nowayout, 45 "Watchdog cannot be stopped once started (default=" 46 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 47 #endif 48 49 static unsigned long bcm47xx_wdt_busy; 50 static char expect_release; 51 static struct timer_list wdt_timer; 52 static atomic_t ticks; 53 54 static inline void bcm47xx_wdt_hw_start(void) 55 { 56 /* this is 2,5s on 100Mhz clock and 2s on 133 Mhz */ 57 ssb_watchdog_timer_set(&ssb_bcm47xx, 0xfffffff); 58 } 59 60 static inline int bcm47xx_wdt_hw_stop(void) 61 { 62 return ssb_watchdog_timer_set(&ssb_bcm47xx, 0); 63 } 64 65 static void bcm47xx_timer_tick(unsigned long unused) 66 { 67 if (!atomic_dec_and_test(&ticks)) { 68 bcm47xx_wdt_hw_start(); 69 mod_timer(&wdt_timer, jiffies + HZ); 70 } else { 71 printk(KERN_CRIT DRV_NAME "Watchdog will fire soon!!!\n"); 72 } 73 } 74 75 static inline void bcm47xx_wdt_pet(void) 76 { 77 atomic_set(&ticks, wdt_time); 78 } 79 80 static void bcm47xx_wdt_start(void) 81 { 82 bcm47xx_wdt_pet(); 83 bcm47xx_timer_tick(0); 84 } 85 86 static void bcm47xx_wdt_pause(void) 87 { 88 del_timer_sync(&wdt_timer); 89 bcm47xx_wdt_hw_stop(); 90 } 91 92 static void bcm47xx_wdt_stop(void) 93 { 94 bcm47xx_wdt_pause(); 95 } 96 97 static int bcm47xx_wdt_settimeout(int new_time) 98 { 99 if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) 100 return -EINVAL; 101 102 wdt_time = new_time; 103 return 0; 104 } 105 106 static int bcm47xx_wdt_open(struct inode *inode, struct file *file) 107 { 108 if (test_and_set_bit(0, &bcm47xx_wdt_busy)) 109 return -EBUSY; 110 111 bcm47xx_wdt_start(); 112 return nonseekable_open(inode, file); 113 } 114 115 static int bcm47xx_wdt_release(struct inode *inode, struct file *file) 116 { 117 if (expect_release == 42) { 118 bcm47xx_wdt_stop(); 119 } else { 120 printk(KERN_CRIT DRV_NAME 121 ": Unexpected close, not stopping watchdog!\n"); 122 bcm47xx_wdt_start(); 123 } 124 125 clear_bit(0, &bcm47xx_wdt_busy); 126 expect_release = 0; 127 return 0; 128 } 129 130 static ssize_t bcm47xx_wdt_write(struct file *file, const char __user *data, 131 size_t len, loff_t *ppos) 132 { 133 if (len) { 134 if (!nowayout) { 135 size_t i; 136 137 expect_release = 0; 138 139 for (i = 0; i != len; i++) { 140 char c; 141 if (get_user(c, data + i)) 142 return -EFAULT; 143 if (c == 'V') 144 expect_release = 42; 145 } 146 } 147 bcm47xx_wdt_pet(); 148 } 149 return len; 150 } 151 152 static struct watchdog_info bcm47xx_wdt_info = { 153 .identity = DRV_NAME, 154 .options = WDIOF_SETTIMEOUT | 155 WDIOF_KEEPALIVEPING | 156 WDIOF_MAGICCLOSE, 157 }; 158 159 static long bcm47xx_wdt_ioctl(struct file *file, 160 unsigned int cmd, unsigned long arg) 161 { 162 void __user *argp = (void __user *)arg; 163 int __user *p = argp; 164 int new_value, retval = -EINVAL;; 165 166 switch (cmd) { 167 case WDIOC_GETSUPPORT: 168 return copy_to_user(argp, &bcm47xx_wdt_info, 169 sizeof(bcm47xx_wdt_info)) ? -EFAULT : 0; 170 171 case WDIOC_GETSTATUS: 172 case WDIOC_GETBOOTSTATUS: 173 return put_user(0, p); 174 175 case WDIOC_SETOPTIONS: 176 if (get_user(new_value, p)) 177 return -EFAULT; 178 179 if (new_value & WDIOS_DISABLECARD) { 180 bcm47xx_wdt_stop(); 181 retval = 0; 182 } 183 184 if (new_value & WDIOS_ENABLECARD) { 185 bcm47xx_wdt_start(); 186 retval = 0; 187 } 188 189 return retval; 190 191 case WDIOC_KEEPALIVE: 192 bcm47xx_wdt_pet(); 193 return 0; 194 195 case WDIOC_SETTIMEOUT: 196 if (get_user(new_value, p)) 197 return -EFAULT; 198 199 if (bcm47xx_wdt_settimeout(new_value)) 200 return -EINVAL; 201 202 bcm47xx_wdt_pet(); 203 204 case WDIOC_GETTIMEOUT: 205 return put_user(wdt_time, p); 206 207 default: 208 return -ENOTTY; 209 } 210 } 211 212 static int bcm47xx_wdt_notify_sys(struct notifier_block *this, 213 unsigned long code, void *unused) 214 { 215 if (code == SYS_DOWN || code == SYS_HALT) 216 bcm47xx_wdt_stop(); 217 return NOTIFY_DONE; 218 } 219 220 static const struct file_operations bcm47xx_wdt_fops = { 221 .owner = THIS_MODULE, 222 .llseek = no_llseek, 223 .unlocked_ioctl = bcm47xx_wdt_ioctl, 224 .open = bcm47xx_wdt_open, 225 .release = bcm47xx_wdt_release, 226 .write = bcm47xx_wdt_write, 227 }; 228 229 static struct miscdevice bcm47xx_wdt_miscdev = { 230 .minor = WATCHDOG_MINOR, 231 .name = "watchdog", 232 .fops = &bcm47xx_wdt_fops, 233 }; 234 235 static struct notifier_block bcm47xx_wdt_notifier = { 236 .notifier_call = bcm47xx_wdt_notify_sys, 237 }; 238 239 static int __init bcm47xx_wdt_init(void) 240 { 241 int ret; 242 243 if (bcm47xx_wdt_hw_stop() < 0) 244 return -ENODEV; 245 246 setup_timer(&wdt_timer, bcm47xx_timer_tick, 0L); 247 248 if (bcm47xx_wdt_settimeout(wdt_time)) { 249 bcm47xx_wdt_settimeout(WDT_DEFAULT_TIME); 250 printk(KERN_INFO DRV_NAME 251 ": wdt_time value must be 1 <= wdt_time <= 256, using %d\n", 252 wdt_time); 253 } 254 255 ret = register_reboot_notifier(&bcm47xx_wdt_notifier); 256 if (ret) 257 return ret; 258 259 ret = misc_register(&bcm47xx_wdt_miscdev); 260 if (ret) { 261 unregister_reboot_notifier(&bcm47xx_wdt_notifier); 262 return ret; 263 } 264 265 printk(KERN_INFO "BCM47xx Watchdog Timer enabled (%d seconds%s)\n", 266 wdt_time, nowayout ? ", nowayout" : ""); 267 return 0; 268 } 269 270 static void __exit bcm47xx_wdt_exit(void) 271 { 272 if (!nowayout) 273 bcm47xx_wdt_stop(); 274 275 misc_deregister(&bcm47xx_wdt_miscdev); 276 277 unregister_reboot_notifier(&bcm47xx_wdt_notifier); 278 } 279 280 module_init(bcm47xx_wdt_init); 281 module_exit(bcm47xx_wdt_exit); 282 283 MODULE_AUTHOR("Aleksandar Radovanovic"); 284 MODULE_DESCRIPTION("Watchdog driver for Broadcom BCM47xx"); 285 MODULE_LICENSE("GPL"); 286 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -
fs/fuse/dev.c
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index ba76b68..c22aefd 100644
a b static void fuse_copy_finish(struct fuse_copy_state *cs) 527 527 } 528 528 } 529 529 530 #ifdef DCACHE_BUG 531 extern void (*fuse_flush_cache_all)(void); 532 extern void (*fuse_flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); 533 #endif 534 530 535 /* 531 536 * Get another pagefull of userspace buffer, and map it to kernel 532 537 * address space, and lock request … … static int fuse_copy_fill(struct fuse_copy_state *cs) 535 540 { 536 541 unsigned long offset; 537 542 int err; 543 #ifdef DCACHE_BUG 544 struct vm_area_struct *vma; 545 #endif 538 546 539 547 unlock_request(cs->fc, cs->req); 540 548 fuse_copy_finish(cs); … … static int fuse_copy_fill(struct fuse_copy_state *cs) 546 554 cs->nr_segs--; 547 555 } 548 556 down_read(¤t->mm->mmap_sem); 557 #ifndef DCACHE_BUG 549 558 err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0, 550 559 &cs->pg, NULL); 560 #else 561 err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0, 562 &cs->pg, &vma); 563 #endif 551 564 up_read(¤t->mm->mmap_sem); 552 565 if (err < 0) 553 566 return err; 554 567 BUG_ON(err != 1); 555 568 offset = cs->addr % PAGE_SIZE; 556 569 cs->mapaddr = kmap_atomic(cs->pg, KM_USER0); 570 #ifdef DCACHE_BUG 571 fuse_flush_cache_page(vma, cs->addr, page_to_pfn(cs->pg)); 572 #endif 557 573 cs->buf = cs->mapaddr + offset; 558 574 cs->len = min(PAGE_SIZE - offset, cs->seglen); 559 575 cs->seglen -= cs->len; … … static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size) 567 583 { 568 584 unsigned ncpy = min(*size, cs->len); 569 585 if (val) { 586 #ifdef DCACHE_BUG 587 // patch from mailing list, it is very important, otherwise, 588 // can't mount, or ls mount point will hang 589 fuse_flush_cache_all(); 590 #endif 570 591 if (cs->write) 571 592 memcpy(cs->buf, *val, ncpy); 572 593 else -
fs/fuse/fuse_i.h
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 6fc5aed..ca2cc6b 100644
a b 8 8 9 9 #ifndef _FS_FUSE_I_H 10 10 #define _FS_FUSE_I_H 11 #define DCACHE_BUG 11 12 12 13 #include <linux/fuse.h> 13 14 #include <linux/fs.h> -
fs/fuse/inode.c
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 91f7c85..8827ce8 100644
a b static int __init fuse_init(void) 1055 1055 printk(KERN_INFO "fuse init (API version %i.%i)\n", 1056 1056 FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION); 1057 1057 1058 #ifdef DCACHE_BUG 1059 printk("fuse init: DCACHE_BUG enabled\n"); 1060 #endif 1061 1058 1062 INIT_LIST_HEAD(&fuse_conn_list); 1059 1063 res = fuse_fs_init(); 1060 1064 if (res) -
include/linux/pci_ids.h
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 0f71812..6087a7d 100644
a b 2106 2106 #define PCI_DEVICE_ID_TIGON3_5906M 0x1713 2107 2107 #define PCI_DEVICE_ID_BCM4401 0x4401 2108 2108 #define PCI_DEVICE_ID_BCM4401B0 0x4402 2109 #define PCI_DEVICE_ID_BCM4713 0x4713 2109 2110 2110 2111 #define PCI_VENDOR_ID_TOPIC 0x151f 2111 2112 #define PCI_DEVICE_ID_TOPIC_TP560 0x0000
Note:
See TracBrowser
for help on using the repository browser.