Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'mips-next' of http://dev.phrozen.org/githttp/mips-next into mips-for-linux-next

+3435 -1225
+6 -5
arch/mips/Kconfig
··· 106 106 107 107 config BCM47XX 108 108 bool "Broadcom BCM47XX based boards" 109 + select ARCH_WANT_OPTIONAL_GPIOLIB 109 110 select CEVT_R4K 110 111 select CSRC_R4K 111 112 select DMA_NONCOHERENT ··· 115 114 select IRQ_CPU 116 115 select SYS_SUPPORTS_32BIT_KERNEL 117 116 select SYS_SUPPORTS_LITTLE_ENDIAN 118 - select GENERIC_GPIO 119 117 select SYS_HAS_EARLY_PRINTK 120 118 help 121 119 Support for BCM47XX based boards ··· 798 798 select CSRC_R4K 799 799 select IRQ_CPU 800 800 select ARCH_SUPPORTS_MSI 801 - select ZONE_DMA if 64BIT 801 + select ZONE_DMA32 if 64BIT 802 802 select SYNC_R4K 803 803 select SYS_HAS_EARLY_PRINTK 804 804 select USB_ARCH_HAS_OHCI if USB_SUPPORT ··· 826 826 select CEVT_R4K 827 827 select CSRC_R4K 828 828 select IRQ_CPU 829 - select ZONE_DMA if 64BIT 829 + select ZONE_DMA32 if 64BIT 830 830 select SYNC_R4K 831 831 select SYS_HAS_EARLY_PRINTK 832 832 select USE_OF ··· 1507 1507 select WEAK_ORDERING 1508 1508 select WEAK_REORDERING_BEYOND_LLSC 1509 1509 select CPU_HAS_PREFETCH 1510 + select CPU_MIPSR2 1510 1511 help 1511 1512 Netlogic Microsystems XLP processors. 1512 1513 endchoice ··· 1719 1718 bool 1720 1719 config MIPS_PGD_C0_CONTEXT 1721 1720 bool 1722 - default y if 64BIT && CPU_MIPSR2 1721 + default y if 64BIT && CPU_MIPSR2 && !CPU_XLP 1723 1722 1724 1723 # 1725 1724 # Set to y for ptrace access to watch registers. ··· 2150 2149 2151 2150 config HW_PERF_EVENTS 2152 2151 bool "Enable hardware performance counter support for perf events" 2153 - depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON) 2152 + depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP) 2154 2153 default y 2155 2154 help 2156 2155 Enable hardware performance counter support for perf events. If
+2
arch/mips/bcm47xx/Kconfig
··· 9 9 select SSB_EMBEDDED 10 10 select SSB_B43_PCI_BRIDGE if PCI 11 11 select SSB_PCICORE_HOSTMODE if PCI 12 + select SSB_DRIVER_GPIO 12 13 default y 13 14 help 14 15 Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support. ··· 24 23 select BCMA_DRIVER_MIPS 25 24 select BCMA_HOST_PCI if PCI 26 25 select BCMA_DRIVER_PCI_HOSTMODE if PCI 26 + select BCMA_DRIVER_GPIO 27 27 default y 28 28 help 29 29 Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
+1 -1
arch/mips/bcm47xx/Makefile
··· 3 3 # under Linux. 4 4 # 5 5 6 - obj-y += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o sprom.o 6 + obj-y += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o 7 7 obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o
-102
arch/mips/bcm47xx/gpio.c
··· 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) 2007 Aurelien Jarno <aurelien@aurel32.net> 7 - */ 8 - 9 - #include <linux/export.h> 10 - #include <linux/ssb/ssb.h> 11 - #include <linux/ssb/ssb_driver_chipcommon.h> 12 - #include <linux/ssb/ssb_driver_extif.h> 13 - #include <asm/mach-bcm47xx/bcm47xx.h> 14 - #include <asm/mach-bcm47xx/gpio.h> 15 - 16 - #if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES) 17 - static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES); 18 - #else 19 - static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES); 20 - #endif 21 - 22 - int gpio_request(unsigned gpio, const char *tag) 23 - { 24 - switch (bcm47xx_bus_type) { 25 - #ifdef CONFIG_BCM47XX_SSB 26 - case BCM47XX_BUS_TYPE_SSB: 27 - if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) && 28 - ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) 29 - return -EINVAL; 30 - 31 - if (ssb_extif_available(&bcm47xx_bus.ssb.extif) && 32 - ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) 33 - return -EINVAL; 34 - 35 - if (test_and_set_bit(gpio, gpio_in_use)) 36 - return -EBUSY; 37 - 38 - return 0; 39 - #endif 40 - #ifdef CONFIG_BCM47XX_BCMA 41 - case BCM47XX_BUS_TYPE_BCMA: 42 - if (gpio >= BCM47XX_CHIPCO_GPIO_LINES) 43 - return -EINVAL; 44 - 45 - if (test_and_set_bit(gpio, gpio_in_use)) 46 - return -EBUSY; 47 - 48 - return 0; 49 - #endif 50 - } 51 - return -EINVAL; 52 - } 53 - EXPORT_SYMBOL(gpio_request); 54 - 55 - void gpio_free(unsigned gpio) 56 - { 57 - switch (bcm47xx_bus_type) { 58 - #ifdef CONFIG_BCM47XX_SSB 59 - case BCM47XX_BUS_TYPE_SSB: 60 - if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) && 61 - ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) 62 - return; 63 - 64 - if (ssb_extif_available(&bcm47xx_bus.ssb.extif) && 65 - ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) 66 - return; 67 - 68 - clear_bit(gpio, gpio_in_use); 69 - return; 70 - #endif 71 - #ifdef CONFIG_BCM47XX_BCMA 72 - case BCM47XX_BUS_TYPE_BCMA: 73 - if (gpio >= BCM47XX_CHIPCO_GPIO_LINES) 74 - return; 75 - 76 - clear_bit(gpio, gpio_in_use); 77 - return; 78 - #endif 79 - } 80 - } 81 - EXPORT_SYMBOL(gpio_free); 82 - 83 - int gpio_to_irq(unsigned gpio) 84 - { 85 - switch (bcm47xx_bus_type) { 86 - #ifdef CONFIG_BCM47XX_SSB 87 - case BCM47XX_BUS_TYPE_SSB: 88 - if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco)) 89 - return ssb_mips_irq(bcm47xx_bus.ssb.chipco.dev) + 2; 90 - else if (ssb_extif_available(&bcm47xx_bus.ssb.extif)) 91 - return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2; 92 - else 93 - return -EINVAL; 94 - #endif 95 - #ifdef CONFIG_BCM47XX_BCMA 96 - case BCM47XX_BUS_TYPE_BCMA: 97 - return bcma_core_mips_irq(bcm47xx_bus.bcma.bus.drv_cc.core) + 2; 98 - #endif 99 - } 100 - return -EINVAL; 101 - } 102 - EXPORT_SYMBOL_GPL(gpio_to_irq);
+16 -4
arch/mips/bcm47xx/prom.c
··· 1 1 /* 2 2 * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> 3 3 * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net> 4 + * Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> 4 5 * 5 6 * This program is free software; you can redistribute it and/or modify it 6 7 * under the terms of the GNU General Public License as published by the ··· 28 27 #include <linux/types.h> 29 28 #include <linux/kernel.h> 30 29 #include <linux/spinlock.h> 30 + #include <linux/smp.h> 31 31 #include <asm/bootinfo.h> 32 32 #include <asm/fw/cfe/cfe_api.h> 33 33 #include <asm/fw/cfe/cfe_error.h> ··· 129 127 { 130 128 unsigned long mem; 131 129 unsigned long max; 130 + unsigned long off; 131 + struct cpuinfo_mips *c = &current_cpu_data; 132 132 133 133 /* Figure out memory size by finding aliases. 134 134 * ··· 147 143 * max contains the biggest possible address supported by the platform. 148 144 * If the method wants to try something above we assume 128MB ram. 149 145 */ 150 - max = ((unsigned long)(prom_init) | ((128 << 20) - 1)); 146 + off = (unsigned long)prom_init; 147 + max = off | ((128 << 20) - 1); 151 148 for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) { 152 - if (((unsigned long)(prom_init) + mem) > max) { 149 + if ((off + mem) > max) { 153 150 mem = (128 << 20); 154 151 printk(KERN_DEBUG "assume 128MB RAM\n"); 155 152 break; 156 153 } 157 - if (*(unsigned long *)((unsigned long)(prom_init) + mem) == 158 - *(unsigned long *)(prom_init)) 154 + if (!memcmp(prom_init, prom_init + mem, 32)) 159 155 break; 160 156 } 157 + 158 + /* Ignoring the last page when ddr size is 128M. Cached 159 + * accesses to last page is causing the processor to prefetch 160 + * using address above 128M stepping out of the ddr address 161 + * space. 162 + */ 163 + if (c->cputype == CPU_74K && (mem == (128 << 20))) 164 + mem -= 0x1000; 161 165 162 166 add_memory_region(0, mem, BOOT_MEM_RAM); 163 167 }
+6 -5
arch/mips/bcm47xx/setup.c
··· 94 94 snprintf(prefix, sizeof(prefix), "pci/%u/%u/", 95 95 bus->host_pci->bus->number + 1, 96 96 PCI_SLOT(bus->host_pci->devfn)); 97 - bcm47xx_fill_sprom(out, prefix); 97 + bcm47xx_fill_sprom(out, prefix, false); 98 98 return 0; 99 99 } else { 100 100 printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n"); ··· 113 113 bcm47xx_fill_ssb_boardinfo(&iv->boardinfo, NULL); 114 114 115 115 memset(&iv->sprom, 0, sizeof(struct ssb_sprom)); 116 - bcm47xx_fill_sprom(&iv->sprom, NULL); 116 + bcm47xx_fill_sprom(&iv->sprom, NULL, false); 117 117 118 118 if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0) 119 119 iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10); ··· 165 165 snprintf(prefix, sizeof(prefix), "pci/%u/%u/", 166 166 bus->host_pci->bus->number + 1, 167 167 PCI_SLOT(bus->host_pci->devfn)); 168 - bcm47xx_fill_sprom(out, prefix); 168 + bcm47xx_fill_sprom(out, prefix, false); 169 169 return 0; 170 170 case BCMA_HOSTTYPE_SOC: 171 171 memset(out, 0, sizeof(struct ssb_sprom)); 172 - bcm47xx_fill_sprom_ethernet(out, NULL); 173 172 core = bcma_find_core(bus, BCMA_CORE_80211); 174 173 if (core) { 175 174 snprintf(prefix, sizeof(prefix), "sb/%u/", 176 175 core->core_index); 177 - bcm47xx_fill_sprom(out, prefix); 176 + bcm47xx_fill_sprom(out, prefix, true); 177 + } else { 178 + bcm47xx_fill_sprom(out, NULL, false); 178 179 } 179 180 return 0; 180 181 default:
+445 -333
arch/mips/bcm47xx/sprom.c
··· 42 42 snprintf(buf, len, "%s", name); 43 43 } 44 44 45 + static int get_nvram_var(const char *prefix, const char *postfix, 46 + const char *name, char *buf, int len, bool fallback) 47 + { 48 + char key[40]; 49 + int err; 50 + 51 + create_key(prefix, postfix, name, key, sizeof(key)); 52 + 53 + err = nvram_getenv(key, buf, len); 54 + if (fallback && err == NVRAM_ERR_ENVNOTFOUND && prefix) { 55 + create_key(NULL, postfix, name, key, sizeof(key)); 56 + err = nvram_getenv(key, buf, len); 57 + } 58 + return err; 59 + } 60 + 45 61 #define NVRAM_READ_VAL(type) \ 46 62 static void nvram_read_ ## type (const char *prefix, \ 47 63 const char *postfix, const char *name, \ 48 - type *val, type allset) \ 64 + type *val, type allset, bool fallback) \ 49 65 { \ 50 66 char buf[100]; \ 51 - char key[40]; \ 52 67 int err; \ 53 68 type var; \ 54 69 \ 55 - create_key(prefix, postfix, name, key, sizeof(key)); \ 56 - \ 57 - err = nvram_getenv(key, buf, sizeof(buf)); \ 70 + err = get_nvram_var(prefix, postfix, name, buf, sizeof(buf), \ 71 + fallback); \ 58 72 if (err < 0) \ 59 73 return; \ 60 74 err = kstrto ## type (buf, 0, &var); \ 61 75 if (err) { \ 62 - pr_warn("can not parse nvram name %s with value %s" \ 63 - " got %i", key, buf, err); \ 76 + pr_warn("can not parse nvram name %s%s%s with value %s got %i\n", \ 77 + prefix, name, postfix, buf, err); \ 64 78 return; \ 65 79 } \ 66 80 if (allset && var == allset) \ ··· 90 76 #undef NVRAM_READ_VAL 91 77 92 78 static void nvram_read_u32_2(const char *prefix, const char *name, 93 - u16 *val_lo, u16 *val_hi) 79 + u16 *val_lo, u16 *val_hi, bool fallback) 94 80 { 95 81 char buf[100]; 96 - char key[40]; 97 82 int err; 98 83 u32 val; 99 84 100 - create_key(prefix, NULL, name, key, sizeof(key)); 101 - 102 - err = nvram_getenv(key, buf, sizeof(buf)); 85 + err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback); 103 86 if (err < 0) 104 87 return; 105 88 err = kstrtou32(buf, 0, &val); 106 89 if (err) { 107 - pr_warn("can not parse nvram name %s with value %s got %i", 108 - key, buf, err); 90 + pr_warn("can not parse nvram name %s%s with value %s got %i\n", 91 + prefix, name, buf, err); 109 92 return; 110 93 } 111 94 *val_lo = (val & 0x0000FFFFU); ··· 110 99 } 111 100 112 101 static void nvram_read_leddc(const char *prefix, const char *name, 113 - u8 *leddc_on_time, u8 *leddc_off_time) 102 + u8 *leddc_on_time, u8 *leddc_off_time, 103 + bool fallback) 114 104 { 115 105 char buf[100]; 116 - char key[40]; 117 106 int err; 118 107 u32 val; 119 108 120 - create_key(prefix, NULL, name, key, sizeof(key)); 121 - 122 - err = nvram_getenv(key, buf, sizeof(buf)); 109 + err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback); 123 110 if (err < 0) 124 111 return; 125 112 err = kstrtou32(buf, 0, &val); 126 113 if (err) { 127 - pr_warn("can not parse nvram name %s with value %s got %i", 128 - key, buf, err); 114 + pr_warn("can not parse nvram name %s%s with value %s got %i\n", 115 + prefix, name, buf, err); 129 116 return; 130 117 } 131 118 ··· 135 126 } 136 127 137 128 static void nvram_read_macaddr(const char *prefix, const char *name, 138 - u8 (*val)[6]) 129 + u8 (*val)[6], bool fallback) 139 130 { 140 131 char buf[100]; 141 - char key[40]; 142 132 int err; 143 133 144 - create_key(prefix, NULL, name, key, sizeof(key)); 145 - 146 - err = nvram_getenv(key, buf, sizeof(buf)); 134 + err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback); 147 135 if (err < 0) 148 136 return; 137 + 149 138 nvram_parse_macaddr(buf, *val); 150 139 } 151 140 152 141 static void nvram_read_alpha2(const char *prefix, const char *name, 153 - char (*val)[2]) 142 + char (*val)[2], bool fallback) 154 143 { 155 144 char buf[10]; 156 - char key[40]; 157 145 int err; 158 146 159 - create_key(prefix, NULL, name, key, sizeof(key)); 160 - 161 - err = nvram_getenv(key, buf, sizeof(buf)); 147 + err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback); 162 148 if (err < 0) 163 149 return; 164 150 if (buf[0] == '0') 165 151 return; 166 152 if (strlen(buf) > 2) { 167 - pr_warn("alpha2 is too long %s", buf); 153 + pr_warn("alpha2 is too long %s\n", buf); 168 154 return; 169 155 } 170 156 memcpy(val, buf, sizeof(val)); 171 157 } 172 158 173 159 static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom, 174 - const char *prefix) 160 + const char *prefix, bool fallback) 175 161 { 176 - nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0); 177 - if (!sprom->board_rev) 178 - nvram_read_u16(NULL, NULL, "boardrev", &sprom->board_rev, 0); 179 - nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0); 180 - nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff); 181 - nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff); 182 - nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff); 183 - nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff); 184 - nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0); 185 - nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0); 186 - nvram_read_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0); 187 - nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0); 188 - nvram_read_alpha2(prefix, "ccode", &sprom->alpha2); 162 + nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff, fallback); 163 + nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff, fallback); 164 + nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff, fallback); 165 + nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff, fallback); 166 + nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0, 167 + fallback); 168 + nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0, 169 + fallback); 170 + nvram_read_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0, 171 + fallback); 172 + nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0, 173 + fallback); 174 + nvram_read_alpha2(prefix, "ccode", &sprom->alpha2, fallback); 189 175 } 190 176 191 177 static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom, 192 - const char *prefix) 178 + const char *prefix, bool fallback) 193 179 { 194 - nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0); 195 - nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0); 196 - nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0); 197 - nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0); 198 - nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0); 199 - nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0); 200 - nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0); 201 - nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0); 202 - nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0); 203 - nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0); 180 + nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0, fallback); 181 + nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0, fallback); 182 + nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0, fallback); 183 + nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0, fallback); 184 + nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0, 185 + fallback); 186 + nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0, fallback); 187 + nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0, fallback); 188 + nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0, fallback); 189 + nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0, fallback); 190 + nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0, fallback); 204 191 } 205 192 206 - static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix) 193 + static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix, 194 + bool fallback) 207 195 { 208 - nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0); 209 - nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0); 196 + nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0, 197 + fallback); 198 + nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0, fallback); 210 199 } 211 200 212 201 static void bcm47xx_fill_sprom_r2389(struct ssb_sprom *sprom, 213 - const char *prefix) 202 + const char *prefix, bool fallback) 214 203 { 215 - nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0); 216 - nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0); 217 - nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0); 218 - nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0); 219 - nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0); 220 - nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0); 221 - nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0); 222 - nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0); 223 - nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0); 204 + nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0, fallback); 205 + nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0, fallback); 206 + nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0, fallback); 207 + nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0, fallback); 208 + nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0, fallback); 209 + nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0, fallback); 210 + nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0, fallback); 211 + nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0, 212 + fallback); 213 + nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0, 214 + fallback); 224 215 } 225 216 226 - static void bcm47xx_fill_sprom_r2(struct ssb_sprom *sprom, const char *prefix) 217 + static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix, 218 + bool fallback) 227 219 { 228 - nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, 229 - &sprom->boardflags_hi); 230 - nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); 220 + nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0, fallback); 221 + nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0, 222 + fallback); 223 + nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0, 224 + fallback); 225 + nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0, 226 + fallback); 227 + nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0, fallback); 228 + nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0, 229 + fallback); 230 + nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0, 231 + fallback); 232 + nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0, 233 + fallback); 234 + nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0, fallback); 235 + nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0, fallback); 236 + nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0, fallback); 237 + nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0, fallback); 238 + nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0, fallback); 239 + nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0, fallback); 231 240 } 232 241 233 - static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix) 242 + static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix, 243 + bool fallback) 234 244 { 235 - nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0); 236 - nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0); 237 - nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0); 238 - nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0); 239 - nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0); 240 - nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0); 241 - nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0); 242 - nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0); 243 - nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0); 244 - nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0); 245 - nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0); 246 - nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0); 247 - nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0); 248 - nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0); 249 - } 250 - 251 - static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix) 252 - { 253 - nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, 254 - &sprom->boardflags_hi); 255 - nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); 256 - nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0); 245 + nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0, fallback); 257 246 nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, 258 - &sprom->leddc_off_time); 247 + &sprom->leddc_off_time, fallback); 259 248 } 260 249 261 250 static void bcm47xx_fill_sprom_r4589(struct ssb_sprom *sprom, 262 - const char *prefix) 251 + const char *prefix, bool fallback) 263 252 { 264 - nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, 265 - &sprom->boardflags_hi); 266 - nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo, 267 - &sprom->boardflags2_hi); 268 - nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); 269 - nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0); 270 - nvram_read_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0); 271 - nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.a3, 0); 272 - nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf); 273 - nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf); 274 - nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff); 253 + nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0, fallback); 254 + nvram_read_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0, 255 + fallback); 256 + nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.a3, 0, 257 + fallback); 258 + nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf, fallback); 259 + nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf, fallback); 260 + nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff, 261 + fallback); 275 262 nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, 276 - &sprom->leddc_off_time); 263 + &sprom->leddc_off_time, fallback); 277 264 } 278 265 279 - static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix) 266 + static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix, 267 + bool fallback) 280 268 { 281 - nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0); 282 - nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0); 283 - nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0); 284 - nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0); 285 - nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0); 286 - nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0); 287 - nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0); 288 - nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0); 289 - nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0); 290 - nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0); 291 - nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0); 292 - nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0); 293 - nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0); 294 - nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0); 295 - nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0); 296 - nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0); 297 - nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0); 298 - nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0); 299 - nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0); 300 - nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0); 301 - nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0); 302 - nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0); 303 - nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0); 304 - nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0); 305 - nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0); 306 - nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0); 307 - nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0); 308 - nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0); 309 - nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0); 310 - nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0); 311 - nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0); 312 - nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0); 313 - nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0); 314 - nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0); 315 - nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0); 316 - nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0); 317 - nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0); 318 - nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0); 319 - nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0); 320 - nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0); 321 - nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0); 269 + nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0, fallback); 270 + nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0, fallback); 271 + nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0, fallback); 272 + nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0, 273 + fallback); 274 + nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0, 275 + fallback); 276 + nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0, fallback); 277 + nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0, fallback); 278 + nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0, fallback); 279 + nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0, fallback); 280 + nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0, 281 + fallback); 282 + nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0, 283 + fallback); 284 + nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0, 285 + fallback); 286 + nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0, 287 + fallback); 288 + nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0, 289 + fallback); 290 + nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0, 291 + fallback); 292 + nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0, 293 + fallback); 294 + nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0, 295 + fallback); 296 + nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0, 297 + fallback); 298 + nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0, 299 + fallback); 300 + nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0, 301 + fallback); 302 + nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0, 303 + fallback); 304 + nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0, 305 + fallback); 306 + nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0, 307 + fallback); 308 + nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0, 309 + fallback); 310 + nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0, 311 + fallback); 312 + nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0, 313 + fallback); 314 + nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0, 315 + fallback); 316 + nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0, 317 + fallback); 318 + nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0, 319 + fallback); 320 + nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0, 321 + fallback); 322 + nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0, 323 + fallback); 324 + nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0, 325 + fallback); 326 + nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0, 327 + fallback); 328 + nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0, 329 + fallback); 330 + nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0, 331 + fallback); 332 + nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0, 333 + fallback); 334 + nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0, 335 + fallback); 336 + nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0, 337 + fallback); 338 + nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0, 339 + fallback); 340 + nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0, 341 + fallback); 342 + nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0, 343 + fallback); 322 344 } 323 345 324 - static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix) 346 + static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix, 347 + bool fallback) 325 348 { 326 - nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0); 327 - nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0); 328 - nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0); 329 - nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0); 330 - nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0); 331 - nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0); 332 - nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0); 333 - nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0); 334 - nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0); 335 - nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0); 336 - nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0); 337 - nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0); 338 - nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0); 339 - nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0); 340 - nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0); 341 - nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0); 349 + nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0, 350 + fallback); 351 + nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0, 352 + fallback); 353 + nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0, 354 + fallback); 355 + nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0, 356 + fallback); 357 + nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0, 358 + fallback); 359 + nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0, 360 + fallback); 361 + nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0, 362 + fallback); 363 + nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0, 364 + fallback); 365 + nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0, 366 + fallback); 367 + nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0, 368 + fallback); 369 + nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0, 370 + fallback); 371 + nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0, 372 + fallback); 373 + nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0, 374 + fallback); 375 + nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0, 376 + fallback); 377 + nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0, 378 + fallback); 379 + nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0, 380 + fallback); 342 381 } 343 382 344 - static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix) 383 + static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix, 384 + bool fallback) 345 385 { 346 - nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0); 386 + nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0, 387 + fallback); 347 388 nvram_read_u8(prefix, NULL, "extpagain2g", 348 - &sprom->fem.ghz2.extpa_gain, 0); 389 + &sprom->fem.ghz2.extpa_gain, 0, fallback); 349 390 nvram_read_u8(prefix, NULL, "pdetrange2g", 350 - &sprom->fem.ghz2.pdet_range, 0); 351 - nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0); 352 - nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0); 353 - nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0); 391 + &sprom->fem.ghz2.pdet_range, 0, fallback); 392 + nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0, 393 + fallback); 394 + nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0, 395 + fallback); 396 + nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0, 397 + fallback); 354 398 nvram_read_u8(prefix, NULL, "extpagain5g", 355 - &sprom->fem.ghz5.extpa_gain, 0); 399 + &sprom->fem.ghz5.extpa_gain, 0, fallback); 356 400 nvram_read_u8(prefix, NULL, "pdetrange5g", 357 - &sprom->fem.ghz5.pdet_range, 0); 358 - nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0); 359 - nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0); 360 - nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0); 361 - nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0); 362 - nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0); 363 - nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0); 401 + &sprom->fem.ghz5.pdet_range, 0, fallback); 402 + nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0, 403 + fallback); 404 + nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0, 405 + fallback); 406 + nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0, 407 + fallback); 408 + nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0, 409 + fallback); 410 + nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0, 411 + fallback); 412 + nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0, 413 + fallback); 364 414 nvram_read_u8(prefix, NULL, "tempsense_slope", 365 - &sprom->tempsense_slope, 0); 366 - nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0); 415 + &sprom->tempsense_slope, 0, fallback); 416 + nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0, 417 + fallback); 367 418 nvram_read_u8(prefix, NULL, "tempsense_option", 368 - &sprom->tempsense_option, 0); 419 + &sprom->tempsense_option, 0, fallback); 369 420 nvram_read_u8(prefix, NULL, "freqoffset_corr", 370 - &sprom->freqoffset_corr, 0); 371 - nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0); 372 - nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0); 373 - nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0); 374 - nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0); 421 + &sprom->freqoffset_corr, 0, fallback); 422 + nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0, 423 + fallback); 424 + nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0, 425 + fallback); 426 + nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0, fallback); 427 + nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0, fallback); 375 428 nvram_read_u8(prefix, NULL, "phycal_tempdelta", 376 - &sprom->phycal_tempdelta, 0); 377 - nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0); 429 + &sprom->phycal_tempdelta, 0, fallback); 430 + nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0, 431 + fallback); 378 432 nvram_read_u8(prefix, NULL, "temps_hysteresis", 379 - &sprom->temps_hysteresis, 0); 380 - nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0); 381 - nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0); 433 + &sprom->temps_hysteresis, 0, fallback); 434 + nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0, 435 + fallback); 436 + nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0, 437 + fallback); 382 438 nvram_read_u8(prefix, NULL, "rxgainerr2ga0", 383 - &sprom->rxgainerr2ga[0], 0); 439 + &sprom->rxgainerr2ga[0], 0, fallback); 384 440 nvram_read_u8(prefix, NULL, "rxgainerr2ga1", 385 - &sprom->rxgainerr2ga[1], 0); 441 + &sprom->rxgainerr2ga[1], 0, fallback); 386 442 nvram_read_u8(prefix, NULL, "rxgainerr2ga2", 387 - &sprom->rxgainerr2ga[2], 0); 443 + &sprom->rxgainerr2ga[2], 0, fallback); 388 444 nvram_read_u8(prefix, NULL, "rxgainerr5gla0", 389 - &sprom->rxgainerr5gla[0], 0); 445 + &sprom->rxgainerr5gla[0], 0, fallback); 390 446 nvram_read_u8(prefix, NULL, "rxgainerr5gla1", 391 - &sprom->rxgainerr5gla[1], 0); 447 + &sprom->rxgainerr5gla[1], 0, fallback); 392 448 nvram_read_u8(prefix, NULL, "rxgainerr5gla2", 393 - &sprom->rxgainerr5gla[2], 0); 449 + &sprom->rxgainerr5gla[2], 0, fallback); 394 450 nvram_read_u8(prefix, NULL, "rxgainerr5gma0", 395 - &sprom->rxgainerr5gma[0], 0); 451 + &sprom->rxgainerr5gma[0], 0, fallback); 396 452 nvram_read_u8(prefix, NULL, "rxgainerr5gma1", 397 - &sprom->rxgainerr5gma[1], 0); 453 + &sprom->rxgainerr5gma[1], 0, fallback); 398 454 nvram_read_u8(prefix, NULL, "rxgainerr5gma2", 399 - &sprom->rxgainerr5gma[2], 0); 455 + &sprom->rxgainerr5gma[2], 0, fallback); 400 456 nvram_read_u8(prefix, NULL, "rxgainerr5gha0", 401 - &sprom->rxgainerr5gha[0], 0); 457 + &sprom->rxgainerr5gha[0], 0, fallback); 402 458 nvram_read_u8(prefix, NULL, "rxgainerr5gha1", 403 - &sprom->rxgainerr5gha[1], 0); 459 + &sprom->rxgainerr5gha[1], 0, fallback); 404 460 nvram_read_u8(prefix, NULL, "rxgainerr5gha2", 405 - &sprom->rxgainerr5gha[2], 0); 461 + &sprom->rxgainerr5gha[2], 0, fallback); 406 462 nvram_read_u8(prefix, NULL, "rxgainerr5gua0", 407 - &sprom->rxgainerr5gua[0], 0); 463 + &sprom->rxgainerr5gua[0], 0, fallback); 408 464 nvram_read_u8(prefix, NULL, "rxgainerr5gua1", 409 - &sprom->rxgainerr5gua[1], 0); 465 + &sprom->rxgainerr5gua[1], 0, fallback); 410 466 nvram_read_u8(prefix, NULL, "rxgainerr5gua2", 411 - &sprom->rxgainerr5gua[2], 0); 412 - nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0); 413 - nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0); 414 - nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0); 467 + &sprom->rxgainerr5gua[2], 0, fallback); 468 + nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0, 469 + fallback); 470 + nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0, 471 + fallback); 472 + nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0, 473 + fallback); 415 474 nvram_read_u8(prefix, NULL, "noiselvl5gla0", 416 - &sprom->noiselvl5gla[0], 0); 475 + &sprom->noiselvl5gla[0], 0, fallback); 417 476 nvram_read_u8(prefix, NULL, "noiselvl5gla1", 418 - &sprom->noiselvl5gla[1], 0); 477 + &sprom->noiselvl5gla[1], 0, fallback); 419 478 nvram_read_u8(prefix, NULL, "noiselvl5gla2", 420 - &sprom->noiselvl5gla[2], 0); 479 + &sprom->noiselvl5gla[2], 0, fallback); 421 480 nvram_read_u8(prefix, NULL, "noiselvl5gma0", 422 - &sprom->noiselvl5gma[0], 0); 481 + &sprom->noiselvl5gma[0], 0, fallback); 423 482 nvram_read_u8(prefix, NULL, "noiselvl5gma1", 424 - &sprom->noiselvl5gma[1], 0); 483 + &sprom->noiselvl5gma[1], 0, fallback); 425 484 nvram_read_u8(prefix, NULL, "noiselvl5gma2", 426 - &sprom->noiselvl5gma[2], 0); 485 + &sprom->noiselvl5gma[2], 0, fallback); 427 486 nvram_read_u8(prefix, NULL, "noiselvl5gha0", 428 - &sprom->noiselvl5gha[0], 0); 487 + &sprom->noiselvl5gha[0], 0, fallback); 429 488 nvram_read_u8(prefix, NULL, "noiselvl5gha1", 430 - &sprom->noiselvl5gha[1], 0); 489 + &sprom->noiselvl5gha[1], 0, fallback); 431 490 nvram_read_u8(prefix, NULL, "noiselvl5gha2", 432 - &sprom->noiselvl5gha[2], 0); 491 + &sprom->noiselvl5gha[2], 0, fallback); 433 492 nvram_read_u8(prefix, NULL, "noiselvl5gua0", 434 - &sprom->noiselvl5gua[0], 0); 493 + &sprom->noiselvl5gua[0], 0, fallback); 435 494 nvram_read_u8(prefix, NULL, "noiselvl5gua1", 436 - &sprom->noiselvl5gua[1], 0); 495 + &sprom->noiselvl5gua[1], 0, fallback); 437 496 nvram_read_u8(prefix, NULL, "noiselvl5gua2", 438 - &sprom->noiselvl5gua[2], 0); 497 + &sprom->noiselvl5gua[2], 0, fallback); 439 498 nvram_read_u8(prefix, NULL, "pcieingress_war", 440 - &sprom->pcieingress_war, 0); 499 + &sprom->pcieingress_war, 0, fallback); 441 500 } 442 501 443 - static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix) 502 + static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix, 503 + bool fallback) 444 504 { 445 - nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0); 446 - nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0); 505 + nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0, 506 + fallback); 507 + nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0, 508 + fallback); 447 509 nvram_read_u32(prefix, NULL, "legofdmbw202gpo", 448 - &sprom->legofdmbw202gpo, 0); 510 + &sprom->legofdmbw202gpo, 0, fallback); 449 511 nvram_read_u32(prefix, NULL, "legofdmbw20ul2gpo", 450 - &sprom->legofdmbw20ul2gpo, 0); 512 + &sprom->legofdmbw20ul2gpo, 0, fallback); 451 513 nvram_read_u32(prefix, NULL, "legofdmbw205glpo", 452 - &sprom->legofdmbw205glpo, 0); 514 + &sprom->legofdmbw205glpo, 0, fallback); 453 515 nvram_read_u32(prefix, NULL, "legofdmbw20ul5glpo", 454 - &sprom->legofdmbw20ul5glpo, 0); 516 + &sprom->legofdmbw20ul5glpo, 0, fallback); 455 517 nvram_read_u32(prefix, NULL, "legofdmbw205gmpo", 456 - &sprom->legofdmbw205gmpo, 0); 518 + &sprom->legofdmbw205gmpo, 0, fallback); 457 519 nvram_read_u32(prefix, NULL, "legofdmbw20ul5gmpo", 458 - &sprom->legofdmbw20ul5gmpo, 0); 520 + &sprom->legofdmbw20ul5gmpo, 0, fallback); 459 521 nvram_read_u32(prefix, NULL, "legofdmbw205ghpo", 460 - &sprom->legofdmbw205ghpo, 0); 522 + &sprom->legofdmbw205ghpo, 0, fallback); 461 523 nvram_read_u32(prefix, NULL, "legofdmbw20ul5ghpo", 462 - &sprom->legofdmbw20ul5ghpo, 0); 463 - nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0); 464 - nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0); 465 - nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0); 466 - nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0); 524 + &sprom->legofdmbw20ul5ghpo, 0, fallback); 525 + nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0, 526 + fallback); 527 + nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0, 528 + fallback); 529 + nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0, 530 + fallback); 531 + nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0, 532 + fallback); 467 533 nvram_read_u32(prefix, NULL, "mcsbw20ul5glpo", 468 - &sprom->mcsbw20ul5glpo, 0); 469 - nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0); 470 - nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0); 534 + &sprom->mcsbw20ul5glpo, 0, fallback); 535 + nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0, 536 + fallback); 537 + nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0, 538 + fallback); 471 539 nvram_read_u32(prefix, NULL, "mcsbw20ul5gmpo", 472 - &sprom->mcsbw20ul5gmpo, 0); 473 - nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0); 474 - nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0); 540 + &sprom->mcsbw20ul5gmpo, 0, fallback); 541 + nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0, 542 + fallback); 543 + nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0, 544 + fallback); 475 545 nvram_read_u32(prefix, NULL, "mcsbw20ul5ghpo", 476 - &sprom->mcsbw20ul5ghpo, 0); 477 - nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0); 478 - nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0); 546 + &sprom->mcsbw20ul5ghpo, 0, fallback); 547 + nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0, 548 + fallback); 549 + nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0, fallback); 479 550 nvram_read_u16(prefix, NULL, "legofdm40duppo", 480 - &sprom->legofdm40duppo, 0); 481 - nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0); 482 - nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0); 551 + &sprom->legofdm40duppo, 0, fallback); 552 + nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0, fallback); 553 + nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0, fallback); 483 554 } 484 555 485 556 static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom, 486 - const char *prefix) 557 + const char *prefix, bool fallback) 487 558 { 488 559 char postfix[2]; 489 560 int i; ··· 572 483 struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; 573 484 snprintf(postfix, sizeof(postfix), "%i", i); 574 485 nvram_read_u8(prefix, postfix, "maxp2ga", 575 - &pwr_info->maxpwr_2g, 0); 486 + &pwr_info->maxpwr_2g, 0, fallback); 576 487 nvram_read_u8(prefix, postfix, "itt2ga", 577 - &pwr_info->itssi_2g, 0); 488 + &pwr_info->itssi_2g, 0, fallback); 578 489 nvram_read_u8(prefix, postfix, "itt5ga", 579 - &pwr_info->itssi_5g, 0); 490 + &pwr_info->itssi_5g, 0, fallback); 580 491 nvram_read_u16(prefix, postfix, "pa2gw0a", 581 - &pwr_info->pa_2g[0], 0); 492 + &pwr_info->pa_2g[0], 0, fallback); 582 493 nvram_read_u16(prefix, postfix, "pa2gw1a", 583 - &pwr_info->pa_2g[1], 0); 494 + &pwr_info->pa_2g[1], 0, fallback); 584 495 nvram_read_u16(prefix, postfix, "pa2gw2a", 585 - &pwr_info->pa_2g[2], 0); 496 + &pwr_info->pa_2g[2], 0, fallback); 586 497 nvram_read_u8(prefix, postfix, "maxp5ga", 587 - &pwr_info->maxpwr_5g, 0); 498 + &pwr_info->maxpwr_5g, 0, fallback); 588 499 nvram_read_u8(prefix, postfix, "maxp5gha", 589 - &pwr_info->maxpwr_5gh, 0); 500 + &pwr_info->maxpwr_5gh, 0, fallback); 590 501 nvram_read_u8(prefix, postfix, "maxp5gla", 591 - &pwr_info->maxpwr_5gl, 0); 502 + &pwr_info->maxpwr_5gl, 0, fallback); 592 503 nvram_read_u16(prefix, postfix, "pa5gw0a", 593 - &pwr_info->pa_5g[0], 0); 504 + &pwr_info->pa_5g[0], 0, fallback); 594 505 nvram_read_u16(prefix, postfix, "pa5gw1a", 595 - &pwr_info->pa_5g[1], 0); 506 + &pwr_info->pa_5g[1], 0, fallback); 596 507 nvram_read_u16(prefix, postfix, "pa5gw2a", 597 - &pwr_info->pa_5g[2], 0); 508 + &pwr_info->pa_5g[2], 0, fallback); 598 509 nvram_read_u16(prefix, postfix, "pa5glw0a", 599 - &pwr_info->pa_5gl[0], 0); 510 + &pwr_info->pa_5gl[0], 0, fallback); 600 511 nvram_read_u16(prefix, postfix, "pa5glw1a", 601 - &pwr_info->pa_5gl[1], 0); 512 + &pwr_info->pa_5gl[1], 0, fallback); 602 513 nvram_read_u16(prefix, postfix, "pa5glw2a", 603 - &pwr_info->pa_5gl[2], 0); 514 + &pwr_info->pa_5gl[2], 0, fallback); 604 515 nvram_read_u16(prefix, postfix, "pa5ghw0a", 605 - &pwr_info->pa_5gh[0], 0); 516 + &pwr_info->pa_5gh[0], 0, fallback); 606 517 nvram_read_u16(prefix, postfix, "pa5ghw1a", 607 - &pwr_info->pa_5gh[1], 0); 518 + &pwr_info->pa_5gh[1], 0, fallback); 608 519 nvram_read_u16(prefix, postfix, "pa5ghw2a", 609 - &pwr_info->pa_5gh[2], 0); 520 + &pwr_info->pa_5gh[2], 0, fallback); 610 521 } 611 522 } 612 523 613 524 static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom, 614 - const char *prefix) 525 + const char *prefix, bool fallback) 615 526 { 616 527 char postfix[2]; 617 528 int i; ··· 620 531 struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; 621 532 snprintf(postfix, sizeof(postfix), "%i", i); 622 533 nvram_read_u16(prefix, postfix, "pa2gw3a", 623 - &pwr_info->pa_2g[3], 0); 534 + &pwr_info->pa_2g[3], 0, fallback); 624 535 nvram_read_u16(prefix, postfix, "pa5gw3a", 625 - &pwr_info->pa_5g[3], 0); 536 + &pwr_info->pa_5g[3], 0, fallback); 626 537 nvram_read_u16(prefix, postfix, "pa5glw3a", 627 - &pwr_info->pa_5gl[3], 0); 538 + &pwr_info->pa_5gl[3], 0, fallback); 628 539 nvram_read_u16(prefix, postfix, "pa5ghw3a", 629 - &pwr_info->pa_5gh[3], 0); 540 + &pwr_info->pa_5gh[3], 0, fallback); 630 541 } 631 542 } 632 543 633 - void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix) 544 + static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, 545 + const char *prefix, bool fallback) 634 546 { 635 - nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac); 636 - nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0); 637 - nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0); 547 + nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac, fallback); 548 + nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0, 549 + fallback); 550 + nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0, 551 + fallback); 638 552 639 - nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac); 640 - nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0); 641 - nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0); 553 + nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac, fallback); 554 + nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0, 555 + fallback); 556 + nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0, 557 + fallback); 642 558 643 - nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac); 644 - nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac); 559 + nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac, fallback); 560 + nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac, fallback); 645 561 } 646 562 647 - void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) 563 + static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix, 564 + bool fallback) 648 565 { 649 - bcm47xx_fill_sprom_ethernet(sprom, prefix); 566 + nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0, 567 + fallback); 568 + nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0, 569 + fallback); 570 + nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0, 571 + fallback); 572 + nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, 573 + &sprom->boardflags_hi, fallback); 574 + nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo, 575 + &sprom->boardflags2_hi, fallback); 576 + } 650 577 651 - nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0); 578 + void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix, 579 + bool fallback) 580 + { 581 + bcm47xx_fill_sprom_ethernet(sprom, prefix, fallback); 582 + bcm47xx_fill_board_data(sprom, prefix, fallback); 583 + 584 + nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0, fallback); 652 585 653 586 switch (sprom->revision) { 654 587 case 1: 655 - bcm47xx_fill_sprom_r1234589(sprom, prefix); 656 - bcm47xx_fill_sprom_r12389(sprom, prefix); 657 - bcm47xx_fill_sprom_r1(sprom, prefix); 588 + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); 589 + bcm47xx_fill_sprom_r12389(sprom, prefix, fallback); 590 + bcm47xx_fill_sprom_r1(sprom, prefix, fallback); 658 591 break; 659 592 case 2: 660 - bcm47xx_fill_sprom_r1234589(sprom, prefix); 661 - bcm47xx_fill_sprom_r12389(sprom, prefix); 662 - bcm47xx_fill_sprom_r2389(sprom, prefix); 663 - bcm47xx_fill_sprom_r2(sprom, prefix); 593 + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); 594 + bcm47xx_fill_sprom_r12389(sprom, prefix, fallback); 595 + bcm47xx_fill_sprom_r2389(sprom, prefix, fallback); 664 596 break; 665 597 case 3: 666 - bcm47xx_fill_sprom_r1234589(sprom, prefix); 667 - bcm47xx_fill_sprom_r12389(sprom, prefix); 668 - bcm47xx_fill_sprom_r2389(sprom, prefix); 669 - bcm47xx_fill_sprom_r389(sprom, prefix); 670 - bcm47xx_fill_sprom_r3(sprom, prefix); 598 + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); 599 + bcm47xx_fill_sprom_r12389(sprom, prefix, fallback); 600 + bcm47xx_fill_sprom_r2389(sprom, prefix, fallback); 601 + bcm47xx_fill_sprom_r389(sprom, prefix, fallback); 602 + bcm47xx_fill_sprom_r3(sprom, prefix, fallback); 671 603 break; 672 604 case 4: 673 605 case 5: 674 - bcm47xx_fill_sprom_r1234589(sprom, prefix); 675 - bcm47xx_fill_sprom_r4589(sprom, prefix); 676 - bcm47xx_fill_sprom_r458(sprom, prefix); 677 - bcm47xx_fill_sprom_r45(sprom, prefix); 678 - bcm47xx_fill_sprom_path_r4589(sprom, prefix); 679 - bcm47xx_fill_sprom_path_r45(sprom, prefix); 606 + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); 607 + bcm47xx_fill_sprom_r4589(sprom, prefix, fallback); 608 + bcm47xx_fill_sprom_r458(sprom, prefix, fallback); 609 + bcm47xx_fill_sprom_r45(sprom, prefix, fallback); 610 + bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback); 611 + bcm47xx_fill_sprom_path_r45(sprom, prefix, fallback); 680 612 break; 681 613 case 8: 682 - bcm47xx_fill_sprom_r1234589(sprom, prefix); 683 - bcm47xx_fill_sprom_r12389(sprom, prefix); 684 - bcm47xx_fill_sprom_r2389(sprom, prefix); 685 - bcm47xx_fill_sprom_r389(sprom, prefix); 686 - bcm47xx_fill_sprom_r4589(sprom, prefix); 687 - bcm47xx_fill_sprom_r458(sprom, prefix); 688 - bcm47xx_fill_sprom_r89(sprom, prefix); 689 - bcm47xx_fill_sprom_path_r4589(sprom, prefix); 614 + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); 615 + bcm47xx_fill_sprom_r12389(sprom, prefix, fallback); 616 + bcm47xx_fill_sprom_r2389(sprom, prefix, fallback); 617 + bcm47xx_fill_sprom_r389(sprom, prefix, fallback); 618 + bcm47xx_fill_sprom_r4589(sprom, prefix, fallback); 619 + bcm47xx_fill_sprom_r458(sprom, prefix, fallback); 620 + bcm47xx_fill_sprom_r89(sprom, prefix, fallback); 621 + bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback); 690 622 break; 691 623 case 9: 692 - bcm47xx_fill_sprom_r1234589(sprom, prefix); 693 - bcm47xx_fill_sprom_r12389(sprom, prefix); 694 - bcm47xx_fill_sprom_r2389(sprom, prefix); 695 - bcm47xx_fill_sprom_r389(sprom, prefix); 696 - bcm47xx_fill_sprom_r4589(sprom, prefix); 697 - bcm47xx_fill_sprom_r89(sprom, prefix); 698 - bcm47xx_fill_sprom_r9(sprom, prefix); 699 - bcm47xx_fill_sprom_path_r4589(sprom, prefix); 624 + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); 625 + bcm47xx_fill_sprom_r12389(sprom, prefix, fallback); 626 + bcm47xx_fill_sprom_r2389(sprom, prefix, fallback); 627 + bcm47xx_fill_sprom_r389(sprom, prefix, fallback); 628 + bcm47xx_fill_sprom_r4589(sprom, prefix, fallback); 629 + bcm47xx_fill_sprom_r89(sprom, prefix, fallback); 630 + bcm47xx_fill_sprom_r9(sprom, prefix, fallback); 631 + bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback); 700 632 break; 701 633 default: 702 634 pr_warn("Unsupported SPROM revision %d detected. Will extract" 703 635 " v1\n", sprom->revision); 704 636 sprom->revision = 1; 705 - bcm47xx_fill_sprom_r1234589(sprom, prefix); 706 - bcm47xx_fill_sprom_r12389(sprom, prefix); 707 - bcm47xx_fill_sprom_r1(sprom, prefix); 637 + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); 638 + bcm47xx_fill_sprom_r12389(sprom, prefix, fallback); 639 + bcm47xx_fill_sprom_r1(sprom, prefix, fallback); 708 640 } 709 641 } 710 642 ··· 733 623 void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo, 734 624 const char *prefix) 735 625 { 736 - nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0); 626 + nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0, 627 + true); 737 628 if (!boardinfo->vendor) 738 629 boardinfo->vendor = SSB_BOARDVENDOR_BCM; 739 630 740 - nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0); 631 + nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); 741 632 } 742 633 #endif 743 634 ··· 746 635 void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo, 747 636 const char *prefix) 748 637 { 749 - nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0); 638 + nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0, 639 + true); 750 640 if (!boardinfo->vendor) 751 641 boardinfo->vendor = SSB_BOARDVENDOR_BCM; 752 642 753 - nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0); 643 + nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); 754 644 } 755 645 #endif
+6 -2
arch/mips/bcm47xx/wgt634u.c
··· 11 11 #include <linux/leds.h> 12 12 #include <linux/mtd/physmap.h> 13 13 #include <linux/ssb/ssb.h> 14 + #include <linux/ssb/ssb_embedded.h> 14 15 #include <linux/interrupt.h> 15 16 #include <linux/reboot.h> 16 17 #include <linux/gpio.h> ··· 117 116 118 117 /* Interrupt are level triggered, revert the interrupt polarity 119 118 to clear the interrupt. */ 120 - gpio_polarity(WGT634U_GPIO_RESET, state); 119 + ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << WGT634U_GPIO_RESET, 120 + state ? 1 << WGT634U_GPIO_RESET : 0); 121 121 122 122 if (!state) { 123 123 printk(KERN_INFO "Reset button pressed"); ··· 152 150 gpio_interrupt, IRQF_SHARED, 153 151 "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) { 154 152 gpio_direction_input(WGT634U_GPIO_RESET); 155 - gpio_intmask(WGT634U_GPIO_RESET, 1); 153 + ssb_gpio_intmask(&bcm47xx_bus.ssb, 154 + 1 << WGT634U_GPIO_RESET, 155 + 1 << WGT634U_GPIO_RESET); 156 156 ssb_chipco_irq_mask(&bcm47xx_bus.ssb.chipco, 157 157 SSB_CHIPCO_IRQ_GPIO, 158 158 SSB_CHIPCO_IRQ_GPIO);
+4 -3
arch/mips/bcm63xx/Makefile
··· 1 - obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ 2 - dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \ 3 - dev-spi.o dev-uart.o dev-wdt.o dev-usb-usbd.o 1 + obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o reset.o \ 2 + setup.o timer.o dev-dsp.o dev-enet.o dev-flash.o \ 3 + dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-wdt.o \ 4 + dev-usb-usbd.o 4 5 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 5 6 6 7 obj-y += boards/
+11 -60
arch/mips/bcm63xx/boards/board_bcm963xx.c
··· 18 18 #include <bcm63xx_dev_uart.h> 19 19 #include <bcm63xx_regs.h> 20 20 #include <bcm63xx_io.h> 21 + #include <bcm63xx_nvram.h> 21 22 #include <bcm63xx_dev_pci.h> 22 23 #include <bcm63xx_dev_enet.h> 23 24 #include <bcm63xx_dev_dsp.h> ··· 30 29 31 30 #define PFX "board_bcm963xx: " 32 31 33 - static struct bcm963xx_nvram nvram; 34 - static unsigned int mac_addr_used; 35 32 static struct board_info board; 36 33 37 34 /* ··· 715 716 } 716 717 717 718 /* 718 - * register & return a new board mac address 719 - */ 720 - static int board_get_mac_address(u8 *mac) 721 - { 722 - u8 *oui; 723 - int count; 724 - 725 - if (mac_addr_used >= nvram.mac_addr_count) { 726 - printk(KERN_ERR PFX "not enough mac address\n"); 727 - return -ENODEV; 728 - } 729 - 730 - memcpy(mac, nvram.mac_addr_base, ETH_ALEN); 731 - oui = mac + ETH_ALEN/2 - 1; 732 - count = mac_addr_used; 733 - 734 - while (count--) { 735 - u8 *p = mac + ETH_ALEN - 1; 736 - 737 - do { 738 - (*p)++; 739 - if (*p != 0) 740 - break; 741 - p--; 742 - } while (p != oui); 743 - 744 - if (p == oui) { 745 - printk(KERN_ERR PFX "unable to fetch mac address\n"); 746 - return -ENODEV; 747 - } 748 - } 749 - 750 - mac_addr_used++; 751 - return 0; 752 - } 753 - 754 - /* 755 719 * early init callback, read nvram data from flash and checksum it 756 720 */ 757 721 void __init board_prom_init(void) 758 722 { 759 - unsigned int check_len, i; 760 - u8 *boot_addr, *cfe, *p; 723 + unsigned int i; 724 + u8 *boot_addr, *cfe; 761 725 char cfe_version[32]; 726 + char *board_name; 762 727 u32 val; 763 728 764 729 /* read base address of boot chip select (0) ··· 745 782 strcpy(cfe_version, "unknown"); 746 783 printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); 747 784 748 - /* extract nvram data */ 749 - memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram)); 750 - 751 - /* check checksum before using data */ 752 - if (nvram.version <= 4) 753 - check_len = offsetof(struct bcm963xx_nvram, checksum_old); 754 - else 755 - check_len = sizeof(nvram); 756 - val = 0; 757 - p = (u8 *)&nvram; 758 - while (check_len--) 759 - val += *p; 760 - if (val) { 785 + if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) { 761 786 printk(KERN_ERR PFX "invalid nvram checksum\n"); 762 787 return; 763 788 } 764 789 790 + board_name = bcm63xx_nvram_get_name(); 765 791 /* find board by name */ 766 792 for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { 767 - if (strncmp(nvram.name, bcm963xx_boards[i]->name, 768 - sizeof(nvram.name))) 793 + if (strncmp(board_name, bcm963xx_boards[i]->name, 16)) 769 794 continue; 770 795 /* copy, board desc array is marked initdata */ 771 796 memcpy(&board, bcm963xx_boards[i], sizeof(board)); ··· 763 812 /* bail out if board is not found, will complain later */ 764 813 if (!board.name[0]) { 765 814 char name[17]; 766 - memcpy(name, nvram.name, 16); 815 + memcpy(name, board_name, 16); 767 816 name[16] = 0; 768 817 printk(KERN_ERR PFX "unknown bcm963xx board: %s\n", 769 818 name); ··· 841 890 bcm63xx_pcmcia_register(); 842 891 843 892 if (board.has_enet0 && 844 - !board_get_mac_address(board.enet0.mac_addr)) 893 + !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr)) 845 894 bcm63xx_enet_register(0, &board.enet0); 846 895 847 896 if (board.has_enet1 && 848 - !board_get_mac_address(board.enet1.mac_addr)) 897 + !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr)) 849 898 bcm63xx_enet_register(1, &board.enet1); 850 899 851 900 if (board.has_usbd) ··· 858 907 * do this after registering enet devices 859 908 */ 860 909 #ifdef CONFIG_SSB_PCIHOST 861 - if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { 910 + if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { 862 911 memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); 863 912 memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); 864 913 if (ssb_arch_register_fallback_sprom(
+20 -14
arch/mips/bcm63xx/clk.c
··· 14 14 #include <bcm63xx_cpu.h> 15 15 #include <bcm63xx_io.h> 16 16 #include <bcm63xx_regs.h> 17 + #include <bcm63xx_reset.h> 17 18 #include <bcm63xx_clk.h> 18 19 19 20 static DEFINE_MUTEX(clocks_mutex); ··· 125 124 CKCTL_6368_SWPKT_USB_EN | 126 125 CKCTL_6368_SWPKT_SAR_EN, enable); 127 126 if (enable) { 128 - u32 val; 129 - 130 127 /* reset switch core afer clock change */ 131 - val = bcm_perf_readl(PERF_SOFTRESET_6368_REG); 132 - val &= ~SOFTRESET_6368_ENETSW_MASK; 133 - bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); 128 + bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 1); 134 129 msleep(10); 135 - val |= SOFTRESET_6368_ENETSW_MASK; 136 - bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); 130 + bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 0); 137 131 msleep(10); 138 132 } 139 133 } ··· 218 222 CKCTL_6368_SWPKT_SAR_EN, enable); 219 223 220 224 if (enable) { 221 - u32 val; 222 - 223 225 /* reset sar core afer clock change */ 224 - val = bcm_perf_readl(PERF_SOFTRESET_6368_REG); 225 - val &= ~SOFTRESET_6368_SAR_MASK; 226 - bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); 226 + bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 1); 227 227 mdelay(1); 228 - val |= SOFTRESET_6368_SAR_MASK; 229 - bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); 228 + bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 0); 230 229 mdelay(1); 231 230 } 232 231 } ··· 241 250 242 251 static struct clk clk_ipsec = { 243 252 .set = ipsec_set, 253 + }; 254 + 255 + /* 256 + * PCIe clock 257 + */ 258 + 259 + static void pcie_set(struct clk *clk, int enable) 260 + { 261 + bcm_hwclock_set(CKCTL_6328_PCIE_EN, enable); 262 + } 263 + 264 + static struct clk clk_pcie = { 265 + .set = pcie_set, 244 266 }; 245 267 246 268 /* ··· 317 313 return &clk_pcm; 318 314 if (BCMCPU_IS_6368() && !strcmp(id, "ipsec")) 319 315 return &clk_ipsec; 316 + if (BCMCPU_IS_6328() && !strcmp(id, "pcie")) 317 + return &clk_pcie; 320 318 return ERR_PTR(-ENOENT); 321 319 } 322 320
+107
arch/mips/bcm63xx/nvram.c
··· 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) 2008 Maxime Bizon <mbizon@freebox.fr> 7 + * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> 8 + * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com> 9 + */ 10 + 11 + #define pr_fmt(fmt) "bcm63xx_nvram: " fmt 12 + 13 + #include <linux/init.h> 14 + #include <linux/crc32.h> 15 + #include <linux/export.h> 16 + #include <linux/kernel.h> 17 + #include <linux/if_ether.h> 18 + 19 + #include <bcm63xx_nvram.h> 20 + 21 + /* 22 + * nvram structure 23 + */ 24 + struct bcm963xx_nvram { 25 + u32 version; 26 + u8 reserved1[256]; 27 + u8 name[16]; 28 + u32 main_tp_number; 29 + u32 psi_size; 30 + u32 mac_addr_count; 31 + u8 mac_addr_base[ETH_ALEN]; 32 + u8 reserved2[2]; 33 + u32 checksum_old; 34 + u8 reserved3[720]; 35 + u32 checksum_high; 36 + }; 37 + 38 + static struct bcm963xx_nvram nvram; 39 + static int mac_addr_used; 40 + 41 + int __init bcm63xx_nvram_init(void *addr) 42 + { 43 + unsigned int check_len; 44 + u32 crc, expected_crc; 45 + 46 + /* extract nvram data */ 47 + memcpy(&nvram, addr, sizeof(nvram)); 48 + 49 + /* check checksum before using data */ 50 + if (nvram.version <= 4) { 51 + check_len = offsetof(struct bcm963xx_nvram, reserved3); 52 + expected_crc = nvram.checksum_old; 53 + nvram.checksum_old = 0; 54 + } else { 55 + check_len = sizeof(nvram); 56 + expected_crc = nvram.checksum_high; 57 + nvram.checksum_high = 0; 58 + } 59 + 60 + crc = crc32_le(~0, (u8 *)&nvram, check_len); 61 + 62 + if (crc != expected_crc) 63 + return -EINVAL; 64 + 65 + return 0; 66 + } 67 + 68 + u8 *bcm63xx_nvram_get_name(void) 69 + { 70 + return nvram.name; 71 + } 72 + EXPORT_SYMBOL(bcm63xx_nvram_get_name); 73 + 74 + int bcm63xx_nvram_get_mac_address(u8 *mac) 75 + { 76 + u8 *oui; 77 + int count; 78 + 79 + if (mac_addr_used >= nvram.mac_addr_count) { 80 + pr_err("not enough mac addresses\n"); 81 + return -ENODEV; 82 + } 83 + 84 + memcpy(mac, nvram.mac_addr_base, ETH_ALEN); 85 + oui = mac + ETH_ALEN/2 - 1; 86 + count = mac_addr_used; 87 + 88 + while (count--) { 89 + u8 *p = mac + ETH_ALEN - 1; 90 + 91 + do { 92 + (*p)++; 93 + if (*p != 0) 94 + break; 95 + p--; 96 + } while (p != oui); 97 + 98 + if (p == oui) { 99 + pr_err("unable to fetch mac address\n"); 100 + return -ENODEV; 101 + } 102 + } 103 + 104 + mac_addr_used++; 105 + return 0; 106 + } 107 + EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address);
+223
arch/mips/bcm63xx/reset.c
··· 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) 2012 Jonas Gorski <jonas.gorski@gmail.com> 7 + */ 8 + 9 + #include <linux/module.h> 10 + #include <linux/mutex.h> 11 + #include <linux/err.h> 12 + #include <linux/clk.h> 13 + #include <linux/delay.h> 14 + #include <bcm63xx_cpu.h> 15 + #include <bcm63xx_io.h> 16 + #include <bcm63xx_regs.h> 17 + #include <bcm63xx_reset.h> 18 + 19 + #define __GEN_RESET_BITS_TABLE(__cpu) \ 20 + [BCM63XX_RESET_SPI] = BCM## __cpu ##_RESET_SPI, \ 21 + [BCM63XX_RESET_ENET] = BCM## __cpu ##_RESET_ENET, \ 22 + [BCM63XX_RESET_USBH] = BCM## __cpu ##_RESET_USBH, \ 23 + [BCM63XX_RESET_USBD] = BCM## __cpu ##_RESET_USBD, \ 24 + [BCM63XX_RESET_DSL] = BCM## __cpu ##_RESET_DSL, \ 25 + [BCM63XX_RESET_SAR] = BCM## __cpu ##_RESET_SAR, \ 26 + [BCM63XX_RESET_EPHY] = BCM## __cpu ##_RESET_EPHY, \ 27 + [BCM63XX_RESET_ENETSW] = BCM## __cpu ##_RESET_ENETSW, \ 28 + [BCM63XX_RESET_PCM] = BCM## __cpu ##_RESET_PCM, \ 29 + [BCM63XX_RESET_MPI] = BCM## __cpu ##_RESET_MPI, \ 30 + [BCM63XX_RESET_PCIE] = BCM## __cpu ##_RESET_PCIE, \ 31 + [BCM63XX_RESET_PCIE_EXT] = BCM## __cpu ##_RESET_PCIE_EXT, 32 + 33 + #define BCM6328_RESET_SPI SOFTRESET_6328_SPI_MASK 34 + #define BCM6328_RESET_ENET 0 35 + #define BCM6328_RESET_USBH SOFTRESET_6328_USBH_MASK 36 + #define BCM6328_RESET_USBD SOFTRESET_6328_USBS_MASK 37 + #define BCM6328_RESET_DSL 0 38 + #define BCM6328_RESET_SAR SOFTRESET_6328_SAR_MASK 39 + #define BCM6328_RESET_EPHY SOFTRESET_6328_EPHY_MASK 40 + #define BCM6328_RESET_ENETSW SOFTRESET_6328_ENETSW_MASK 41 + #define BCM6328_RESET_PCM SOFTRESET_6328_PCM_MASK 42 + #define BCM6328_RESET_MPI 0 43 + #define BCM6328_RESET_PCIE \ 44 + (SOFTRESET_6328_PCIE_MASK | \ 45 + SOFTRESET_6328_PCIE_CORE_MASK | \ 46 + SOFTRESET_6328_PCIE_HARD_MASK) 47 + #define BCM6328_RESET_PCIE_EXT SOFTRESET_6328_PCIE_EXT_MASK 48 + 49 + #define BCM6338_RESET_SPI SOFTRESET_6338_SPI_MASK 50 + #define BCM6338_RESET_ENET SOFTRESET_6338_ENET_MASK 51 + #define BCM6338_RESET_USBH SOFTRESET_6338_USBH_MASK 52 + #define BCM6338_RESET_USBD SOFTRESET_6338_USBS_MASK 53 + #define BCM6338_RESET_DSL SOFTRESET_6338_ADSL_MASK 54 + #define BCM6338_RESET_SAR SOFTRESET_6338_SAR_MASK 55 + #define BCM6338_RESET_EPHY 0 56 + #define BCM6338_RESET_ENETSW 0 57 + #define BCM6338_RESET_PCM 0 58 + #define BCM6338_RESET_MPI 0 59 + #define BCM6338_RESET_PCIE 0 60 + #define BCM6338_RESET_PCIE_EXT 0 61 + 62 + #define BCM6348_RESET_SPI SOFTRESET_6348_SPI_MASK 63 + #define BCM6348_RESET_ENET SOFTRESET_6348_ENET_MASK 64 + #define BCM6348_RESET_USBH SOFTRESET_6348_USBH_MASK 65 + #define BCM6348_RESET_USBD SOFTRESET_6348_USBS_MASK 66 + #define BCM6348_RESET_DSL SOFTRESET_6348_ADSL_MASK 67 + #define BCM6348_RESET_SAR SOFTRESET_6348_SAR_MASK 68 + #define BCM6348_RESET_EPHY 0 69 + #define BCM6348_RESET_ENETSW 0 70 + #define BCM6348_RESET_PCM 0 71 + #define BCM6348_RESET_MPI 0 72 + #define BCM6348_RESET_PCIE 0 73 + #define BCM6348_RESET_PCIE_EXT 0 74 + 75 + #define BCM6358_RESET_SPI SOFTRESET_6358_SPI_MASK 76 + #define BCM6358_RESET_ENET SOFTRESET_6358_ENET_MASK 77 + #define BCM6358_RESET_USBH SOFTRESET_6358_USBH_MASK 78 + #define BCM6358_RESET_USBD 0 79 + #define BCM6358_RESET_DSL SOFTRESET_6358_ADSL_MASK 80 + #define BCM6358_RESET_SAR SOFTRESET_6358_SAR_MASK 81 + #define BCM6358_RESET_EPHY SOFTRESET_6358_EPHY_MASK 82 + #define BCM6358_RESET_ENETSW 0 83 + #define BCM6358_RESET_PCM SOFTRESET_6358_PCM_MASK 84 + #define BCM6358_RESET_MPI SOFTRESET_6358_MPI_MASK 85 + #define BCM6358_RESET_PCIE 0 86 + #define BCM6358_RESET_PCIE_EXT 0 87 + 88 + #define BCM6368_RESET_SPI SOFTRESET_6368_SPI_MASK 89 + #define BCM6368_RESET_ENET 0 90 + #define BCM6368_RESET_USBH SOFTRESET_6368_USBH_MASK 91 + #define BCM6368_RESET_USBD SOFTRESET_6368_USBS_MASK 92 + #define BCM6368_RESET_DSL 0 93 + #define BCM6368_RESET_SAR SOFTRESET_6368_SAR_MASK 94 + #define BCM6368_RESET_EPHY SOFTRESET_6368_EPHY_MASK 95 + #define BCM6368_RESET_ENETSW 0 96 + #define BCM6368_RESET_PCM SOFTRESET_6368_PCM_MASK 97 + #define BCM6368_RESET_MPI SOFTRESET_6368_MPI_MASK 98 + #define BCM6368_RESET_PCIE 0 99 + #define BCM6368_RESET_PCIE_EXT 0 100 + 101 + #ifdef BCMCPU_RUNTIME_DETECT 102 + 103 + /* 104 + * core reset bits 105 + */ 106 + static const u32 bcm6328_reset_bits[] = { 107 + __GEN_RESET_BITS_TABLE(6328) 108 + }; 109 + 110 + static const u32 bcm6338_reset_bits[] = { 111 + __GEN_RESET_BITS_TABLE(6338) 112 + }; 113 + 114 + static const u32 bcm6348_reset_bits[] = { 115 + __GEN_RESET_BITS_TABLE(6348) 116 + }; 117 + 118 + static const u32 bcm6358_reset_bits[] = { 119 + __GEN_RESET_BITS_TABLE(6358) 120 + }; 121 + 122 + static const u32 bcm6368_reset_bits[] = { 123 + __GEN_RESET_BITS_TABLE(6368) 124 + }; 125 + 126 + const u32 *bcm63xx_reset_bits; 127 + static int reset_reg; 128 + 129 + static int __init bcm63xx_reset_bits_init(void) 130 + { 131 + if (BCMCPU_IS_6328()) { 132 + reset_reg = PERF_SOFTRESET_6328_REG; 133 + bcm63xx_reset_bits = bcm6328_reset_bits; 134 + } else if (BCMCPU_IS_6338()) { 135 + reset_reg = PERF_SOFTRESET_REG; 136 + bcm63xx_reset_bits = bcm6338_reset_bits; 137 + } else if (BCMCPU_IS_6348()) { 138 + reset_reg = PERF_SOFTRESET_REG; 139 + bcm63xx_reset_bits = bcm6348_reset_bits; 140 + } else if (BCMCPU_IS_6358()) { 141 + reset_reg = PERF_SOFTRESET_6358_REG; 142 + bcm63xx_reset_bits = bcm6358_reset_bits; 143 + } else if (BCMCPU_IS_6368()) { 144 + reset_reg = PERF_SOFTRESET_6368_REG; 145 + bcm63xx_reset_bits = bcm6368_reset_bits; 146 + } 147 + 148 + return 0; 149 + } 150 + #else 151 + 152 + #ifdef CONFIG_BCM63XX_CPU_6328 153 + static const u32 bcm63xx_reset_bits[] = { 154 + __GEN_RESET_BITS_TABLE(6328) 155 + }; 156 + #define reset_reg PERF_SOFTRESET_6328_REG 157 + #endif 158 + 159 + #ifdef CONFIG_BCM63XX_CPU_6338 160 + static const u32 bcm63xx_reset_bits[] = { 161 + __GEN_RESET_BITS_TABLE(6338) 162 + }; 163 + #define reset_reg PERF_SOFTRESET_REG 164 + #endif 165 + 166 + #ifdef CONFIG_BCM63XX_CPU_6345 167 + static const u32 bcm63xx_reset_bits[] = { }; 168 + #define reset_reg 0 169 + #endif 170 + 171 + #ifdef CONFIG_BCM63XX_CPU_6348 172 + static const u32 bcm63xx_reset_bits[] = { 173 + __GEN_RESET_BITS_TABLE(6348) 174 + }; 175 + #define reset_reg PERF_SOFTRESET_REG 176 + #endif 177 + 178 + #ifdef CONFIG_BCM63XX_CPU_6358 179 + static const u32 bcm63xx_reset_bits[] = { 180 + __GEN_RESET_BITS_TABLE(6358) 181 + }; 182 + #define reset_reg PERF_SOFTRESET_6358_REG 183 + #endif 184 + 185 + #ifdef CONFIG_BCM63XX_CPU_6368 186 + static const u32 bcm63xx_reset_bits[] = { 187 + __GEN_RESET_BITS_TABLE(6368) 188 + }; 189 + #define reset_reg PERF_SOFTRESET_6368_REG 190 + #endif 191 + 192 + static int __init bcm63xx_reset_bits_init(void) { return 0; } 193 + #endif 194 + 195 + static DEFINE_SPINLOCK(reset_mutex); 196 + 197 + static void __bcm63xx_core_set_reset(u32 mask, int enable) 198 + { 199 + unsigned long flags; 200 + u32 val; 201 + 202 + if (!mask) 203 + return; 204 + 205 + spin_lock_irqsave(&reset_mutex, flags); 206 + val = bcm_perf_readl(reset_reg); 207 + 208 + if (enable) 209 + val &= ~mask; 210 + else 211 + val |= mask; 212 + 213 + bcm_perf_writel(val, reset_reg); 214 + spin_unlock_irqrestore(&reset_mutex, flags); 215 + } 216 + 217 + void bcm63xx_core_set_reset(enum bcm63xx_core_reset core, int reset) 218 + { 219 + __bcm63xx_core_set_reset(bcm63xx_reset_bits[core], reset); 220 + } 221 + EXPORT_SYMBOL(bcm63xx_core_set_reset); 222 + 223 + postcore_initcall(bcm63xx_reset_bits_init);
+2 -1
arch/mips/cavium-octeon/flash_setup.c
··· 51 51 flash_map.name = "phys_mapped_flash"; 52 52 flash_map.phys = region_cfg.s.base << 16; 53 53 flash_map.size = 0x1fc00000 - flash_map.phys; 54 - flash_map.bankwidth = 1; 54 + /* 8-bit bus (0 + 1) or 16-bit bus (1 + 1) */ 55 + flash_map.bankwidth = region_cfg.s.width + 1; 55 56 flash_map.virt = ioremap(flash_map.phys, flash_map.size); 56 57 pr_notice("Bootbus flash: Setting flash for %luMB flash at " 57 58 "0x%08llx\n", flash_map.size >> 20, flash_map.phys);
+111
arch/mips/configs/ath79_defconfig
··· 1 + CONFIG_ATH79=y 2 + CONFIG_ATH79_MACH_AP121=y 3 + CONFIG_ATH79_MACH_AP81=y 4 + CONFIG_ATH79_MACH_DB120=y 5 + CONFIG_ATH79_MACH_PB44=y 6 + CONFIG_ATH79_MACH_UBNT_XM=y 7 + CONFIG_HZ_100=y 8 + # CONFIG_SECCOMP is not set 9 + CONFIG_EXPERIMENTAL=y 10 + # CONFIG_LOCALVERSION_AUTO is not set 11 + CONFIG_SYSVIPC=y 12 + CONFIG_HIGH_RES_TIMERS=y 13 + CONFIG_BLK_DEV_INITRD=y 14 + # CONFIG_RD_GZIP is not set 15 + CONFIG_RD_LZMA=y 16 + # CONFIG_KALLSYMS is not set 17 + # CONFIG_AIO is not set 18 + CONFIG_EMBEDDED=y 19 + # CONFIG_VM_EVENT_COUNTERS is not set 20 + # CONFIG_SLUB_DEBUG is not set 21 + # CONFIG_COMPAT_BRK is not set 22 + CONFIG_MODULES=y 23 + CONFIG_MODULE_UNLOAD=y 24 + # CONFIG_BLK_DEV_BSG is not set 25 + # CONFIG_IOSCHED_CFQ is not set 26 + CONFIG_PCI=y 27 + # CONFIG_SUSPEND is not set 28 + CONFIG_NET=y 29 + CONFIG_PACKET=y 30 + CONFIG_UNIX=y 31 + CONFIG_INET=y 32 + CONFIG_IP_MULTICAST=y 33 + CONFIG_IP_ADVANCED_ROUTER=y 34 + # CONFIG_INET_XFRM_MODE_TRANSPORT is not set 35 + # CONFIG_INET_XFRM_MODE_TUNNEL is not set 36 + # CONFIG_INET_XFRM_MODE_BEET is not set 37 + # CONFIG_INET_LRO is not set 38 + # CONFIG_IPV6 is not set 39 + CONFIG_CFG80211=m 40 + CONFIG_MAC80211=m 41 + CONFIG_MAC80211_DEBUGFS=y 42 + CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 43 + # CONFIG_FIRMWARE_IN_KERNEL is not set 44 + CONFIG_MTD=y 45 + CONFIG_MTD_REDBOOT_PARTS=y 46 + CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-2 47 + CONFIG_MTD_CMDLINE_PARTS=y 48 + CONFIG_MTD_CHAR=y 49 + CONFIG_MTD_BLOCK=y 50 + CONFIG_MTD_CFI=y 51 + CONFIG_MTD_JEDECPROBE=y 52 + CONFIG_MTD_CFI_AMDSTD=y 53 + CONFIG_MTD_COMPLEX_MAPPINGS=y 54 + CONFIG_MTD_PHYSMAP=y 55 + CONFIG_MTD_M25P80=y 56 + # CONFIG_M25PXX_USE_FAST_READ is not set 57 + CONFIG_NETDEVICES=y 58 + # CONFIG_NET_PACKET_ENGINE is not set 59 + CONFIG_ATH_COMMON=m 60 + CONFIG_ATH9K=m 61 + CONFIG_ATH9K_AHB=y 62 + CONFIG_INPUT=m 63 + # CONFIG_INPUT_MOUSEDEV is not set 64 + # CONFIG_KEYBOARD_ATKBD is not set 65 + CONFIG_KEYBOARD_GPIO_POLLED=m 66 + # CONFIG_INPUT_MOUSE is not set 67 + CONFIG_INPUT_MISC=y 68 + # CONFIG_SERIO is not set 69 + # CONFIG_VT is not set 70 + # CONFIG_LEGACY_PTYS is not set 71 + # CONFIG_DEVKMEM is not set 72 + CONFIG_SERIAL_8250=y 73 + CONFIG_SERIAL_8250_CONSOLE=y 74 + # CONFIG_SERIAL_8250_PCI is not set 75 + CONFIG_SERIAL_8250_NR_UARTS=1 76 + CONFIG_SERIAL_8250_RUNTIME_UARTS=1 77 + CONFIG_SERIAL_AR933X=y 78 + CONFIG_SERIAL_AR933X_CONSOLE=y 79 + # CONFIG_HW_RANDOM is not set 80 + CONFIG_I2C=y 81 + # CONFIG_I2C_COMPAT is not set 82 + # CONFIG_I2C_HELPER_AUTO is not set 83 + CONFIG_I2C_GPIO=y 84 + CONFIG_SPI=y 85 + CONFIG_SPI_ATH79=y 86 + CONFIG_SPI_GPIO=y 87 + CONFIG_GPIO_SYSFS=y 88 + CONFIG_GPIO_PCF857X=y 89 + # CONFIG_HWMON is not set 90 + CONFIG_WATCHDOG=y 91 + CONFIG_ATH79_WDT=y 92 + # CONFIG_VGA_ARB is not set 93 + # CONFIG_HID is not set 94 + # CONFIG_USB_HID is not set 95 + CONFIG_USB=y 96 + CONFIG_USB_EHCI_HCD=y 97 + # CONFIG_USB_EHCI_TT_NEWSCHED is not set 98 + CONFIG_USB_OHCI_HCD=y 99 + CONFIG_LEDS_CLASS=y 100 + CONFIG_LEDS_GPIO=y 101 + # CONFIG_IOMMU_SUPPORT is not set 102 + # CONFIG_DNOTIFY is not set 103 + # CONFIG_PROC_PAGE_MONITOR is not set 104 + # CONFIG_ENABLE_MUST_CHECK is not set 105 + CONFIG_STRIP_ASM_SYMS=y 106 + CONFIG_DEBUG_FS=y 107 + # CONFIG_SCHED_DEBUG is not set 108 + # CONFIG_FTRACE is not set 109 + CONFIG_CRYPTO=y 110 + # CONFIG_CRYPTO_ANSI_CPRNG is not set 111 + CONFIG_CRC_ITU_T=m
+2 -2
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
··· 44 44 extern union bcm47xx_bus bcm47xx_bus; 45 45 extern enum bcm47xx_bus_type bcm47xx_bus_type; 46 46 47 - void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix); 48 - void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix); 47 + void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix, 48 + bool fallback); 49 49 50 50 #ifdef CONFIG_BCM47XX_SSB 51 51 void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo,
+8 -146
arch/mips/include/asm/mach-bcm47xx/gpio.h
··· 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) 2007 Aurelien Jarno <aurelien@aurel32.net> 7 - */ 1 + #ifndef __ASM_MIPS_MACH_BCM47XX_GPIO_H 2 + #define __ASM_MIPS_MACH_BCM47XX_GPIO_H 8 3 9 - #ifndef __BCM47XX_GPIO_H 10 - #define __BCM47XX_GPIO_H 4 + #include <asm-generic/gpio.h> 11 5 12 - #include <linux/ssb/ssb_embedded.h> 13 - #include <linux/bcma/bcma.h> 14 - #include <asm/mach-bcm47xx/bcm47xx.h> 6 + #define gpio_get_value __gpio_get_value 7 + #define gpio_set_value __gpio_set_value 15 8 16 - #define BCM47XX_EXTIF_GPIO_LINES 5 17 - #define BCM47XX_CHIPCO_GPIO_LINES 16 9 + #define gpio_cansleep __gpio_cansleep 10 + #define gpio_to_irq __gpio_to_irq 18 11 19 - extern int gpio_request(unsigned gpio, const char *label); 20 - extern void gpio_free(unsigned gpio); 21 - extern int gpio_to_irq(unsigned gpio); 22 - 23 - static inline int gpio_get_value(unsigned gpio) 12 + static inline int irq_to_gpio(unsigned int irq) 24 13 { 25 - switch (bcm47xx_bus_type) { 26 - #ifdef CONFIG_BCM47XX_SSB 27 - case BCM47XX_BUS_TYPE_SSB: 28 - return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio); 29 - #endif 30 - #ifdef CONFIG_BCM47XX_BCMA 31 - case BCM47XX_BUS_TYPE_BCMA: 32 - return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc, 33 - 1 << gpio); 34 - #endif 35 - } 36 14 return -EINVAL; 37 15 } 38 16 39 - #define gpio_get_value_cansleep gpio_get_value 40 - 41 - static inline void gpio_set_value(unsigned gpio, int value) 42 - { 43 - switch (bcm47xx_bus_type) { 44 - #ifdef CONFIG_BCM47XX_SSB 45 - case BCM47XX_BUS_TYPE_SSB: 46 - ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio, 47 - value ? 1 << gpio : 0); 48 - return; 49 17 #endif 50 - #ifdef CONFIG_BCM47XX_BCMA 51 - case BCM47XX_BUS_TYPE_BCMA: 52 - bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio, 53 - value ? 1 << gpio : 0); 54 - return; 55 - #endif 56 - } 57 - } 58 - 59 - #define gpio_set_value_cansleep gpio_set_value 60 - 61 - static inline int gpio_cansleep(unsigned gpio) 62 - { 63 - return 0; 64 - } 65 - 66 - static inline int gpio_is_valid(unsigned gpio) 67 - { 68 - return gpio < (BCM47XX_EXTIF_GPIO_LINES + BCM47XX_CHIPCO_GPIO_LINES); 69 - } 70 - 71 - 72 - static inline int gpio_direction_input(unsigned gpio) 73 - { 74 - switch (bcm47xx_bus_type) { 75 - #ifdef CONFIG_BCM47XX_SSB 76 - case BCM47XX_BUS_TYPE_SSB: 77 - ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0); 78 - return 0; 79 - #endif 80 - #ifdef CONFIG_BCM47XX_BCMA 81 - case BCM47XX_BUS_TYPE_BCMA: 82 - bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio, 83 - 0); 84 - return 0; 85 - #endif 86 - } 87 - return -EINVAL; 88 - } 89 - 90 - static inline int gpio_direction_output(unsigned gpio, int value) 91 - { 92 - switch (bcm47xx_bus_type) { 93 - #ifdef CONFIG_BCM47XX_SSB 94 - case BCM47XX_BUS_TYPE_SSB: 95 - /* first set the gpio out value */ 96 - ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio, 97 - value ? 1 << gpio : 0); 98 - /* then set the gpio mode */ 99 - ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio); 100 - return 0; 101 - #endif 102 - #ifdef CONFIG_BCM47XX_BCMA 103 - case BCM47XX_BUS_TYPE_BCMA: 104 - /* first set the gpio out value */ 105 - bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio, 106 - value ? 1 << gpio : 0); 107 - /* then set the gpio mode */ 108 - bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio, 109 - 1 << gpio); 110 - return 0; 111 - #endif 112 - } 113 - return -EINVAL; 114 - } 115 - 116 - static inline int gpio_intmask(unsigned gpio, int value) 117 - { 118 - switch (bcm47xx_bus_type) { 119 - #ifdef CONFIG_BCM47XX_SSB 120 - case BCM47XX_BUS_TYPE_SSB: 121 - ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio, 122 - value ? 1 << gpio : 0); 123 - return 0; 124 - #endif 125 - #ifdef CONFIG_BCM47XX_BCMA 126 - case BCM47XX_BUS_TYPE_BCMA: 127 - bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc, 128 - 1 << gpio, value ? 1 << gpio : 0); 129 - return 0; 130 - #endif 131 - } 132 - return -EINVAL; 133 - } 134 - 135 - static inline int gpio_polarity(unsigned gpio, int value) 136 - { 137 - switch (bcm47xx_bus_type) { 138 - #ifdef CONFIG_BCM47XX_SSB 139 - case BCM47XX_BUS_TYPE_SSB: 140 - ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio, 141 - value ? 1 << gpio : 0); 142 - return 0; 143 - #endif 144 - #ifdef CONFIG_BCM47XX_BCMA 145 - case BCM47XX_BUS_TYPE_BCMA: 146 - bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc, 147 - 1 << gpio, value ? 1 << gpio : 0); 148 - return 0; 149 - #endif 150 - } 151 - return -EINVAL; 152 - } 153 - 154 - 155 - #endif /* __BCM47XX_GPIO_H */
+35
arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h
··· 1 + #ifndef BCM63XX_NVRAM_H 2 + #define BCM63XX_NVRAM_H 3 + 4 + #include <linux/types.h> 5 + 6 + /** 7 + * bcm63xx_nvram_init() - initializes nvram 8 + * @nvram: address of the nvram data 9 + * 10 + * Initialized the local nvram copy from the target address and checks 11 + * its checksum. 12 + * 13 + * Returns 0 on success. 14 + */ 15 + int __init bcm63xx_nvram_init(void *nvram); 16 + 17 + /** 18 + * bcm63xx_nvram_get_name() - returns the board name according to nvram 19 + * 20 + * Returns the board name field from nvram. Note that it might not be 21 + * null terminated if it is exactly 16 bytes long. 22 + */ 23 + u8 *bcm63xx_nvram_get_name(void); 24 + 25 + /** 26 + * bcm63xx_nvram_get_mac_address() - register & return a new mac address 27 + * @mac: pointer to array for allocated mac 28 + * 29 + * Registers and returns a mac address from the allocated macs from nvram. 30 + * 31 + * Returns 0 on success. 32 + */ 33 + int bcm63xx_nvram_get_mac_address(u8 *mac); 34 + 35 + #endif /* BCM63XX_NVRAM_H */
+22 -7
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
··· 53 53 CKCTL_6338_SAR_EN | \ 54 54 CKCTL_6338_SPI_EN) 55 55 56 - #define CKCTL_6345_CPU_EN (1 << 0) 57 - #define CKCTL_6345_BUS_EN (1 << 1) 58 - #define CKCTL_6345_EBI_EN (1 << 2) 59 - #define CKCTL_6345_UART_EN (1 << 3) 60 - #define CKCTL_6345_ADSLPHY_EN (1 << 4) 61 - #define CKCTL_6345_ENET_EN (1 << 7) 62 - #define CKCTL_6345_USBH_EN (1 << 8) 56 + /* BCM6345 clock bits are shifted by 16 on the left, because of the test 57 + * control register which is 16-bits wide. That way we do not have any 58 + * specific BCM6345 code for handling clocks, and writing 0 to the test 59 + * control register is fine. 60 + */ 61 + #define CKCTL_6345_CPU_EN (1 << 16) 62 + #define CKCTL_6345_BUS_EN (1 << 17) 63 + #define CKCTL_6345_EBI_EN (1 << 18) 64 + #define CKCTL_6345_UART_EN (1 << 19) 65 + #define CKCTL_6345_ADSLPHY_EN (1 << 20) 66 + #define CKCTL_6345_ENET_EN (1 << 23) 67 + #define CKCTL_6345_USBH_EN (1 << 24) 63 68 64 69 #define CKCTL_6345_ALL_SAFE_EN (CKCTL_6345_ENET_EN | \ 65 70 CKCTL_6345_USBH_EN | \ ··· 196 191 /* Soft Reset register */ 197 192 #define PERF_SOFTRESET_REG 0x28 198 193 #define PERF_SOFTRESET_6328_REG 0x10 194 + #define PERF_SOFTRESET_6358_REG 0x34 199 195 #define PERF_SOFTRESET_6368_REG 0x10 200 196 201 197 #define SOFTRESET_6328_SPI_MASK (1 << 0) ··· 249 243 SOFTRESET_6348_SAR_MASK | \ 250 244 SOFTRESET_6348_ACLC_MASK | \ 251 245 SOFTRESET_6348_ADSLMIPSPLL_MASK) 246 + 247 + #define SOFTRESET_6358_SPI_MASK (1 << 0) 248 + #define SOFTRESET_6358_ENET_MASK (1 << 2) 249 + #define SOFTRESET_6358_MPI_MASK (1 << 3) 250 + #define SOFTRESET_6358_EPHY_MASK (1 << 6) 251 + #define SOFTRESET_6358_SAR_MASK (1 << 7) 252 + #define SOFTRESET_6358_USBH_MASK (1 << 12) 253 + #define SOFTRESET_6358_PCM_MASK (1 << 13) 254 + #define SOFTRESET_6358_ADSL_MASK (1 << 14) 252 255 253 256 #define SOFTRESET_6368_SPI_MASK (1 << 0) 254 257 #define SOFTRESET_6368_MPI_MASK (1 << 3)
+21
arch/mips/include/asm/mach-bcm63xx/bcm63xx_reset.h
··· 1 + #ifndef __BCM63XX_RESET_H 2 + #define __BCM63XX_RESET_H 3 + 4 + enum bcm63xx_core_reset { 5 + BCM63XX_RESET_SPI, 6 + BCM63XX_RESET_ENET, 7 + BCM63XX_RESET_USBH, 8 + BCM63XX_RESET_USBD, 9 + BCM63XX_RESET_SAR, 10 + BCM63XX_RESET_DSL, 11 + BCM63XX_RESET_EPHY, 12 + BCM63XX_RESET_ENETSW, 13 + BCM63XX_RESET_PCM, 14 + BCM63XX_RESET_MPI, 15 + BCM63XX_RESET_PCIE, 16 + BCM63XX_RESET_PCIE_EXT, 17 + }; 18 + 19 + void bcm63xx_core_set_reset(enum bcm63xx_core_reset, int reset); 20 + 21 + #endif
-17
arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
··· 15 15 #define BCM963XX_NVRAM_OFFSET 0x580 16 16 17 17 /* 18 - * nvram structure 19 - */ 20 - struct bcm963xx_nvram { 21 - u32 version; 22 - u8 reserved1[256]; 23 - u8 name[16]; 24 - u32 main_tp_number; 25 - u32 psi_size; 26 - u32 mac_addr_count; 27 - u8 mac_addr_base[6]; 28 - u8 reserved2[2]; 29 - u32 checksum_old; 30 - u8 reserved3[720]; 31 - u32 checksum_high; 32 - }; 33 - 34 - /* 35 18 * board definition 36 19 */ 37 20 struct board_info {
+3
arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
··· 82 82 #define LTQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000) 83 83 #define LTQ_MPS_CHIPID ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344)) 84 84 85 + /* allow booting xrx200 phys */ 86 + int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr); 87 + 85 88 /* request a non-gpio and set the PIO config */ 86 89 #define PMU_PPE BIT(13) 87 90 extern void ltq_pmu_enable(unsigned int module);
+2 -1
arch/mips/include/asm/mach-loongson1/platform.h
··· 18 18 extern struct platform_device ls1x_ehci_device; 19 19 extern struct platform_device ls1x_rtc_device; 20 20 21 - void ls1x_serial_setup(void); 21 + extern void __init ls1x_clk_init(void); 22 + extern void __init ls1x_serial_setup(struct platform_device *pdev); 22 23 23 24 #endif /* __ASM_MACH_LOONGSON1_PLATFORM_H */
+4 -3
arch/mips/include/asm/mach-loongson1/regs-clk.h
··· 20 20 21 21 /* Clock PLL Divisor Register Bits */ 22 22 #define DIV_DC_EN (0x1 << 31) 23 - #define DIV_DC (0x1f << 26) 24 23 #define DIV_CPU_EN (0x1 << 25) 25 - #define DIV_CPU (0x1f << 20) 26 24 #define DIV_DDR_EN (0x1 << 19) 27 - #define DIV_DDR (0x1f << 14) 28 25 29 26 #define DIV_DC_SHIFT 26 30 27 #define DIV_CPU_SHIFT 20 31 28 #define DIV_DDR_SHIFT 14 29 + 30 + #define DIV_DC_WIDTH 5 31 + #define DIV_CPU_WIDTH 5 32 + #define DIV_DDR_WIDTH 5 32 33 33 34 #endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */
+3 -1
arch/mips/include/asm/mach-netlogic/irq.h
··· 8 8 #ifndef __ASM_NETLOGIC_IRQ_H 9 9 #define __ASM_NETLOGIC_IRQ_H 10 10 11 - #define NR_IRQS 64 11 + #include <asm/mach-netlogic/multi-node.h> 12 + #define NR_IRQS (64 * NLM_NR_NODES) 13 + 12 14 #define MIPS_CPU_IRQ_BASE 0 13 15 14 16 #endif /* __ASM_NETLOGIC_IRQ_H */
+54
arch/mips/include/asm/mach-netlogic/multi-node.h
··· 1 + /* 2 + * Copyright (c) 2003-2012 Broadcom Corporation 3 + * All Rights Reserved 4 + * 5 + * This software is available to you under a choice of one of two 6 + * licenses. You may choose to be licensed under the terms of the GNU 7 + * General Public License (GPL) Version 2, available from the file 8 + * COPYING in the main directory of this source tree, or the Broadcom 9 + * license below: 10 + * 11 + * Redistribution and use in source and binary forms, with or without 12 + * modification, are permitted provided that the following conditions 13 + * are met: 14 + * 15 + * 1. Redistributions of source code must retain the above copyright 16 + * notice, this list of conditions and the following disclaimer. 17 + * 2. Redistributions in binary form must reproduce the above copyright 18 + * notice, this list of conditions and the following disclaimer in 19 + * the documentation and/or other materials provided with the 20 + * distribution. 21 + * 22 + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR 23 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 + * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE 26 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 29 + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 32 + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 + */ 34 + 35 + #ifndef _NETLOGIC_MULTI_NODE_H_ 36 + #define _NETLOGIC_MULTI_NODE_H_ 37 + 38 + #ifndef CONFIG_NLM_MULTINODE 39 + #define NLM_NR_NODES 1 40 + #else 41 + #if defined(CONFIG_NLM_MULTINODE_2) 42 + #define NLM_NR_NODES 2 43 + #elif defined(CONFIG_NLM_MULTINODE_4) 44 + #define NLM_NR_NODES 4 45 + #else 46 + #define NLM_NR_NODES 1 47 + #endif 48 + #endif 49 + 50 + #define NLM_CORES_PER_NODE 8 51 + #define NLM_THREADS_PER_CORE 4 52 + #define NLM_CPUS_PER_NODE (NLM_CORES_PER_NODE * NLM_THREADS_PER_CORE) 53 + 54 + #endif
+44 -7
arch/mips/include/asm/netlogic/common.h
··· 45 45 #define BOOT_NMI_HANDLER 8 46 46 47 47 #ifndef __ASSEMBLY__ 48 + #include <linux/cpumask.h> 49 + #include <linux/spinlock.h> 50 + #include <asm/irq.h> 51 + #include <asm/mach-netlogic/multi-node.h> 52 + 48 53 struct irq_desc; 49 - extern struct plat_smp_ops nlm_smp_ops; 50 - extern char nlm_reset_entry[], nlm_reset_entry_end[]; 51 54 void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc); 52 55 void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc); 53 - void nlm_smp_irq_init(void); 56 + void nlm_smp_irq_init(int hwcpuid); 54 57 void nlm_boot_secondary_cpus(void); 55 - int nlm_wakeup_secondary_cpus(u32 wakeup_mask); 58 + int nlm_wakeup_secondary_cpus(void); 56 59 void nlm_rmiboot_preboot(void); 60 + void nlm_percpu_init(int hwcpuid); 57 61 58 62 static inline void 59 63 nlm_set_nmi_handler(void *handler) ··· 72 68 * Misc. 73 69 */ 74 70 unsigned int nlm_get_cpu_frequency(void); 71 + void nlm_node_init(int node); 72 + extern struct plat_smp_ops nlm_smp_ops; 73 + extern char nlm_reset_entry[], nlm_reset_entry_end[]; 75 74 76 - extern unsigned long nlm_common_ebase; 77 - extern int nlm_threads_per_core; 78 - extern uint32_t nlm_cpumask, nlm_coremask; 75 + extern unsigned int nlm_threads_per_core; 76 + extern cpumask_t nlm_cpumask; 77 + 78 + struct nlm_soc_info { 79 + unsigned long coremask; /* cores enabled on the soc */ 80 + unsigned long ebase; 81 + uint64_t irqmask; 82 + uint64_t sysbase; /* only for XLP */ 83 + uint64_t picbase; 84 + spinlock_t piclock; 85 + }; 86 + 87 + #define nlm_get_node(i) (&nlm_nodes[i]) 88 + #ifdef CONFIG_CPU_XLR 89 + #define nlm_current_node() (&nlm_nodes[0]) 90 + #else 91 + #define nlm_current_node() (&nlm_nodes[nlm_nodeid()]) 92 + #endif 93 + 94 + struct irq_data; 95 + uint64_t nlm_pci_irqmask(int node); 96 + void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *)); 97 + 98 + /* 99 + * The NR_IRQs is divided between nodes, each of them has a separate irq space 100 + */ 101 + static inline int nlm_irq_to_xirq(int node, int irq) 102 + { 103 + return node * NR_IRQS / NLM_NR_NODES + irq; 104 + } 105 + 106 + extern struct nlm_soc_info nlm_nodes[NLM_NR_NODES]; 107 + extern int nlm_cpu_ready[]; 79 108 #endif 80 109 #endif /* _NETLOGIC_COMMON_H_ */
+1 -1
arch/mips/include/asm/netlogic/interrupt.h
··· 39 39 40 40 #define IRQ_IPI_SMP_FUNCTION 3 41 41 #define IRQ_IPI_SMP_RESCHEDULE 4 42 - #define IRQ_MSGRING 6 42 + #define IRQ_FMN 5 43 43 #define IRQ_TIMER 7 44 44 45 45 #endif
+142
arch/mips/include/asm/netlogic/mips-extns.h
··· 73 73 return __read_32bit_c0_register($15, 1) & 0x3ff; 74 74 } 75 75 76 + static inline int nlm_nodeid(void) 77 + { 78 + return (__read_32bit_c0_register($15, 1) >> 5) & 0x3; 79 + } 80 + 81 + static inline unsigned int nlm_core_id(void) 82 + { 83 + return (read_c0_ebase() & 0x1c) >> 2; 84 + } 85 + 86 + static inline unsigned int nlm_thread_id(void) 87 + { 88 + return read_c0_ebase() & 0x3; 89 + } 90 + 91 + #define __read_64bit_c2_split(source, sel) \ 92 + ({ \ 93 + unsigned long long __val; \ 94 + unsigned long __flags; \ 95 + \ 96 + local_irq_save(__flags); \ 97 + if (sel == 0) \ 98 + __asm__ __volatile__( \ 99 + ".set\tmips64\n\t" \ 100 + "dmfc2\t%M0, " #source "\n\t" \ 101 + "dsll\t%L0, %M0, 32\n\t" \ 102 + "dsra\t%M0, %M0, 32\n\t" \ 103 + "dsra\t%L0, %L0, 32\n\t" \ 104 + ".set\tmips0\n\t" \ 105 + : "=r" (__val)); \ 106 + else \ 107 + __asm__ __volatile__( \ 108 + ".set\tmips64\n\t" \ 109 + "dmfc2\t%M0, " #source ", " #sel "\n\t" \ 110 + "dsll\t%L0, %M0, 32\n\t" \ 111 + "dsra\t%M0, %M0, 32\n\t" \ 112 + "dsra\t%L0, %L0, 32\n\t" \ 113 + ".set\tmips0\n\t" \ 114 + : "=r" (__val)); \ 115 + local_irq_restore(__flags); \ 116 + \ 117 + __val; \ 118 + }) 119 + 120 + #define __write_64bit_c2_split(source, sel, val) \ 121 + do { \ 122 + unsigned long __flags; \ 123 + \ 124 + local_irq_save(__flags); \ 125 + if (sel == 0) \ 126 + __asm__ __volatile__( \ 127 + ".set\tmips64\n\t" \ 128 + "dsll\t%L0, %L0, 32\n\t" \ 129 + "dsrl\t%L0, %L0, 32\n\t" \ 130 + "dsll\t%M0, %M0, 32\n\t" \ 131 + "or\t%L0, %L0, %M0\n\t" \ 132 + "dmtc2\t%L0, " #source "\n\t" \ 133 + ".set\tmips0\n\t" \ 134 + : : "r" (val)); \ 135 + else \ 136 + __asm__ __volatile__( \ 137 + ".set\tmips64\n\t" \ 138 + "dsll\t%L0, %L0, 32\n\t" \ 139 + "dsrl\t%L0, %L0, 32\n\t" \ 140 + "dsll\t%M0, %M0, 32\n\t" \ 141 + "or\t%L0, %L0, %M0\n\t" \ 142 + "dmtc2\t%L0, " #source ", " #sel "\n\t" \ 143 + ".set\tmips0\n\t" \ 144 + : : "r" (val)); \ 145 + local_irq_restore(__flags); \ 146 + } while (0) 147 + 148 + #define __read_32bit_c2_register(source, sel) \ 149 + ({ uint32_t __res; \ 150 + if (sel == 0) \ 151 + __asm__ __volatile__( \ 152 + ".set\tmips32\n\t" \ 153 + "mfc2\t%0, " #source "\n\t" \ 154 + ".set\tmips0\n\t" \ 155 + : "=r" (__res)); \ 156 + else \ 157 + __asm__ __volatile__( \ 158 + ".set\tmips32\n\t" \ 159 + "mfc2\t%0, " #source ", " #sel "\n\t" \ 160 + ".set\tmips0\n\t" \ 161 + : "=r" (__res)); \ 162 + __res; \ 163 + }) 164 + 165 + #define __read_64bit_c2_register(source, sel) \ 166 + ({ unsigned long long __res; \ 167 + if (sizeof(unsigned long) == 4) \ 168 + __res = __read_64bit_c2_split(source, sel); \ 169 + else if (sel == 0) \ 170 + __asm__ __volatile__( \ 171 + ".set\tmips64\n\t" \ 172 + "dmfc2\t%0, " #source "\n\t" \ 173 + ".set\tmips0\n\t" \ 174 + : "=r" (__res)); \ 175 + else \ 176 + __asm__ __volatile__( \ 177 + ".set\tmips64\n\t" \ 178 + "dmfc2\t%0, " #source ", " #sel "\n\t" \ 179 + ".set\tmips0\n\t" \ 180 + : "=r" (__res)); \ 181 + __res; \ 182 + }) 183 + 184 + #define __write_64bit_c2_register(register, sel, value) \ 185 + do { \ 186 + if (sizeof(unsigned long) == 4) \ 187 + __write_64bit_c2_split(register, sel, value); \ 188 + else if (sel == 0) \ 189 + __asm__ __volatile__( \ 190 + ".set\tmips64\n\t" \ 191 + "dmtc2\t%z0, " #register "\n\t" \ 192 + ".set\tmips0\n\t" \ 193 + : : "Jr" (value)); \ 194 + else \ 195 + __asm__ __volatile__( \ 196 + ".set\tmips64\n\t" \ 197 + "dmtc2\t%z0, " #register ", " #sel "\n\t" \ 198 + ".set\tmips0\n\t" \ 199 + : : "Jr" (value)); \ 200 + } while (0) 201 + 202 + #define __write_32bit_c2_register(reg, sel, value) \ 203 + ({ \ 204 + if (sel == 0) \ 205 + __asm__ __volatile__( \ 206 + ".set\tmips32\n\t" \ 207 + "mtc2\t%z0, " #reg "\n\t" \ 208 + ".set\tmips0\n\t" \ 209 + : : "Jr" (value)); \ 210 + else \ 211 + __asm__ __volatile__( \ 212 + ".set\tmips32\n\t" \ 213 + "mtc2\t%z0, " #reg ", " #sel "\n\t" \ 214 + ".set\tmips0\n\t" \ 215 + : : "Jr" (value)); \ 216 + }) 217 + 76 218 #endif /*_ASM_NLM_MIPS_EXTS_H */
+8 -36
arch/mips/include/asm/netlogic/xlp-hal/pic.h
··· 273 273 return nlm_read_pic_reg(base, PIC_IRT(irt_index)); 274 274 } 275 275 276 - static inline uint64_t 277 - nlm_pic_read_control(uint64_t base) 278 - { 279 - return nlm_read_pic_reg(base, PIC_CTRL); 280 - } 281 - 282 - static inline void 283 - nlm_pic_write_control(uint64_t base, uint64_t control) 284 - { 285 - nlm_write_pic_reg(base, PIC_CTRL, control); 286 - } 287 - 288 - static inline void 289 - nlm_pic_update_control(uint64_t base, uint64_t control) 290 - { 291 - uint64_t val; 292 - 293 - val = nlm_read_pic_reg(base, PIC_CTRL); 294 - nlm_write_pic_reg(base, PIC_CTRL, control | val); 295 - } 296 - 297 276 static inline void 298 277 nlm_set_irt_to_cpu(uint64_t base, int irt, int cpu) 299 278 { 300 279 uint64_t val; 301 280 302 281 val = nlm_read_pic_reg(base, PIC_IRT(irt)); 303 - val |= cpu & 0xf; 304 - if (cpu > 15) 305 - val |= 1 << 16; 282 + /* clear cpuset and mask */ 283 + val &= ~((0x7ull << 16) | 0xffff); 284 + /* set DB, cpuset and cpumask */ 285 + val |= (1 << 19) | ((cpu >> 4) << 16) | (1 << (cpu & 0xf)); 306 286 nlm_write_pic_reg(base, PIC_IRT(irt), val); 307 287 } 308 288 ··· 349 369 static inline void 350 370 nlm_pic_disable_irt(uint64_t base, int irt) 351 371 { 352 - uint32_t reg; 372 + uint64_t reg; 353 373 354 374 reg = nlm_read_pic_reg(base, PIC_IRT(irt)); 355 375 nlm_write_pic_reg(base, PIC_IRT(irt), reg & ~((uint64_t)1 << 31)); ··· 359 379 nlm_pic_send_ipi(uint64_t base, int hwt, int irq, int nmi) 360 380 { 361 381 uint64_t ipi; 362 - int node, ncpu; 363 382 364 - node = hwt / 32; 365 - ncpu = hwt & 0x1f; 366 - ipi = ((uint64_t)nmi << 31) | (irq << 20) | (node << 17) | 367 - (1 << (ncpu & 0xf)); 368 - if (ncpu > 15) 369 - ipi |= 0x10000; /* Setting bit 16 to select cpus 16-31 */ 370 - 383 + ipi = (nmi << 31) | (irq << 20); 384 + ipi |= ((hwt >> 4) << 16) | (1 << (hwt & 0xf)); /* cpuset and mask */ 371 385 nlm_write_pic_reg(base, PIC_IPI_CTL, ipi); 372 386 } 373 387 ··· 378 404 static inline void 379 405 nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt) 380 406 { 381 - nlm_pic_write_irt_direct(base, irt, 0, 0, 0, irq, 0); 407 + nlm_pic_write_irt_direct(base, irt, 0, 0, 0, irq, hwt); 382 408 } 383 409 384 - extern uint64_t nlm_pic_base; 385 410 int nlm_irq_to_irt(int irq); 386 - int nlm_irt_to_irq(int irt); 387 411 388 412 #endif /* __ASSEMBLY__ */ 389 413 #endif /* _NLM_HAL_PIC_H */
-1
arch/mips/include/asm/netlogic/xlp-hal/sys.h
··· 124 124 #define nlm_get_sys_pcibase(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node)) 125 125 #define nlm_get_sys_regbase(node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ) 126 126 127 - extern uint64_t nlm_sys_base; 128 127 #endif 129 128 #endif
+363
arch/mips/include/asm/netlogic/xlr/fmn.h
··· 1 + /* 2 + * Copyright (c) 2003-2012 Broadcom Corporation 3 + * All Rights Reserved 4 + * 5 + * This software is available to you under a choice of one of two 6 + * licenses. You may choose to be licensed under the terms of the GNU 7 + * General Public License (GPL) Version 2, available from the file 8 + * COPYING in the main directory of this source tree, or the Broadcom 9 + * license below: 10 + * 11 + * Redistribution and use in source and binary forms, with or without 12 + * modification, are permitted provided that the following conditions 13 + * are met: 14 + * 15 + * 1. Redistributions of source code must retain the above copyright 16 + * notice, this list of conditions and the following disclaimer. 17 + * 2. Redistributions in binary form must reproduce the above copyright 18 + * notice, this list of conditions and the following disclaimer in 19 + * the documentation and/or other materials provided with the 20 + * distribution. 21 + * 22 + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR 23 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 + * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE 26 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 29 + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 32 + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 + */ 34 + 35 + #ifndef _NLM_FMN_H_ 36 + #define _NLM_FMN_H_ 37 + 38 + #include <asm/netlogic/mips-extns.h> /* for COP2 access */ 39 + 40 + /* Station IDs */ 41 + #define FMN_STNID_CPU0 0x00 42 + #define FMN_STNID_CPU1 0x08 43 + #define FMN_STNID_CPU2 0x10 44 + #define FMN_STNID_CPU3 0x18 45 + #define FMN_STNID_CPU4 0x20 46 + #define FMN_STNID_CPU5 0x28 47 + #define FMN_STNID_CPU6 0x30 48 + #define FMN_STNID_CPU7 0x38 49 + 50 + #define FMN_STNID_XGS0_TX 64 51 + #define FMN_STNID_XMAC0_00_TX 64 52 + #define FMN_STNID_XMAC0_01_TX 65 53 + #define FMN_STNID_XMAC0_02_TX 66 54 + #define FMN_STNID_XMAC0_03_TX 67 55 + #define FMN_STNID_XMAC0_04_TX 68 56 + #define FMN_STNID_XMAC0_05_TX 69 57 + #define FMN_STNID_XMAC0_06_TX 70 58 + #define FMN_STNID_XMAC0_07_TX 71 59 + #define FMN_STNID_XMAC0_08_TX 72 60 + #define FMN_STNID_XMAC0_09_TX 73 61 + #define FMN_STNID_XMAC0_10_TX 74 62 + #define FMN_STNID_XMAC0_11_TX 75 63 + #define FMN_STNID_XMAC0_12_TX 76 64 + #define FMN_STNID_XMAC0_13_TX 77 65 + #define FMN_STNID_XMAC0_14_TX 78 66 + #define FMN_STNID_XMAC0_15_TX 79 67 + 68 + #define FMN_STNID_XGS1_TX 80 69 + #define FMN_STNID_XMAC1_00_TX 80 70 + #define FMN_STNID_XMAC1_01_TX 81 71 + #define FMN_STNID_XMAC1_02_TX 82 72 + #define FMN_STNID_XMAC1_03_TX 83 73 + #define FMN_STNID_XMAC1_04_TX 84 74 + #define FMN_STNID_XMAC1_05_TX 85 75 + #define FMN_STNID_XMAC1_06_TX 86 76 + #define FMN_STNID_XMAC1_07_TX 87 77 + #define FMN_STNID_XMAC1_08_TX 88 78 + #define FMN_STNID_XMAC1_09_TX 89 79 + #define FMN_STNID_XMAC1_10_TX 90 80 + #define FMN_STNID_XMAC1_11_TX 91 81 + #define FMN_STNID_XMAC1_12_TX 92 82 + #define FMN_STNID_XMAC1_13_TX 93 83 + #define FMN_STNID_XMAC1_14_TX 94 84 + #define FMN_STNID_XMAC1_15_TX 95 85 + 86 + #define FMN_STNID_GMAC 96 87 + #define FMN_STNID_GMACJFR_0 96 88 + #define FMN_STNID_GMACRFR_0 97 89 + #define FMN_STNID_GMACTX0 98 90 + #define FMN_STNID_GMACTX1 99 91 + #define FMN_STNID_GMACTX2 100 92 + #define FMN_STNID_GMACTX3 101 93 + #define FMN_STNID_GMACJFR_1 102 94 + #define FMN_STNID_GMACRFR_1 103 95 + 96 + #define FMN_STNID_DMA 104 97 + #define FMN_STNID_DMA_0 104 98 + #define FMN_STNID_DMA_1 105 99 + #define FMN_STNID_DMA_2 106 100 + #define FMN_STNID_DMA_3 107 101 + 102 + #define FMN_STNID_XGS0FR 112 103 + #define FMN_STNID_XMAC0JFR 112 104 + #define FMN_STNID_XMAC0RFR 113 105 + 106 + #define FMN_STNID_XGS1FR 114 107 + #define FMN_STNID_XMAC1JFR 114 108 + #define FMN_STNID_XMAC1RFR 115 109 + #define FMN_STNID_SEC 120 110 + #define FMN_STNID_SEC0 120 111 + #define FMN_STNID_SEC1 121 112 + #define FMN_STNID_SEC2 122 113 + #define FMN_STNID_SEC3 123 114 + #define FMN_STNID_PK0 124 115 + #define FMN_STNID_SEC_RSA 124 116 + #define FMN_STNID_SEC_RSVD0 125 117 + #define FMN_STNID_SEC_RSVD1 126 118 + #define FMN_STNID_SEC_RSVD2 127 119 + 120 + #define FMN_STNID_GMAC1 80 121 + #define FMN_STNID_GMAC1_FR_0 81 122 + #define FMN_STNID_GMAC1_TX0 82 123 + #define FMN_STNID_GMAC1_TX1 83 124 + #define FMN_STNID_GMAC1_TX2 84 125 + #define FMN_STNID_GMAC1_TX3 85 126 + #define FMN_STNID_GMAC1_FR_1 87 127 + #define FMN_STNID_GMAC0 96 128 + #define FMN_STNID_GMAC0_FR_0 97 129 + #define FMN_STNID_GMAC0_TX0 98 130 + #define FMN_STNID_GMAC0_TX1 99 131 + #define FMN_STNID_GMAC0_TX2 100 132 + #define FMN_STNID_GMAC0_TX3 101 133 + #define FMN_STNID_GMAC0_FR_1 103 134 + #define FMN_STNID_CMP_0 108 135 + #define FMN_STNID_CMP_1 109 136 + #define FMN_STNID_CMP_2 110 137 + #define FMN_STNID_CMP_3 111 138 + #define FMN_STNID_PCIE_0 116 139 + #define FMN_STNID_PCIE_1 117 140 + #define FMN_STNID_PCIE_2 118 141 + #define FMN_STNID_PCIE_3 119 142 + #define FMN_STNID_XLS_PK0 121 143 + 144 + #define nlm_read_c2_cc0(s) __read_32bit_c2_register($16, s) 145 + #define nlm_read_c2_cc1(s) __read_32bit_c2_register($17, s) 146 + #define nlm_read_c2_cc2(s) __read_32bit_c2_register($18, s) 147 + #define nlm_read_c2_cc3(s) __read_32bit_c2_register($19, s) 148 + #define nlm_read_c2_cc4(s) __read_32bit_c2_register($20, s) 149 + #define nlm_read_c2_cc5(s) __read_32bit_c2_register($21, s) 150 + #define nlm_read_c2_cc6(s) __read_32bit_c2_register($22, s) 151 + #define nlm_read_c2_cc7(s) __read_32bit_c2_register($23, s) 152 + #define nlm_read_c2_cc8(s) __read_32bit_c2_register($24, s) 153 + #define nlm_read_c2_cc9(s) __read_32bit_c2_register($25, s) 154 + #define nlm_read_c2_cc10(s) __read_32bit_c2_register($26, s) 155 + #define nlm_read_c2_cc11(s) __read_32bit_c2_register($27, s) 156 + #define nlm_read_c2_cc12(s) __read_32bit_c2_register($28, s) 157 + #define nlm_read_c2_cc13(s) __read_32bit_c2_register($29, s) 158 + #define nlm_read_c2_cc14(s) __read_32bit_c2_register($30, s) 159 + #define nlm_read_c2_cc15(s) __read_32bit_c2_register($31, s) 160 + 161 + #define nlm_write_c2_cc0(s, v) __write_32bit_c2_register($16, s, v) 162 + #define nlm_write_c2_cc1(s, v) __write_32bit_c2_register($17, s, v) 163 + #define nlm_write_c2_cc2(s, v) __write_32bit_c2_register($18, s, v) 164 + #define nlm_write_c2_cc3(s, v) __write_32bit_c2_register($19, s, v) 165 + #define nlm_write_c2_cc4(s, v) __write_32bit_c2_register($20, s, v) 166 + #define nlm_write_c2_cc5(s, v) __write_32bit_c2_register($21, s, v) 167 + #define nlm_write_c2_cc6(s, v) __write_32bit_c2_register($22, s, v) 168 + #define nlm_write_c2_cc7(s, v) __write_32bit_c2_register($23, s, v) 169 + #define nlm_write_c2_cc8(s, v) __write_32bit_c2_register($24, s, v) 170 + #define nlm_write_c2_cc9(s, v) __write_32bit_c2_register($25, s, v) 171 + #define nlm_write_c2_cc10(s, v) __write_32bit_c2_register($26, s, v) 172 + #define nlm_write_c2_cc11(s, v) __write_32bit_c2_register($27, s, v) 173 + #define nlm_write_c2_cc12(s, v) __write_32bit_c2_register($28, s, v) 174 + #define nlm_write_c2_cc13(s, v) __write_32bit_c2_register($29, s, v) 175 + #define nlm_write_c2_cc14(s, v) __write_32bit_c2_register($30, s, v) 176 + #define nlm_write_c2_cc15(s, v) __write_32bit_c2_register($31, s, v) 177 + 178 + #define nlm_read_c2_status(sel) __read_32bit_c2_register($2, 0) 179 + #define nlm_read_c2_config() __read_32bit_c2_register($3, 0) 180 + #define nlm_write_c2_config(v) __write_32bit_c2_register($3, 0, v) 181 + #define nlm_read_c2_bucksize(b) __read_32bit_c2_register($4, b) 182 + #define nlm_write_c2_bucksize(b, v) __write_32bit_c2_register($4, b, v) 183 + 184 + #define nlm_read_c2_rx_msg0() __read_64bit_c2_register($1, 0) 185 + #define nlm_read_c2_rx_msg1() __read_64bit_c2_register($1, 1) 186 + #define nlm_read_c2_rx_msg2() __read_64bit_c2_register($1, 2) 187 + #define nlm_read_c2_rx_msg3() __read_64bit_c2_register($1, 3) 188 + 189 + #define nlm_write_c2_tx_msg0(v) __write_64bit_c2_register($0, 0, v) 190 + #define nlm_write_c2_tx_msg1(v) __write_64bit_c2_register($0, 1, v) 191 + #define nlm_write_c2_tx_msg2(v) __write_64bit_c2_register($0, 2, v) 192 + #define nlm_write_c2_tx_msg3(v) __write_64bit_c2_register($0, 3, v) 193 + 194 + #define FMN_STN_RX_QSIZE 256 195 + #define FMN_NSTATIONS 128 196 + #define FMN_CORE_NBUCKETS 8 197 + 198 + static inline void nlm_msgsnd(unsigned int stid) 199 + { 200 + __asm__ volatile ( 201 + ".set push\n" 202 + ".set noreorder\n" 203 + ".set noat\n" 204 + "move $1, %0\n" 205 + "c2 0x10001\n" /* msgsnd $1 */ 206 + ".set pop\n" 207 + : : "r" (stid) : "$1" 208 + ); 209 + } 210 + 211 + static inline void nlm_msgld(unsigned int pri) 212 + { 213 + __asm__ volatile ( 214 + ".set push\n" 215 + ".set noreorder\n" 216 + ".set noat\n" 217 + "move $1, %0\n" 218 + "c2 0x10002\n" /* msgld $1 */ 219 + ".set pop\n" 220 + : : "r" (pri) : "$1" 221 + ); 222 + } 223 + 224 + static inline void nlm_msgwait(unsigned int mask) 225 + { 226 + __asm__ volatile ( 227 + ".set push\n" 228 + ".set noreorder\n" 229 + ".set noat\n" 230 + "move $8, %0\n" 231 + "c2 0x10003\n" /* msgwait $1 */ 232 + ".set pop\n" 233 + : : "r" (mask) : "$1" 234 + ); 235 + } 236 + 237 + /* 238 + * Disable interrupts and enable COP2 access 239 + */ 240 + static inline uint32_t nlm_cop2_enable(void) 241 + { 242 + uint32_t sr = read_c0_status(); 243 + 244 + write_c0_status((sr & ~ST0_IE) | ST0_CU2); 245 + return sr; 246 + } 247 + 248 + static inline void nlm_cop2_restore(uint32_t sr) 249 + { 250 + write_c0_status(sr); 251 + } 252 + 253 + static inline void nlm_fmn_setup_intr(int irq, unsigned int tmask) 254 + { 255 + uint32_t config; 256 + 257 + config = (1 << 24) /* interrupt water mark - 1 msg */ 258 + | (irq << 16) /* irq */ 259 + | (tmask << 8) /* thread mask */ 260 + | 0x2; /* enable watermark intr, disable empty intr */ 261 + nlm_write_c2_config(config); 262 + } 263 + 264 + struct nlm_fmn_msg { 265 + uint64_t msg0; 266 + uint64_t msg1; 267 + uint64_t msg2; 268 + uint64_t msg3; 269 + }; 270 + 271 + static inline int nlm_fmn_send(unsigned int size, unsigned int code, 272 + unsigned int stid, struct nlm_fmn_msg *msg) 273 + { 274 + unsigned int dest; 275 + uint32_t status; 276 + int i; 277 + 278 + /* 279 + * Make sure that all the writes pending at the cpu are flushed. 280 + * Any writes pending on CPU will not be see by devices. L1/L2 281 + * caches are coherent with IO, so no cache flush needed. 282 + */ 283 + __asm __volatile("sync"); 284 + 285 + /* Load TX message buffers */ 286 + nlm_write_c2_tx_msg0(msg->msg0); 287 + nlm_write_c2_tx_msg1(msg->msg1); 288 + nlm_write_c2_tx_msg2(msg->msg2); 289 + nlm_write_c2_tx_msg3(msg->msg3); 290 + dest = ((size - 1) << 16) | (code << 8) | stid; 291 + 292 + /* 293 + * Retry a few times on credit fail, this should be a 294 + * transient condition, unless there is a configuration 295 + * failure, or the receiver is stuck. 296 + */ 297 + for (i = 0; i < 8; i++) { 298 + nlm_msgsnd(dest); 299 + status = nlm_read_c2_status(0); 300 + if ((status & 0x2) == 1) 301 + pr_info("Send pending fail!\n"); 302 + if ((status & 0x4) == 0) 303 + return 0; 304 + } 305 + 306 + /* If there is a credit failure, return error */ 307 + return status & 0x06; 308 + } 309 + 310 + static inline int nlm_fmn_receive(int bucket, int *size, int *code, int *stid, 311 + struct nlm_fmn_msg *msg) 312 + { 313 + uint32_t status, tmp; 314 + 315 + nlm_msgld(bucket); 316 + 317 + /* wait for load pending to clear */ 318 + do { 319 + status = nlm_read_c2_status(1); 320 + } while ((status & 0x08) != 0); 321 + 322 + /* receive error bits */ 323 + tmp = status & 0x30; 324 + if (tmp != 0) 325 + return tmp; 326 + 327 + *size = ((status & 0xc0) >> 6) + 1; 328 + *code = (status & 0xff00) >> 8; 329 + *stid = (status & 0x7f0000) >> 16; 330 + msg->msg0 = nlm_read_c2_rx_msg0(); 331 + msg->msg1 = nlm_read_c2_rx_msg1(); 332 + msg->msg2 = nlm_read_c2_rx_msg2(); 333 + msg->msg3 = nlm_read_c2_rx_msg3(); 334 + 335 + return 0; 336 + } 337 + 338 + struct xlr_fmn_info { 339 + int num_buckets; 340 + int start_stn_id; 341 + int end_stn_id; 342 + int credit_config[128]; 343 + }; 344 + 345 + struct xlr_board_fmn_config { 346 + int bucket_size[128]; /* size of buckets for all stations */ 347 + struct xlr_fmn_info cpu[8]; 348 + struct xlr_fmn_info gmac[2]; 349 + struct xlr_fmn_info dma; 350 + struct xlr_fmn_info cmp; 351 + struct xlr_fmn_info sae; 352 + struct xlr_fmn_info xgmac[2]; 353 + }; 354 + 355 + extern int nlm_register_fmn_handler(int start, int end, 356 + void (*fn)(int, int, int, int, struct nlm_fmn_msg *, void *), 357 + void *arg); 358 + extern void xlr_percpu_fmn_init(void); 359 + extern void nlm_setup_fmn_irq(void); 360 + extern void xlr_board_info_setup(void); 361 + 362 + extern struct xlr_board_fmn_config xlr_board_fmn_config; 363 + #endif
-2
arch/mips/include/asm/netlogic/xlr/pic.h
··· 258 258 nlm_write_reg(base, PIC_IRT_1(irt), 259 259 (1 << 30) | (1 << 6) | irq); 260 260 } 261 - 262 - extern uint64_t nlm_pic_base; 263 261 #endif 264 262 #endif /* _ASM_NLM_XLR_PIC_H */
+2 -4
arch/mips/include/asm/netlogic/xlr/xlr.h
··· 51 51 return ((prid & 0xf000) == 0x4000); 52 52 } 53 53 54 - /* 55 - * XLR chip types 56 - */ 57 - /* The XLS product line has chip versions 0x[48c]? */ 54 + /* XLR chip types */ 55 + /* The XLS product line has chip versions 0x[48c]? */ 58 56 static inline unsigned int nlm_chip_is_xls(void) 59 57 { 60 58 uint32_t prid = read_c0_prid();
+124
arch/mips/kernel/perf_event_mipsxx.c
··· 840 840 [PERF_COUNT_HW_BRANCH_MISSES] = { 0x02, CNTR_ODD, T }, 841 841 }; 842 842 843 + static const struct mips_perf_event xlp_event_map[PERF_COUNT_HW_MAX] = { 844 + [PERF_COUNT_HW_CPU_CYCLES] = { 0x01, CNTR_ALL }, 845 + [PERF_COUNT_HW_INSTRUCTIONS] = { 0x18, CNTR_ALL }, /* PAPI_TOT_INS */ 846 + [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x04, CNTR_ALL }, /* PAPI_L1_ICA */ 847 + [PERF_COUNT_HW_CACHE_MISSES] = { 0x07, CNTR_ALL }, /* PAPI_L1_ICM */ 848 + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x1b, CNTR_ALL }, /* PAPI_BR_CN */ 849 + [PERF_COUNT_HW_BRANCH_MISSES] = { 0x1c, CNTR_ALL }, /* PAPI_BR_MSP */ 850 + [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID }, 851 + }; 852 + 843 853 /* 24K/34K/1004K cores can share the same cache event map. */ 844 854 static const struct mips_perf_event mipsxxcore_cache_map 845 855 [PERF_COUNT_HW_CACHE_MAX] ··· 1098 1088 [C(ITLB)] = { 1099 1089 [C(OP_READ)] = { 1100 1090 [C(RESULT_MISS)] = { 0x37, CNTR_ALL }, 1091 + }, 1092 + }, 1093 + }; 1094 + 1095 + static const struct mips_perf_event xlp_cache_map 1096 + [PERF_COUNT_HW_CACHE_MAX] 1097 + [PERF_COUNT_HW_CACHE_OP_MAX] 1098 + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { 1099 + [C(L1D)] = { 1100 + [C(OP_READ)] = { 1101 + [C(RESULT_ACCESS)] = { 0x31, CNTR_ALL }, /* PAPI_L1_DCR */ 1102 + [C(RESULT_MISS)] = { 0x30, CNTR_ALL }, /* PAPI_L1_LDM */ 1103 + }, 1104 + [C(OP_WRITE)] = { 1105 + [C(RESULT_ACCESS)] = { 0x2f, CNTR_ALL }, /* PAPI_L1_DCW */ 1106 + [C(RESULT_MISS)] = { 0x2e, CNTR_ALL }, /* PAPI_L1_STM */ 1107 + }, 1108 + [C(OP_PREFETCH)] = { 1109 + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1110 + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1111 + }, 1112 + }, 1113 + [C(L1I)] = { 1114 + [C(OP_READ)] = { 1115 + [C(RESULT_ACCESS)] = { 0x04, CNTR_ALL }, /* PAPI_L1_ICA */ 1116 + [C(RESULT_MISS)] = { 0x07, CNTR_ALL }, /* PAPI_L1_ICM */ 1117 + }, 1118 + [C(OP_WRITE)] = { 1119 + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1120 + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1121 + }, 1122 + [C(OP_PREFETCH)] = { 1123 + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1124 + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1125 + }, 1126 + }, 1127 + [C(LL)] = { 1128 + [C(OP_READ)] = { 1129 + [C(RESULT_ACCESS)] = { 0x35, CNTR_ALL }, /* PAPI_L2_DCR */ 1130 + [C(RESULT_MISS)] = { 0x37, CNTR_ALL }, /* PAPI_L2_LDM */ 1131 + }, 1132 + [C(OP_WRITE)] = { 1133 + [C(RESULT_ACCESS)] = { 0x34, CNTR_ALL }, /* PAPI_L2_DCA */ 1134 + [C(RESULT_MISS)] = { 0x36, CNTR_ALL }, /* PAPI_L2_DCM */ 1135 + }, 1136 + [C(OP_PREFETCH)] = { 1137 + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1138 + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1139 + }, 1140 + }, 1141 + [C(DTLB)] = { 1142 + /* 1143 + * Only general DTLB misses are counted use the same event for 1144 + * read and write. 1145 + */ 1146 + [C(OP_READ)] = { 1147 + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1148 + [C(RESULT_MISS)] = { 0x2d, CNTR_ALL }, /* PAPI_TLB_DM */ 1149 + }, 1150 + [C(OP_WRITE)] = { 1151 + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1152 + [C(RESULT_MISS)] = { 0x2d, CNTR_ALL }, /* PAPI_TLB_DM */ 1153 + }, 1154 + [C(OP_PREFETCH)] = { 1155 + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1156 + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1157 + }, 1158 + }, 1159 + [C(ITLB)] = { 1160 + [C(OP_READ)] = { 1161 + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1162 + [C(RESULT_MISS)] = { 0x08, CNTR_ALL }, /* PAPI_TLB_IM */ 1163 + }, 1164 + [C(OP_WRITE)] = { 1165 + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1166 + [C(RESULT_MISS)] = { 0x08, CNTR_ALL }, /* PAPI_TLB_IM */ 1167 + }, 1168 + [C(OP_PREFETCH)] = { 1169 + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1170 + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1171 + }, 1172 + }, 1173 + [C(BPU)] = { 1174 + [C(OP_READ)] = { 1175 + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1176 + [C(RESULT_MISS)] = { 0x25, CNTR_ALL }, 1177 + }, 1178 + [C(OP_WRITE)] = { 1179 + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1180 + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1181 + }, 1182 + [C(OP_PREFETCH)] = { 1183 + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1184 + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, 1101 1185 }, 1102 1186 }, 1103 1187 }; ··· 1548 1444 return &raw_event; 1549 1445 } 1550 1446 1447 + static const struct mips_perf_event *xlp_pmu_map_raw_event(u64 config) 1448 + { 1449 + unsigned int raw_id = config & 0xff; 1450 + 1451 + /* Only 1-63 are defined */ 1452 + if ((raw_id < 0x01) || (raw_id > 0x3f)) 1453 + return ERR_PTR(-EOPNOTSUPP); 1454 + 1455 + raw_event.cntr_mask = CNTR_ALL; 1456 + raw_event.event_id = raw_id; 1457 + 1458 + return &raw_event; 1459 + } 1460 + 1551 1461 static int __init 1552 1462 init_hw_perf_events(void) 1553 1463 { ··· 1639 1521 mipspmu.name = "BMIPS5000"; 1640 1522 mipspmu.general_event_map = &bmips5000_event_map; 1641 1523 mipspmu.cache_event_map = &bmips5000_cache_map; 1524 + break; 1525 + case CPU_XLP: 1526 + mipspmu.name = "xlp"; 1527 + mipspmu.general_event_map = &xlp_event_map; 1528 + mipspmu.cache_event_map = &xlp_cache_map; 1529 + mipspmu.map_raw_event = xlp_pmu_map_raw_event; 1642 1530 break; 1643 1531 default: 1644 1532 pr_cont("Either hardware does not support performance "
+4
arch/mips/lantiq/Kconfig
··· 36 36 bool "PCI Support" 37 37 depends on SOC_XWAY && PCI 38 38 39 + config XRX200_PHY_FW 40 + bool "XRX200 PHY firmware loader" 41 + depends on SOC_XWAY 42 + 39 43 endif
+1 -4
arch/mips/lantiq/prom.c
··· 87 87 reserve_bootmem(base, size, BOOTMEM_DEFAULT); 88 88 89 89 unflatten_device_tree(); 90 - 91 - /* free the space reserved for the dt blob */ 92 - free_bootmem(base, size); 93 90 } 94 91 95 92 void __init prom_init(void) ··· 116 119 sizeof(of_ids[0].compatible)); 117 120 strncpy(of_ids[1].compatible, "simple-bus", 118 121 sizeof(of_ids[1].compatible)); 119 - return of_platform_bus_probe(NULL, of_ids, NULL); 122 + return of_platform_populate(NULL, of_ids, NULL, NULL); 120 123 } 121 124 122 125 arch_initcall(plat_of_setup);
+2
arch/mips/lantiq/xway/Makefile
··· 1 1 obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o 2 + 3 + obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o
+8 -1
arch/mips/lantiq/xway/dma.c
··· 25 25 #include <lantiq_soc.h> 26 26 #include <xway_dma.h> 27 27 28 + #define LTQ_DMA_ID 0x08 28 29 #define LTQ_DMA_CTRL 0x10 29 30 #define LTQ_DMA_CPOLL 0x14 30 31 #define LTQ_DMA_CS 0x18 ··· 215 214 { 216 215 struct clk *clk; 217 216 struct resource *res; 217 + unsigned id; 218 218 int i; 219 219 220 220 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ··· 245 243 ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); 246 244 ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); 247 245 } 248 - dev_info(&pdev->dev, "init done\n"); 246 + 247 + id = ltq_dma_r32(LTQ_DMA_ID); 248 + dev_info(&pdev->dev, 249 + "Init done - hw rev: %X, ports: %d, channels: %d\n", 250 + id & 0x1f, (id >> 16) & 0xf, id >> 20); 251 + 249 252 return 0; 250 253 } 251 254
+51 -7
arch/mips/lantiq/xway/reset.c
··· 28 28 #define RCU_RST_REQ 0x0010 29 29 /* reset status register */ 30 30 #define RCU_RST_STAT 0x0014 31 + /* vr9 gphy registers */ 32 + #define RCU_GFS_ADD0_XRX200 0x0020 33 + #define RCU_GFS_ADD1_XRX200 0x0068 31 34 32 35 /* reboot bit */ 36 + #define RCU_RD_GPHY0_XRX200 BIT(31) 33 37 #define RCU_RD_SRST BIT(30) 38 + #define RCU_RD_GPHY1_XRX200 BIT(29) 39 + 34 40 /* reset cause */ 35 41 #define RCU_STAT_SHIFT 26 36 42 /* boot selection */ 37 - #define RCU_BOOT_SEL_SHIFT 26 38 - #define RCU_BOOT_SEL_MASK 0x7 43 + #define RCU_BOOT_SEL(x) ((x >> 18) & 0x7) 44 + #define RCU_BOOT_SEL_XRX200(x) (((x >> 17) & 0xf) | ((x >> 8) & 0x10)) 39 45 40 46 /* remapped base addr of the reset control unit */ 41 47 static void __iomem *ltq_rcu_membase; 48 + static struct device_node *ltq_rcu_np; 42 49 43 50 /* This function is used by the watchdog driver */ 44 51 int ltq_reset_cause(void) ··· 59 52 unsigned char ltq_boot_select(void) 60 53 { 61 54 u32 val = ltq_rcu_r32(RCU_RST_STAT); 62 - return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK; 55 + 56 + if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) 57 + return RCU_BOOT_SEL_XRX200(val); 58 + 59 + return RCU_BOOT_SEL(val); 60 + } 61 + 62 + /* reset / boot a gphy */ 63 + static struct ltq_xrx200_gphy_reset { 64 + u32 rd; 65 + u32 addr; 66 + } xrx200_gphy[] = { 67 + {RCU_RD_GPHY0_XRX200, RCU_GFS_ADD0_XRX200}, 68 + {RCU_RD_GPHY1_XRX200, RCU_GFS_ADD1_XRX200}, 69 + }; 70 + 71 + /* reset and boot a gphy. these phys only exist on xrx200 SoC */ 72 + int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr) 73 + { 74 + if (!of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) { 75 + dev_err(dev, "this SoC has no GPHY\n"); 76 + return -EINVAL; 77 + } 78 + if (id > 1) { 79 + dev_err(dev, "%u is an invalid gphy id\n", id); 80 + return -EINVAL; 81 + } 82 + dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr); 83 + 84 + ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | xrx200_gphy[id].rd, 85 + RCU_RST_REQ); 86 + ltq_rcu_w32(dev_addr, xrx200_gphy[id].addr); 87 + ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~xrx200_gphy[id].rd, 88 + RCU_RST_REQ); 89 + return 0; 63 90 } 64 91 65 92 /* reset a io domain for u micro seconds */ ··· 126 85 static int __init mips_reboot_setup(void) 127 86 { 128 87 struct resource res; 129 - struct device_node *np = 130 - of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway"); 88 + 89 + ltq_rcu_np = of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway"); 90 + if (!ltq_rcu_np) 91 + ltq_rcu_np = of_find_compatible_node(NULL, NULL, 92 + "lantiq,rcu-xrx200"); 131 93 132 94 /* check if all the reset register range is available */ 133 - if (!np) 95 + if (!ltq_rcu_np) 134 96 panic("Failed to load reset resources from devicetree"); 135 97 136 - if (of_address_to_resource(np, 0, &res)) 98 + if (of_address_to_resource(ltq_rcu_np, 0, &res)) 137 99 panic("Failed to get rcu memory range"); 138 100 139 101 if (request_mem_region(res.start, resource_size(&res), res.name) < 0)
+4
arch/mips/lantiq/xway/sysctrl.c
··· 370 370 clkdev_add_pmu("1d900000.pcie", "pdi", 1, PMU1_PCIE_PDI); 371 371 clkdev_add_pmu("1d900000.pcie", "ctl", 1, PMU1_PCIE_CTL); 372 372 clkdev_add_pmu("1d900000.pcie", "ahb", 0, PMU_AHBM | PMU_AHBS); 373 + clkdev_add_pmu("1e108000.eth", NULL, 0, 374 + PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM | 375 + PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 | 376 + PMU_PPE_QSB | PMU_PPE_TOP); 373 377 } else if (of_machine_is_compatible("lantiq,ar9")) { 374 378 clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), 375 379 ltq_ar9_fpi_hz());
+97
arch/mips/lantiq/xway/xrx200_phy_fw.c
··· 1 + /* 2 + * This program is free software; you can redistribute it and/or modify it 3 + * under the terms of the GNU General Public License version 2 as published 4 + * by the Free Software Foundation. 5 + * 6 + * Copyright (C) 2012 John Crispin <blogic@openwrt.org> 7 + */ 8 + 9 + #include <linux/delay.h> 10 + #include <linux/dma-mapping.h> 11 + #include <linux/module.h> 12 + #include <linux/firmware.h> 13 + #include <linux/of_platform.h> 14 + 15 + #include <lantiq_soc.h> 16 + 17 + #define XRX200_GPHY_FW_ALIGN (16 * 1024) 18 + 19 + static dma_addr_t xway_gphy_load(struct platform_device *pdev) 20 + { 21 + const struct firmware *fw; 22 + dma_addr_t dev_addr = 0; 23 + const char *fw_name; 24 + void *fw_addr; 25 + size_t size; 26 + 27 + if (of_property_read_string(pdev->dev.of_node, "firmware", &fw_name)) { 28 + dev_err(&pdev->dev, "failed to load firmware filename\n"); 29 + return 0; 30 + } 31 + 32 + dev_info(&pdev->dev, "requesting %s\n", fw_name); 33 + if (request_firmware(&fw, fw_name, &pdev->dev)) { 34 + dev_err(&pdev->dev, "failed to load firmware: %s\n", fw_name); 35 + return 0; 36 + } 37 + 38 + /* 39 + * GPHY cores need the firmware code in a persistent and contiguous 40 + * memory area with a 16 kB boundary aligned start address 41 + */ 42 + size = fw->size + XRX200_GPHY_FW_ALIGN; 43 + 44 + fw_addr = dma_alloc_coherent(&pdev->dev, size, &dev_addr, GFP_KERNEL); 45 + if (fw_addr) { 46 + fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN); 47 + dev_addr = ALIGN(dev_addr, XRX200_GPHY_FW_ALIGN); 48 + memcpy(fw_addr, fw->data, fw->size); 49 + } else { 50 + dev_err(&pdev->dev, "failed to alloc firmware memory\n"); 51 + } 52 + 53 + release_firmware(fw); 54 + return dev_addr; 55 + } 56 + 57 + static int __devinit xway_phy_fw_probe(struct platform_device *pdev) 58 + { 59 + dma_addr_t fw_addr; 60 + struct property *pp; 61 + unsigned char *phyids; 62 + int i, ret = 0; 63 + 64 + fw_addr = xway_gphy_load(pdev); 65 + if (!fw_addr) 66 + return -EINVAL; 67 + pp = of_find_property(pdev->dev.of_node, "phys", NULL); 68 + if (!pp) 69 + return -ENOENT; 70 + phyids = pp->value; 71 + for (i = 0; i < pp->length && !ret; i++) 72 + ret = xrx200_gphy_boot(&pdev->dev, phyids[i], fw_addr); 73 + if (!ret) 74 + mdelay(100); 75 + return ret; 76 + } 77 + 78 + static const struct of_device_id xway_phy_match[] = { 79 + { .compatible = "lantiq,phy-xrx200" }, 80 + {}, 81 + }; 82 + MODULE_DEVICE_TABLE(of, xway_phy_match); 83 + 84 + static struct platform_driver xway_phy_driver = { 85 + .probe = xway_phy_fw_probe, 86 + .driver = { 87 + .name = "phy-xrx200", 88 + .owner = THIS_MODULE, 89 + .of_match_table = xway_phy_match, 90 + }, 91 + }; 92 + 93 + module_platform_driver(xway_phy_driver); 94 + 95 + MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); 96 + MODULE_DESCRIPTION("Lantiq XRX200 PHY Firmware Loader"); 97 + MODULE_LICENSE("GPL");
+1 -1
arch/mips/loongson1/Kconfig
··· 15 15 select SYS_SUPPORTS_LITTLE_ENDIAN 16 16 select SYS_SUPPORTS_HIGHMEM 17 17 select SYS_HAS_EARLY_PRINTK 18 - select HAVE_CLK 18 + select COMMON_CLK 19 19 20 20 endchoice 21 21
+3 -156
arch/mips/loongson1/common/clock.c
··· 7 7 * option) any later version. 8 8 */ 9 9 10 - #include <linux/module.h> 11 - #include <linux/list.h> 12 - #include <linux/mutex.h> 13 10 #include <linux/clk.h> 14 11 #include <linux/err.h> 15 - #include <asm/clock.h> 16 12 #include <asm/time.h> 17 - 18 - #include <loongson1.h> 19 - 20 - static LIST_HEAD(clocks); 21 - static DEFINE_MUTEX(clocks_mutex); 22 - 23 - struct clk *clk_get(struct device *dev, const char *name) 24 - { 25 - struct clk *c; 26 - struct clk *ret = NULL; 27 - 28 - mutex_lock(&clocks_mutex); 29 - list_for_each_entry(c, &clocks, node) { 30 - if (!strcmp(c->name, name)) { 31 - ret = c; 32 - break; 33 - } 34 - } 35 - mutex_unlock(&clocks_mutex); 36 - 37 - return ret; 38 - } 39 - EXPORT_SYMBOL(clk_get); 40 - 41 - int clk_enable(struct clk *clk) 42 - { 43 - return 0; 44 - } 45 - EXPORT_SYMBOL(clk_enable); 46 - 47 - void clk_disable(struct clk *clk) 48 - { 49 - } 50 - EXPORT_SYMBOL(clk_disable); 51 - 52 - unsigned long clk_get_rate(struct clk *clk) 53 - { 54 - return clk->rate; 55 - } 56 - EXPORT_SYMBOL(clk_get_rate); 57 - 58 - void clk_put(struct clk *clk) 59 - { 60 - } 61 - EXPORT_SYMBOL(clk_put); 62 - 63 - static void pll_clk_init(struct clk *clk) 64 - { 65 - u32 pll; 66 - 67 - pll = __raw_readl(LS1X_CLK_PLL_FREQ); 68 - clk->rate = (12 + (pll & 0x3f)) * 33 / 2 69 - + ((pll >> 8) & 0x3ff) * 33 / 1024 / 2; 70 - clk->rate *= 1000000; 71 - } 72 - 73 - static void cpu_clk_init(struct clk *clk) 74 - { 75 - u32 pll, ctrl; 76 - 77 - pll = clk_get_rate(clk->parent); 78 - ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_CPU; 79 - clk->rate = pll / (ctrl >> DIV_CPU_SHIFT); 80 - } 81 - 82 - static void ddr_clk_init(struct clk *clk) 83 - { 84 - u32 pll, ctrl; 85 - 86 - pll = clk_get_rate(clk->parent); 87 - ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_DDR; 88 - clk->rate = pll / (ctrl >> DIV_DDR_SHIFT); 89 - } 90 - 91 - static void dc_clk_init(struct clk *clk) 92 - { 93 - u32 pll, ctrl; 94 - 95 - pll = clk_get_rate(clk->parent); 96 - ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_DC; 97 - clk->rate = pll / (ctrl >> DIV_DC_SHIFT); 98 - } 99 - 100 - static struct clk_ops pll_clk_ops = { 101 - .init = pll_clk_init, 102 - }; 103 - 104 - static struct clk_ops cpu_clk_ops = { 105 - .init = cpu_clk_init, 106 - }; 107 - 108 - static struct clk_ops ddr_clk_ops = { 109 - .init = ddr_clk_init, 110 - }; 111 - 112 - static struct clk_ops dc_clk_ops = { 113 - .init = dc_clk_init, 114 - }; 115 - 116 - static struct clk pll_clk = { 117 - .name = "pll", 118 - .ops = &pll_clk_ops, 119 - }; 120 - 121 - static struct clk cpu_clk = { 122 - .name = "cpu", 123 - .parent = &pll_clk, 124 - .ops = &cpu_clk_ops, 125 - }; 126 - 127 - static struct clk ddr_clk = { 128 - .name = "ddr", 129 - .parent = &pll_clk, 130 - .ops = &ddr_clk_ops, 131 - }; 132 - 133 - static struct clk dc_clk = { 134 - .name = "dc", 135 - .parent = &pll_clk, 136 - .ops = &dc_clk_ops, 137 - }; 138 - 139 - int clk_register(struct clk *clk) 140 - { 141 - mutex_lock(&clocks_mutex); 142 - list_add(&clk->node, &clocks); 143 - if (clk->ops->init) 144 - clk->ops->init(clk); 145 - mutex_unlock(&clocks_mutex); 146 - 147 - return 0; 148 - } 149 - EXPORT_SYMBOL(clk_register); 150 - 151 - static struct clk *ls1x_clks[] = { 152 - &pll_clk, 153 - &cpu_clk, 154 - &ddr_clk, 155 - &dc_clk, 156 - }; 157 - 158 - int __init ls1x_clock_init(void) 159 - { 160 - int i; 161 - 162 - for (i = 0; i < ARRAY_SIZE(ls1x_clks); i++) 163 - clk_register(ls1x_clks[i]); 164 - 165 - return 0; 166 - } 13 + #include <platform.h> 167 14 168 15 void __init plat_time_init(void) 169 16 { 170 17 struct clk *clk; 171 18 172 19 /* Initialize LS1X clocks */ 173 - ls1x_clock_init(); 20 + ls1x_clk_init(); 174 21 175 22 /* setup mips r4k timer */ 176 23 clk = clk_get(NULL, "cpu"); 177 24 if (IS_ERR(clk)) 178 - panic("unable to get dc clock, err=%ld", PTR_ERR(clk)); 25 + panic("unable to get cpu clock, err=%ld", PTR_ERR(clk)); 179 26 180 27 mips_hpt_frequency = clk_get_rate(clk) / 2; 181 28 }
+5 -5
arch/mips/loongson1/common/platform.c
··· 42 42 }, 43 43 }; 44 44 45 - void __init ls1x_serial_setup(void) 45 + void __init ls1x_serial_setup(struct platform_device *pdev) 46 46 { 47 47 struct clk *clk; 48 48 struct plat_serial8250_port *p; 49 49 50 - clk = clk_get(NULL, "dc"); 50 + clk = clk_get(NULL, pdev->name); 51 51 if (IS_ERR(clk)) 52 - panic("unable to get dc clock, err=%ld", PTR_ERR(clk)); 52 + panic("unable to get %s clock, err=%ld", 53 + pdev->name, PTR_ERR(clk)); 53 54 54 - for (p = ls1x_serial8250_port; p->flags != 0; ++p) 55 + for (p = pdev->dev.platform_data; p->flags != 0; ++p) 55 56 p->uartclk = clk_get_rate(clk); 56 57 } 57 58 ··· 71 70 }; 72 71 73 72 static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { 74 - .bus_id = 0, 75 73 .phy_mask = 0, 76 74 }; 77 75
+1 -4
arch/mips/loongson1/ls1b/board.c
··· 9 9 10 10 #include <platform.h> 11 11 12 - #include <linux/serial_8250.h> 13 - #include <loongson1.h> 14 - 15 12 static struct platform_device *ls1b_platform_devices[] __initdata = { 16 13 &ls1x_uart_device, 17 14 &ls1x_eth0_device, ··· 20 23 { 21 24 int err; 22 25 23 - ls1x_serial_setup(); 26 + ls1x_serial_setup(&ls1x_uart_device); 24 27 25 28 err = platform_add_devices(ls1b_platform_devices, 26 29 ARRAY_SIZE(ls1b_platform_devices));
+4 -4
arch/mips/mm/c-r4k.c
··· 1333 1333 { 1334 1334 get_option(&str, &cca); 1335 1335 1336 - return 1; 1336 + return 0; 1337 1337 } 1338 1338 1339 - __setup("cca=", cca_setup); 1339 + early_param("cca", cca_setup); 1340 1340 1341 1341 static void __cpuinit coherency_setup(void) 1342 1342 { ··· 1386 1386 { 1387 1387 coherentio = 1; 1388 1388 1389 - return 1; 1389 + return 0; 1390 1390 } 1391 1391 1392 - __setup("coherentio", setcoherentio); 1392 + early_param("coherentio", setcoherentio); 1393 1393 #endif 1394 1394 1395 1395 static void __cpuinit r4k_cache_error_setup(void)
+6 -2
arch/mips/mm/tlbex.c
··· 183 183 184 184 static int __cpuinitdata hazard_instance; 185 185 186 - static void uasm_bgezl_hazard(u32 **p, struct uasm_reloc **r, int instance) 186 + static void __cpuinit uasm_bgezl_hazard(u32 **p, 187 + struct uasm_reloc **r, 188 + int instance) 187 189 { 188 190 switch (instance) { 189 191 case 0 ... 7: ··· 196 194 } 197 195 } 198 196 199 - static void uasm_bgezl_label(struct uasm_label **l, u32 **p, int instance) 197 + static void __cpuinit uasm_bgezl_label(struct uasm_label **l, 198 + u32 **p, 199 + int instance) 200 200 { 201 201 switch (instance) { 202 202 case 0 ... 7:
+28
arch/mips/netlogic/Kconfig
··· 9 9 This DTB will be used if the firmware does not pass in a DTB 10 10 pointer to the kernel. The corresponding DTS file is at 11 11 arch/mips/netlogic/dts/xlp_evp.dts 12 + 13 + config NLM_MULTINODE 14 + bool "Support for multi-chip boards" 15 + depends on NLM_XLP_BOARD 16 + default n 17 + help 18 + Add support for boards with 2 or 4 XLPs connected over ICI. 19 + 20 + if NLM_MULTINODE 21 + choice 22 + prompt "Number of XLPs on the board" 23 + default NLM_MULTINODE_2 24 + help 25 + In the multi-node case, specify the number of SoCs on the board. 26 + 27 + config NLM_MULTINODE_2 28 + bool "Dual-XLP board" 29 + help 30 + Support boards with upto two XLPs connected over ICI. 31 + 32 + config NLM_MULTINODE_4 33 + bool "Quad-XLP board" 34 + help 35 + Support boards with upto four XLPs connected over ICI. 36 + 37 + endchoice 38 + 39 + endif 12 40 endif 13 41 14 42 config NLM_COMMON
+105 -60
arch/mips/netlogic/common/irq.c
··· 36 36 #include <linux/init.h> 37 37 #include <linux/linkage.h> 38 38 #include <linux/interrupt.h> 39 - #include <linux/spinlock.h> 40 39 #include <linux/mm.h> 41 40 #include <linux/slab.h> 42 41 #include <linux/irq.h> ··· 58 59 #elif defined(CONFIG_CPU_XLR) 59 60 #include <asm/netlogic/xlr/iomap.h> 60 61 #include <asm/netlogic/xlr/pic.h> 62 + #include <asm/netlogic/xlr/fmn.h> 61 63 #else 62 64 #error "Unknown CPU" 63 65 #endif 64 - /* 65 - * These are the routines that handle all the low level interrupt stuff. 66 - * Actions handled here are: initialization of the interrupt map, requesting of 67 - * interrupt lines by handlers, dispatching if interrupts to handlers, probing 68 - * for interrupt lines 69 - */ 70 66 71 - /* Globals */ 72 - static uint64_t nlm_irq_mask; 73 - static DEFINE_SPINLOCK(nlm_pic_lock); 67 + #ifdef CONFIG_SMP 68 + #define SMP_IRQ_MASK ((1ULL << IRQ_IPI_SMP_FUNCTION) | \ 69 + (1ULL << IRQ_IPI_SMP_RESCHEDULE)) 70 + #else 71 + #define SMP_IRQ_MASK 0 72 + #endif 73 + #define PERCPU_IRQ_MASK (SMP_IRQ_MASK | (1ull << IRQ_TIMER) | \ 74 + (1ull << IRQ_FMN)) 75 + 76 + struct nlm_pic_irq { 77 + void (*extra_ack)(struct irq_data *); 78 + struct nlm_soc_info *node; 79 + int picirq; 80 + int irt; 81 + int flags; 82 + }; 74 83 75 84 static void xlp_pic_enable(struct irq_data *d) 76 85 { 77 86 unsigned long flags; 78 - int irt; 87 + struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); 79 88 80 - irt = nlm_irq_to_irt(d->irq); 81 - if (irt == -1) 82 - return; 83 - spin_lock_irqsave(&nlm_pic_lock, flags); 84 - nlm_pic_enable_irt(nlm_pic_base, irt); 85 - spin_unlock_irqrestore(&nlm_pic_lock, flags); 89 + BUG_ON(!pd); 90 + spin_lock_irqsave(&pd->node->piclock, flags); 91 + nlm_pic_enable_irt(pd->node->picbase, pd->irt); 92 + spin_unlock_irqrestore(&pd->node->piclock, flags); 86 93 } 87 94 88 95 static void xlp_pic_disable(struct irq_data *d) 89 96 { 97 + struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); 90 98 unsigned long flags; 91 - int irt; 92 99 93 - irt = nlm_irq_to_irt(d->irq); 94 - if (irt == -1) 95 - return; 96 - spin_lock_irqsave(&nlm_pic_lock, flags); 97 - nlm_pic_disable_irt(nlm_pic_base, irt); 98 - spin_unlock_irqrestore(&nlm_pic_lock, flags); 100 + BUG_ON(!pd); 101 + spin_lock_irqsave(&pd->node->piclock, flags); 102 + nlm_pic_disable_irt(pd->node->picbase, pd->irt); 103 + spin_unlock_irqrestore(&pd->node->piclock, flags); 99 104 } 100 105 101 106 static void xlp_pic_mask_ack(struct irq_data *d) 102 107 { 103 - uint64_t mask = 1ull << d->irq; 108 + struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); 109 + uint64_t mask = 1ull << pd->picirq; 104 110 105 111 write_c0_eirr(mask); /* ack by writing EIRR */ 106 112 } 107 113 108 114 static void xlp_pic_unmask(struct irq_data *d) 109 115 { 110 - void *hd = irq_data_get_irq_handler_data(d); 111 - int irt; 116 + struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); 112 117 113 - irt = nlm_irq_to_irt(d->irq); 114 - if (irt == -1) 118 + if (!pd) 115 119 return; 116 120 117 - if (hd) { 118 - void (*extra_ack)(void *) = hd; 119 - extra_ack(d); 120 - } 121 + if (pd->extra_ack) 122 + pd->extra_ack(d); 123 + 121 124 /* Ack is a single write, no need to lock */ 122 - nlm_pic_ack(nlm_pic_base, irt); 125 + nlm_pic_ack(pd->node->picbase, pd->irt); 123 126 } 124 127 125 128 static struct irq_chip xlp_pic = { ··· 175 174 .irq_eoi = cpuintr_ack, 176 175 }; 177 176 178 - void __init init_nlm_common_irqs(void) 177 + static void __init nlm_init_percpu_irqs(void) 179 178 { 180 - int i, irq, irt; 179 + int i; 181 180 182 181 for (i = 0; i < PIC_IRT_FIRST_IRQ; i++) 183 182 irq_set_chip_and_handler(i, &nlm_cpu_intr, handle_percpu_irq); 184 - 185 - for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ ; i++) 186 - irq_set_chip_and_handler(i, &xlp_pic, handle_level_irq); 187 - 188 183 #ifdef CONFIG_SMP 189 184 irq_set_chip_and_handler(IRQ_IPI_SMP_FUNCTION, &nlm_cpu_intr, 190 185 nlm_smp_function_ipi_handler); 191 186 irq_set_chip_and_handler(IRQ_IPI_SMP_RESCHEDULE, &nlm_cpu_intr, 192 187 nlm_smp_resched_ipi_handler); 193 - nlm_irq_mask |= 194 - ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE)); 195 188 #endif 189 + } 196 190 197 - for (irq = PIC_IRT_FIRST_IRQ; irq <= PIC_IRT_LAST_IRQ; irq++) { 198 - irt = nlm_irq_to_irt(irq); 191 + void nlm_setup_pic_irq(int node, int picirq, int irq, int irt) 192 + { 193 + struct nlm_pic_irq *pic_data; 194 + int xirq; 195 + 196 + xirq = nlm_irq_to_xirq(node, irq); 197 + pic_data = kzalloc(sizeof(*pic_data), GFP_KERNEL); 198 + BUG_ON(pic_data == NULL); 199 + pic_data->irt = irt; 200 + pic_data->picirq = picirq; 201 + pic_data->node = nlm_get_node(node); 202 + irq_set_chip_and_handler(xirq, &xlp_pic, handle_level_irq); 203 + irq_set_handler_data(xirq, pic_data); 204 + } 205 + 206 + void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *)) 207 + { 208 + struct nlm_pic_irq *pic_data; 209 + int xirq; 210 + 211 + xirq = nlm_irq_to_xirq(node, irq); 212 + pic_data = irq_get_handler_data(xirq); 213 + pic_data->extra_ack = xack; 214 + } 215 + 216 + static void nlm_init_node_irqs(int node) 217 + { 218 + int i, irt; 219 + uint64_t irqmask; 220 + struct nlm_soc_info *nodep; 221 + 222 + pr_info("Init IRQ for node %d\n", node); 223 + nodep = nlm_get_node(node); 224 + irqmask = PERCPU_IRQ_MASK; 225 + for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ; i++) { 226 + irt = nlm_irq_to_irt(i); 199 227 if (irt == -1) 200 228 continue; 201 - nlm_irq_mask |= (1ULL << irq); 202 - nlm_pic_init_irt(nlm_pic_base, irt, irq, 0); 229 + nlm_setup_pic_irq(node, i, i, irt); 230 + /* set interrupts to first cpu in node */ 231 + nlm_pic_init_irt(nodep->picbase, irt, i, 232 + node * NLM_CPUS_PER_NODE); 233 + irqmask |= (1ull << i); 203 234 } 204 - 205 - nlm_irq_mask |= (1ULL << IRQ_TIMER); 235 + nodep->irqmask = irqmask; 206 236 } 207 237 208 238 void __init arch_init_irq(void) 209 239 { 210 240 /* Initialize the irq descriptors */ 211 - init_nlm_common_irqs(); 212 - 213 - write_c0_eimr(nlm_irq_mask); 241 + nlm_init_percpu_irqs(); 242 + nlm_init_node_irqs(0); 243 + write_c0_eimr(nlm_current_node()->irqmask); 244 + #if defined(CONFIG_CPU_XLR) 245 + nlm_setup_fmn_irq(); 246 + #endif 214 247 } 215 248 216 - void __cpuinit nlm_smp_irq_init(void) 249 + void nlm_smp_irq_init(int hwcpuid) 217 250 { 218 - /* set interrupt mask for non-zero cpus */ 219 - write_c0_eimr(nlm_irq_mask); 251 + int node, cpu; 252 + 253 + node = hwcpuid / NLM_CPUS_PER_NODE; 254 + cpu = hwcpuid % NLM_CPUS_PER_NODE; 255 + 256 + if (cpu == 0 && node != 0) 257 + nlm_init_node_irqs(node); 258 + write_c0_eimr(nlm_current_node()->irqmask); 220 259 } 221 260 222 261 asmlinkage void plat_irq_dispatch(void) 223 262 { 224 263 uint64_t eirr; 225 - int i; 264 + int i, node; 226 265 266 + node = nlm_nodeid(); 227 267 eirr = read_c0_eirr() & read_c0_eimr(); 228 - if (eirr & (1 << IRQ_TIMER)) { 229 - do_IRQ(IRQ_TIMER); 230 - return; 231 - } 232 268 233 269 i = __ilog2_u64(eirr); 234 270 if (i == -1) 235 271 return; 236 272 237 - do_IRQ(i); 273 + /* per-CPU IRQs don't need translation */ 274 + if (eirr & PERCPU_IRQ_MASK) { 275 + do_IRQ(i); 276 + return; 277 + } 278 + 279 + /* top level irq handling */ 280 + do_IRQ(nlm_irq_to_xirq(node, i)); 238 281 }
+51 -38
arch/mips/netlogic/common/smp.c
··· 59 59 60 60 void nlm_send_ipi_single(int logical_cpu, unsigned int action) 61 61 { 62 - int cpu = cpu_logical_map(logical_cpu); 62 + int cpu, node; 63 + uint64_t picbase; 64 + 65 + cpu = cpu_logical_map(logical_cpu); 66 + node = cpu / NLM_CPUS_PER_NODE; 67 + picbase = nlm_get_node(node)->picbase; 63 68 64 69 if (action & SMP_CALL_FUNCTION) 65 - nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_FUNCTION, 0); 70 + nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_FUNCTION, 0); 66 71 if (action & SMP_RESCHEDULE_YOURSELF) 67 - nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_RESCHEDULE, 0); 72 + nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_RESCHEDULE, 0); 68 73 } 69 74 70 75 void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action) ··· 101 96 void nlm_early_init_secondary(int cpu) 102 97 { 103 98 change_c0_config(CONF_CM_CMASK, 0x3); 104 - write_c0_ebase((uint32_t)nlm_common_ebase); 105 99 #ifdef CONFIG_CPU_XLP 106 - if (hard_smp_processor_id() % 4 == 0) 100 + /* mmu init, once per core */ 101 + if (cpu % NLM_THREADS_PER_CORE == 0) 107 102 xlp_mmu_init(); 108 103 #endif 104 + write_c0_ebase(nlm_current_node()->ebase); 109 105 } 110 106 111 107 /* ··· 114 108 */ 115 109 static void __cpuinit nlm_init_secondary(void) 116 110 { 117 - current_cpu_data.core = hard_smp_processor_id() / 4; 118 - nlm_smp_irq_init(); 111 + int hwtid; 112 + 113 + hwtid = hard_smp_processor_id(); 114 + current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE; 115 + nlm_percpu_init(hwtid); 116 + nlm_smp_irq_init(hwtid); 119 117 } 120 118 121 119 void nlm_prepare_cpus(unsigned int max_cpus) ··· 130 120 131 121 void nlm_smp_finish(void) 132 122 { 133 - #ifdef notyet 134 - nlm_common_msgring_cpu_init(); 135 - #endif 136 123 local_irq_enable(); 137 124 } 138 125 ··· 149 142 150 143 void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) 151 144 { 152 - unsigned long gp = (unsigned long)task_thread_info(idle); 153 - unsigned long sp = (unsigned long)__KSTK_TOS(idle); 154 - int cpu = cpu_logical_map(logical_cpu); 145 + int cpu, node; 155 146 156 - nlm_next_sp = sp; 157 - nlm_next_gp = gp; 147 + cpu = cpu_logical_map(logical_cpu); 148 + node = cpu / NLM_CPUS_PER_NODE; 149 + nlm_next_sp = (unsigned long)__KSTK_TOS(idle); 150 + nlm_next_gp = (unsigned long)task_thread_info(idle); 158 151 159 - /* barrier */ 152 + /* barrier for sp/gp store above */ 160 153 __sync(); 161 - nlm_pic_send_ipi(nlm_pic_base, cpu, 1, 1); 154 + nlm_pic_send_ipi(nlm_get_node(node)->picbase, cpu, 1, 1); /* NMI */ 162 155 } 163 156 164 157 void __init nlm_smp_setup(void) 165 158 { 166 159 unsigned int boot_cpu; 167 - int num_cpus, i; 160 + int num_cpus, i, ncore; 168 161 169 162 boot_cpu = hard_smp_processor_id(); 170 - cpus_clear(phys_cpu_present_map); 163 + cpumask_clear(&phys_cpu_present_map); 171 164 172 - cpu_set(boot_cpu, phys_cpu_present_map); 165 + cpumask_set_cpu(boot_cpu, &phys_cpu_present_map); 173 166 __cpu_number_map[boot_cpu] = 0; 174 167 __cpu_logical_map[0] = boot_cpu; 175 168 set_cpu_possible(0, true); ··· 181 174 * it is only set for ASPs (see smpboot.S) 182 175 */ 183 176 if (nlm_cpu_ready[i]) { 184 - cpu_set(i, phys_cpu_present_map); 177 + cpumask_set_cpu(i, &phys_cpu_present_map); 185 178 __cpu_number_map[i] = num_cpus; 186 179 __cpu_logical_map[num_cpus] = i; 187 180 set_cpu_possible(num_cpus, true); ··· 189 182 } 190 183 } 191 184 185 + /* check with the cores we have worken up */ 186 + for (ncore = 0, i = 0; i < NLM_NR_NODES; i++) 187 + ncore += hweight32(nlm_get_node(i)->coremask); 188 + 192 189 pr_info("Phys CPU present map: %lx, possible map %lx\n", 193 - (unsigned long)phys_cpu_present_map.bits[0], 190 + (unsigned long)cpumask_bits(&phys_cpu_present_map)[0], 194 191 (unsigned long)cpumask_bits(cpu_possible_mask)[0]); 195 192 196 - pr_info("Detected %i Slave CPU(s)\n", num_cpus); 193 + pr_info("Detected (%dc%dt) %d Slave CPU(s)\n", ncore, 194 + nlm_threads_per_core, num_cpus); 197 195 nlm_set_nmi_handler(nlm_boot_secondary_cpus); 198 196 } 199 197 200 - static int nlm_parse_cpumask(u32 cpu_mask) 198 + static int nlm_parse_cpumask(cpumask_t *wakeup_mask) 201 199 { 202 200 uint32_t core0_thr_mask, core_thr_mask; 203 - int threadmode, i; 201 + int threadmode, i, j; 204 202 205 - core0_thr_mask = cpu_mask & 0xf; 203 + core0_thr_mask = 0; 204 + for (i = 0; i < NLM_THREADS_PER_CORE; i++) 205 + if (cpumask_test_cpu(i, wakeup_mask)) 206 + core0_thr_mask |= (1 << i); 206 207 switch (core0_thr_mask) { 207 208 case 1: 208 209 nlm_threads_per_core = 1; ··· 229 214 } 230 215 231 216 /* Verify other cores CPU masks */ 232 - nlm_coremask = 1; 233 - nlm_cpumask = core0_thr_mask; 234 - for (i = 1; i < 8; i++) { 235 - core_thr_mask = (cpu_mask >> (i * 4)) & 0xf; 236 - if (core_thr_mask) { 237 - if (core_thr_mask != core0_thr_mask) 217 + for (i = 0; i < NR_CPUS; i += NLM_THREADS_PER_CORE) { 218 + core_thr_mask = 0; 219 + for (j = 0; j < NLM_THREADS_PER_CORE; j++) 220 + if (cpumask_test_cpu(i + j, wakeup_mask)) 221 + core_thr_mask |= (1 << j); 222 + if (core_thr_mask != 0 && core_thr_mask != core0_thr_mask) 238 223 goto unsupp; 239 - nlm_coremask |= 1 << i; 240 - nlm_cpumask |= core0_thr_mask << (4 * i); 241 - } 242 224 } 243 225 return threadmode; 244 226 245 227 unsupp: 246 - panic("Unsupported CPU mask %x\n", cpu_mask); 228 + panic("Unsupported CPU mask %lx\n", 229 + (unsigned long)cpumask_bits(wakeup_mask)[0]); 247 230 return 0; 248 231 } 249 232 250 - int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask) 233 + int __cpuinit nlm_wakeup_secondary_cpus(void) 251 234 { 252 235 unsigned long reset_vec; 253 236 char *reset_data; ··· 257 244 (nlm_reset_entry_end - nlm_reset_entry)); 258 245 259 246 /* verify the mask and setup core config variables */ 260 - threadmode = nlm_parse_cpumask(wakeup_mask); 247 + threadmode = nlm_parse_cpumask(&nlm_cpumask); 261 248 262 249 /* Setup CPU init parameters */ 263 250 reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS);
+4 -2
arch/mips/netlogic/common/smpboot.S
··· 61 61 li t0, LSU_DEFEATURE 62 62 mfcr t1, t0 63 63 64 - lui t2, 0x4080 /* Enable Unaligned Access, L2HPE */ 64 + lui t2, 0xc080 /* SUE, Enable Unaligned Access, L2HPE */ 65 65 or t1, t1, t2 66 66 #ifdef XLP_AX_WORKAROUND 67 67 li t2, ~0xe /* S1RCM */ ··· 186 186 * jump to the secondary wait function. 187 187 */ 188 188 mfc0 v0, CP0_EBASE, 1 189 - andi v0, 0x7f /* v0 <- node/core */ 189 + andi v0, 0x3ff /* v0 <- node/core */ 190 190 191 191 /* Init MMU in the first thread after changing THREAD_MODE 192 192 * register (Ax Errata?) ··· 263 263 PTR_L gp, 0(t1) 264 264 265 265 /* a0 has the processor id */ 266 + mfc0 a0, CP0_EBASE, 1 267 + andi a0, 0x3ff /* a0 <- node/core */ 266 268 PTR_LA t0, nlm_early_init_secondary 267 269 jalr t0 268 270 nop
+15 -52
arch/mips/netlogic/xlp/nlm_hal.c
··· 40 40 #include <asm/mipsregs.h> 41 41 #include <asm/time.h> 42 42 43 + #include <asm/netlogic/common.h> 43 44 #include <asm/netlogic/haldefs.h> 44 45 #include <asm/netlogic/xlp-hal/iomap.h> 45 46 #include <asm/netlogic/xlp-hal/xlp.h> 46 47 #include <asm/netlogic/xlp-hal/pic.h> 47 48 #include <asm/netlogic/xlp-hal/sys.h> 48 49 49 - /* These addresses are computed by the nlm_hal_init() */ 50 - uint64_t nlm_io_base; 51 - uint64_t nlm_sys_base; 52 - uint64_t nlm_pic_base; 53 - 54 50 /* Main initialization */ 55 - void nlm_hal_init(void) 51 + void nlm_node_init(int node) 56 52 { 57 - nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE); 58 - nlm_sys_base = nlm_get_sys_regbase(0); /* node 0 */ 59 - nlm_pic_base = nlm_get_pic_regbase(0); /* node 0 */ 53 + struct nlm_soc_info *nodep; 54 + 55 + nodep = nlm_get_node(node); 56 + nodep->sysbase = nlm_get_sys_regbase(node); 57 + nodep->picbase = nlm_get_pic_regbase(node); 58 + nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1)); 59 + spin_lock_init(&nodep->piclock); 60 60 } 61 61 62 62 int nlm_irq_to_irt(int irq) ··· 100 100 } 101 101 } 102 102 103 - int nlm_irt_to_irq(int irt) 104 - { 105 - switch (irt) { 106 - case PIC_IRT_UART_0_INDEX: 107 - return PIC_UART_0_IRQ; 108 - case PIC_IRT_UART_1_INDEX: 109 - return PIC_UART_1_IRQ; 110 - case PIC_IRT_PCIE_LINK_0_INDEX: 111 - return PIC_PCIE_LINK_0_IRQ; 112 - case PIC_IRT_PCIE_LINK_1_INDEX: 113 - return PIC_PCIE_LINK_1_IRQ; 114 - case PIC_IRT_PCIE_LINK_2_INDEX: 115 - return PIC_PCIE_LINK_2_IRQ; 116 - case PIC_IRT_PCIE_LINK_3_INDEX: 117 - return PIC_PCIE_LINK_3_IRQ; 118 - case PIC_IRT_EHCI_0_INDEX: 119 - return PIC_EHCI_0_IRQ; 120 - case PIC_IRT_EHCI_1_INDEX: 121 - return PIC_EHCI_1_IRQ; 122 - case PIC_IRT_OHCI_0_INDEX: 123 - return PIC_OHCI_0_IRQ; 124 - case PIC_IRT_OHCI_1_INDEX: 125 - return PIC_OHCI_1_IRQ; 126 - case PIC_IRT_OHCI_2_INDEX: 127 - return PIC_OHCI_2_IRQ; 128 - case PIC_IRT_OHCI_3_INDEX: 129 - return PIC_OHCI_3_IRQ; 130 - case PIC_IRT_MMC_INDEX: 131 - return PIC_MMC_IRQ; 132 - case PIC_IRT_I2C_0_INDEX: 133 - return PIC_I2C_0_IRQ; 134 - case PIC_IRT_I2C_1_INDEX: 135 - return PIC_I2C_1_IRQ; 136 - default: 137 - return -1; 138 - } 139 - } 140 - 141 - unsigned int nlm_get_core_frequency(int core) 103 + unsigned int nlm_get_core_frequency(int node, int core) 142 104 { 143 105 unsigned int pll_divf, pll_divr, dfs_div, ext_div; 144 106 unsigned int rstval, dfsval, denom; 145 - uint64_t num; 107 + uint64_t num, sysbase; 146 108 147 - rstval = nlm_read_sys_reg(nlm_sys_base, SYS_POWER_ON_RESET_CFG); 148 - dfsval = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIV_VALUE); 109 + sysbase = nlm_get_node(node)->sysbase; 110 + rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); 111 + dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE); 149 112 pll_divf = ((rstval >> 10) & 0x7f) + 1; 150 113 pll_divr = ((rstval >> 8) & 0x3) + 1; 151 114 ext_div = ((rstval >> 30) & 0x3) + 1; ··· 122 159 123 160 unsigned int nlm_get_cpu_frequency(void) 124 161 { 125 - return nlm_get_core_frequency(0); 162 + return nlm_get_core_frequency(0, 0); 126 163 }
+28 -22
arch/mips/netlogic/xlp/setup.c
··· 52 52 #include <asm/netlogic/xlp-hal/xlp.h> 53 53 #include <asm/netlogic/xlp-hal/sys.h> 54 54 55 - unsigned long nlm_common_ebase = 0x0; 56 - 57 - /* default to uniprocessor */ 58 - uint32_t nlm_coremask = 1, nlm_cpumask = 1; 59 - int nlm_threads_per_core = 1; 55 + uint64_t nlm_io_base; 56 + struct nlm_soc_info nlm_nodes[NLM_NR_NODES]; 57 + cpumask_t nlm_cpumask = CPU_MASK_CPU0; 58 + unsigned int nlm_threads_per_core; 60 59 extern u32 __dtb_start[]; 61 60 62 61 static void nlm_linux_exit(void) 63 62 { 64 - nlm_write_sys_reg(nlm_sys_base, SYS_CHIP_RESET, 1); 63 + uint64_t sysbase = nlm_get_node(0)->sysbase; 64 + 65 + nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1); 65 66 for ( ; ; ) 66 67 cpu_wait(); 67 68 } 68 69 69 70 void __init plat_mem_setup(void) 70 71 { 72 + void *fdtp; 73 + 71 74 panic_timeout = 5; 72 75 _machine_restart = (void (*)(char *))nlm_linux_exit; 73 76 _machine_halt = nlm_linux_exit; 74 77 pm_power_off = nlm_linux_exit; 78 + 79 + /* 80 + * If no FDT pointer is passed in, use the built-in FDT. 81 + * device_tree_init() does not handle CKSEG0 pointers in 82 + * 64-bit, so convert pointer. 83 + */ 84 + fdtp = (void *)(long)fw_arg0; 85 + if (!fdtp) 86 + fdtp = __dtb_start; 87 + fdtp = phys_to_virt(__pa(fdtp)); 88 + early_init_devtree(fdtp); 75 89 } 76 90 77 91 const char *get_system_type(void) ··· 108 94 (13 + (ffz(PM_DEFAULT_MASK >> 13) / 2))); 109 95 } 110 96 97 + void nlm_percpu_init(int hwcpuid) 98 + { 99 + } 100 + 111 101 void __init prom_init(void) 112 102 { 113 - void *fdtp; 114 - 103 + nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE); 115 104 xlp_mmu_init(); 116 - nlm_hal_init(); 105 + nlm_node_init(0); 117 106 118 - /* 119 - * If no FDT pointer is passed in, use the built-in FDT. 120 - * device_tree_init() does not handle CKSEG0 pointers in 121 - * 64-bit, so convert pointer. 122 - */ 123 - fdtp = (void *)(long)fw_arg0; 124 - if (!fdtp) 125 - fdtp = __dtb_start; 126 - fdtp = phys_to_virt(__pa(fdtp)); 127 - early_init_devtree(fdtp); 128 - 129 - nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1)); 130 107 #ifdef CONFIG_SMP 131 - nlm_wakeup_secondary_cpus(0xffffffff); 108 + cpumask_setall(&nlm_cpumask); 109 + nlm_wakeup_secondary_cpus(); 132 110 133 111 /* update TLB size after waking up threads */ 134 112 current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1;
+55 -28
arch/mips/netlogic/xlp/wakeup.c
··· 51 51 #include <asm/netlogic/xlp-hal/xlp.h> 52 52 #include <asm/netlogic/xlp-hal/sys.h> 53 53 54 - static void xlp_enable_secondary_cores(void) 54 + static int xlp_wakeup_core(uint64_t sysbase, int core) 55 55 { 56 - uint32_t core, value, coremask, syscoremask; 56 + uint32_t coremask, value; 57 57 int count; 58 58 59 - /* read cores in reset from SYS block */ 60 - syscoremask = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET); 59 + coremask = (1 << core); 61 60 62 - /* update user specified */ 63 - nlm_coremask = nlm_coremask & (syscoremask | 1); 61 + /* Enable CPU clock */ 62 + value = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL); 63 + value &= ~coremask; 64 + nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value); 64 65 65 - for (core = 1; core < 8; core++) { 66 - coremask = 1 << core; 67 - if ((nlm_coremask & coremask) == 0) 68 - continue; 66 + /* Remove CPU Reset */ 67 + value = nlm_read_sys_reg(sysbase, SYS_CPU_RESET); 68 + value &= ~coremask; 69 + nlm_write_sys_reg(sysbase, SYS_CPU_RESET, value); 69 70 70 - /* Enable CPU clock */ 71 - value = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL); 72 - value &= ~coremask; 73 - nlm_write_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL, value); 71 + /* Poll for CPU to mark itself coherent */ 72 + count = 100000; 73 + do { 74 + value = nlm_read_sys_reg(sysbase, SYS_CPU_NONCOHERENT_MODE); 75 + } while ((value & coremask) != 0 && --count > 0); 74 76 75 - /* Remove CPU Reset */ 76 - value = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET); 77 - value &= ~coremask; 78 - nlm_write_sys_reg(nlm_sys_base, SYS_CPU_RESET, value); 77 + return count != 0; 78 + } 79 79 80 - /* Poll for CPU to mark itself coherent */ 81 - count = 100000; 82 - do { 83 - value = nlm_read_sys_reg(nlm_sys_base, 84 - SYS_CPU_NONCOHERENT_MODE); 85 - } while ((value & coremask) != 0 && count-- > 0); 80 + static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) 81 + { 82 + struct nlm_soc_info *nodep; 83 + uint64_t syspcibase; 84 + uint32_t syscoremask; 85 + int core, n, cpu; 86 86 87 - if (count == 0) 88 - pr_err("Failed to enable core %d\n", core); 87 + for (n = 0; n < NLM_NR_NODES; n++) { 88 + syspcibase = nlm_get_sys_pcibase(n); 89 + if (nlm_read_reg(syspcibase, 0) == 0xffffffff) 90 + break; 91 + 92 + /* read cores in reset from SYS and account for boot cpu */ 93 + nlm_node_init(n); 94 + nodep = nlm_get_node(n); 95 + syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET); 96 + if (n == 0) 97 + syscoremask |= 1; 98 + 99 + for (core = 0; core < NLM_CORES_PER_NODE; core++) { 100 + /* see if the core exists */ 101 + if ((syscoremask & (1 << core)) == 0) 102 + continue; 103 + 104 + /* see if at least the first thread is enabled */ 105 + cpu = (n * NLM_CORES_PER_NODE + core) 106 + * NLM_THREADS_PER_CORE; 107 + if (!cpumask_test_cpu(cpu, wakeup_mask)) 108 + continue; 109 + 110 + /* wake up the core */ 111 + if (xlp_wakeup_core(nodep->sysbase, core)) 112 + nodep->coremask |= 1u << core; 113 + else 114 + pr_err("Failed to enable core %d\n", core); 115 + } 89 116 } 90 117 } 91 118 92 - void xlp_wakeup_secondary_cpus(void) 119 + void xlp_wakeup_secondary_cpus() 93 120 { 94 121 /* 95 122 * In case of u-boot, the secondaries are in reset ··· 125 98 xlp_boot_core0_siblings(); 126 99 127 100 /* now get other cores out of reset */ 128 - xlp_enable_secondary_cores(); 101 + xlp_enable_secondary_cores(&nlm_cpumask); 129 102 }
+2 -2
arch/mips/netlogic/xlr/Makefile
··· 1 - obj-y += setup.o platform.o platform-flash.o 2 - obj-$(CONFIG_SMP) += wakeup.o 1 + obj-y += fmn.o fmn-config.o setup.o platform.o platform-flash.o 2 + obj-$(CONFIG_SMP) += wakeup.o
+290
arch/mips/netlogic/xlr/fmn-config.c
··· 1 + /* 2 + * Copyright (c) 2003-2012 Broadcom Corporation 3 + * All Rights Reserved 4 + * 5 + * This software is available to you under a choice of one of two 6 + * licenses. You may choose to be licensed under the terms of the GNU 7 + * General Public License (GPL) Version 2, available from the file 8 + * COPYING in the main directory of this source tree, or the Broadcom 9 + * license below: 10 + * 11 + * Redistribution and use in source and binary forms, with or without 12 + * modification, are permitted provided that the following conditions 13 + * are met: 14 + * 15 + * 1. Redistributions of source code must retain the above copyright 16 + * notice, this list of conditions and the following disclaimer. 17 + * 2. Redistributions in binary form must reproduce the above copyright 18 + * notice, this list of conditions and the following disclaimer in 19 + * the documentation and/or other materials provided with the 20 + * distribution. 21 + * 22 + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR 23 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 + * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE 26 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 29 + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 32 + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 + */ 34 + 35 + #include <asm/cpu-info.h> 36 + #include <linux/irq.h> 37 + #include <linux/interrupt.h> 38 + 39 + #include <asm/mipsregs.h> 40 + #include <asm/netlogic/xlr/fmn.h> 41 + #include <asm/netlogic/xlr/xlr.h> 42 + #include <asm/netlogic/common.h> 43 + #include <asm/netlogic/haldefs.h> 44 + 45 + struct xlr_board_fmn_config xlr_board_fmn_config; 46 + 47 + static void __maybe_unused print_credit_config(struct xlr_fmn_info *fmn_info) 48 + { 49 + int bkt; 50 + 51 + pr_info("Bucket size :\n"); 52 + pr_info("Station\t: Size\n"); 53 + for (bkt = 0; bkt < 16; bkt++) 54 + pr_info(" %d %d %d %d %d %d %d %d\n", 55 + xlr_board_fmn_config.bucket_size[(bkt * 8) + 0], 56 + xlr_board_fmn_config.bucket_size[(bkt * 8) + 1], 57 + xlr_board_fmn_config.bucket_size[(bkt * 8) + 2], 58 + xlr_board_fmn_config.bucket_size[(bkt * 8) + 3], 59 + xlr_board_fmn_config.bucket_size[(bkt * 8) + 4], 60 + xlr_board_fmn_config.bucket_size[(bkt * 8) + 5], 61 + xlr_board_fmn_config.bucket_size[(bkt * 8) + 6], 62 + xlr_board_fmn_config.bucket_size[(bkt * 8) + 7]); 63 + pr_info("\n"); 64 + 65 + pr_info("Credits distribution :\n"); 66 + pr_info("Station\t: Size\n"); 67 + for (bkt = 0; bkt < 16; bkt++) 68 + pr_info(" %d %d %d %d %d %d %d %d\n", 69 + fmn_info->credit_config[(bkt * 8) + 0], 70 + fmn_info->credit_config[(bkt * 8) + 1], 71 + fmn_info->credit_config[(bkt * 8) + 2], 72 + fmn_info->credit_config[(bkt * 8) + 3], 73 + fmn_info->credit_config[(bkt * 8) + 4], 74 + fmn_info->credit_config[(bkt * 8) + 5], 75 + fmn_info->credit_config[(bkt * 8) + 6], 76 + fmn_info->credit_config[(bkt * 8) + 7]); 77 + pr_info("\n"); 78 + } 79 + 80 + static void check_credit_distribution(void) 81 + { 82 + struct xlr_board_fmn_config *cfg = &xlr_board_fmn_config; 83 + int bkt, n, total_credits, ncores; 84 + 85 + ncores = hweight32(nlm_current_node()->coremask); 86 + for (bkt = 0; bkt < 128; bkt++) { 87 + total_credits = 0; 88 + for (n = 0; n < ncores; n++) 89 + total_credits += cfg->cpu[n].credit_config[bkt]; 90 + total_credits += cfg->gmac[0].credit_config[bkt]; 91 + total_credits += cfg->gmac[1].credit_config[bkt]; 92 + total_credits += cfg->dma.credit_config[bkt]; 93 + total_credits += cfg->cmp.credit_config[bkt]; 94 + total_credits += cfg->sae.credit_config[bkt]; 95 + total_credits += cfg->xgmac[0].credit_config[bkt]; 96 + total_credits += cfg->xgmac[1].credit_config[bkt]; 97 + if (total_credits > cfg->bucket_size[bkt]) 98 + pr_err("ERROR: Bucket %d: credits (%d) > size (%d)\n", 99 + bkt, total_credits, cfg->bucket_size[bkt]); 100 + } 101 + pr_info("Credit distribution complete.\n"); 102 + } 103 + 104 + /** 105 + * Configure bucket size and credits for a device. 'size' is the size of 106 + * the buckets for the device. This size is distributed among all the CPUs 107 + * so that all of them can send messages to the device. 108 + * 109 + * The device is also given 'cpu_credits' to send messages to the CPUs 110 + * 111 + * @dev_info: FMN information structure for each devices 112 + * @start_stn_id: Starting station id of dev_info 113 + * @end_stn_id: End station id of dev_info 114 + * @num_buckets: Total number of buckets for den_info 115 + * @cpu_credits: Allowed credits to cpu for each devices pointing by dev_info 116 + * @size: Size of the each buckets in the device station 117 + */ 118 + static void setup_fmn_cc(struct xlr_fmn_info *dev_info, int start_stn_id, 119 + int end_stn_id, int num_buckets, int cpu_credits, int size) 120 + { 121 + int i, j, num_core, n, credits_per_cpu; 122 + struct xlr_fmn_info *cpu = xlr_board_fmn_config.cpu; 123 + 124 + num_core = hweight32(nlm_current_node()->coremask); 125 + dev_info->num_buckets = num_buckets; 126 + dev_info->start_stn_id = start_stn_id; 127 + dev_info->end_stn_id = end_stn_id; 128 + 129 + n = num_core; 130 + if (num_core == 3) 131 + n = 4; 132 + 133 + for (i = start_stn_id; i <= end_stn_id; i++) { 134 + xlr_board_fmn_config.bucket_size[i] = size; 135 + 136 + /* Dividing device credits equally to cpus */ 137 + credits_per_cpu = size / n; 138 + for (j = 0; j < num_core; j++) 139 + cpu[j].credit_config[i] = credits_per_cpu; 140 + 141 + /* credits left to distribute */ 142 + credits_per_cpu = size - (credits_per_cpu * num_core); 143 + 144 + /* distribute the remaining credits (if any), among cores */ 145 + for (j = 0; (j < num_core) && (credits_per_cpu >= 4); j++) { 146 + cpu[j].credit_config[i] += 4; 147 + credits_per_cpu -= 4; 148 + } 149 + } 150 + 151 + /* Distributing cpu per bucket credits to devices */ 152 + for (i = 0; i < num_core; i++) { 153 + for (j = 0; j < FMN_CORE_NBUCKETS; j++) 154 + dev_info->credit_config[(i * 8) + j] = cpu_credits; 155 + } 156 + } 157 + 158 + /* 159 + * Each core has 256 slots and 8 buckets, 160 + * Configure the 8 buckets each with 32 slots 161 + */ 162 + static void setup_cpu_fmninfo(struct xlr_fmn_info *cpu, int num_core) 163 + { 164 + int i, j; 165 + 166 + for (i = 0; i < num_core; i++) { 167 + cpu[i].start_stn_id = (8 * i); 168 + cpu[i].end_stn_id = (8 * i + 8); 169 + 170 + for (j = cpu[i].start_stn_id; j < cpu[i].end_stn_id; j++) 171 + xlr_board_fmn_config.bucket_size[j] = 32; 172 + } 173 + } 174 + 175 + /** 176 + * Setup the FMN details for each devices according to the device available 177 + * in each variant of XLR/XLS processor 178 + */ 179 + void xlr_board_info_setup(void) 180 + { 181 + struct xlr_fmn_info *cpu = xlr_board_fmn_config.cpu; 182 + struct xlr_fmn_info *gmac = xlr_board_fmn_config.gmac; 183 + struct xlr_fmn_info *xgmac = xlr_board_fmn_config.xgmac; 184 + struct xlr_fmn_info *dma = &xlr_board_fmn_config.dma; 185 + struct xlr_fmn_info *cmp = &xlr_board_fmn_config.cmp; 186 + struct xlr_fmn_info *sae = &xlr_board_fmn_config.sae; 187 + int processor_id, num_core; 188 + 189 + num_core = hweight32(nlm_current_node()->coremask); 190 + processor_id = read_c0_prid() & 0xff00; 191 + 192 + setup_cpu_fmninfo(cpu, num_core); 193 + switch (processor_id) { 194 + case PRID_IMP_NETLOGIC_XLS104: 195 + case PRID_IMP_NETLOGIC_XLS108: 196 + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, 197 + FMN_STNID_GMAC0_TX3, 8, 16, 32); 198 + setup_fmn_cc(dma, FMN_STNID_DMA_0, 199 + FMN_STNID_DMA_3, 4, 8, 64); 200 + setup_fmn_cc(sae, FMN_STNID_SEC0, 201 + FMN_STNID_SEC1, 2, 8, 128); 202 + break; 203 + 204 + case PRID_IMP_NETLOGIC_XLS204: 205 + case PRID_IMP_NETLOGIC_XLS208: 206 + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, 207 + FMN_STNID_GMAC0_TX3, 8, 16, 32); 208 + setup_fmn_cc(dma, FMN_STNID_DMA_0, 209 + FMN_STNID_DMA_3, 4, 8, 64); 210 + setup_fmn_cc(sae, FMN_STNID_SEC0, 211 + FMN_STNID_SEC1, 2, 8, 128); 212 + break; 213 + 214 + case PRID_IMP_NETLOGIC_XLS404: 215 + case PRID_IMP_NETLOGIC_XLS408: 216 + case PRID_IMP_NETLOGIC_XLS404B: 217 + case PRID_IMP_NETLOGIC_XLS408B: 218 + case PRID_IMP_NETLOGIC_XLS416B: 219 + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, 220 + FMN_STNID_GMAC0_TX3, 8, 8, 32); 221 + setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0, 222 + FMN_STNID_GMAC1_TX3, 8, 8, 32); 223 + setup_fmn_cc(dma, FMN_STNID_DMA_0, 224 + FMN_STNID_DMA_3, 4, 4, 64); 225 + setup_fmn_cc(cmp, FMN_STNID_CMP_0, 226 + FMN_STNID_CMP_3, 4, 4, 64); 227 + setup_fmn_cc(sae, FMN_STNID_SEC0, 228 + FMN_STNID_SEC1, 2, 8, 128); 229 + break; 230 + 231 + case PRID_IMP_NETLOGIC_XLS412B: 232 + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, 233 + FMN_STNID_GMAC0_TX3, 8, 8, 32); 234 + setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0, 235 + FMN_STNID_GMAC1_TX3, 8, 8, 32); 236 + setup_fmn_cc(dma, FMN_STNID_DMA_0, 237 + FMN_STNID_DMA_3, 4, 4, 64); 238 + setup_fmn_cc(cmp, FMN_STNID_CMP_0, 239 + FMN_STNID_CMP_3, 4, 4, 64); 240 + setup_fmn_cc(sae, FMN_STNID_SEC0, 241 + FMN_STNID_SEC1, 2, 8, 128); 242 + break; 243 + 244 + case PRID_IMP_NETLOGIC_XLR308: 245 + case PRID_IMP_NETLOGIC_XLR308C: 246 + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, 247 + FMN_STNID_GMAC0_TX3, 8, 16, 32); 248 + setup_fmn_cc(dma, FMN_STNID_DMA_0, 249 + FMN_STNID_DMA_3, 4, 8, 64); 250 + setup_fmn_cc(sae, FMN_STNID_SEC0, 251 + FMN_STNID_SEC1, 2, 4, 128); 252 + break; 253 + 254 + case PRID_IMP_NETLOGIC_XLR532: 255 + case PRID_IMP_NETLOGIC_XLR532C: 256 + case PRID_IMP_NETLOGIC_XLR516C: 257 + case PRID_IMP_NETLOGIC_XLR508C: 258 + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, 259 + FMN_STNID_GMAC0_TX3, 8, 16, 32); 260 + setup_fmn_cc(dma, FMN_STNID_DMA_0, 261 + FMN_STNID_DMA_3, 4, 8, 64); 262 + setup_fmn_cc(sae, FMN_STNID_SEC0, 263 + FMN_STNID_SEC1, 2, 4, 128); 264 + break; 265 + 266 + case PRID_IMP_NETLOGIC_XLR732: 267 + case PRID_IMP_NETLOGIC_XLR716: 268 + setup_fmn_cc(&xgmac[0], FMN_STNID_XMAC0_00_TX, 269 + FMN_STNID_XMAC0_15_TX, 8, 0, 32); 270 + setup_fmn_cc(&xgmac[1], FMN_STNID_XMAC1_00_TX, 271 + FMN_STNID_XMAC1_15_TX, 8, 0, 32); 272 + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, 273 + FMN_STNID_GMAC0_TX3, 8, 24, 32); 274 + setup_fmn_cc(dma, FMN_STNID_DMA_0, 275 + FMN_STNID_DMA_3, 4, 4, 64); 276 + setup_fmn_cc(sae, FMN_STNID_SEC0, 277 + FMN_STNID_SEC1, 2, 4, 128); 278 + break; 279 + default: 280 + pr_err("Unknown CPU with processor ID [%d]\n", processor_id); 281 + pr_err("Error: Cannot initialize FMN credits.\n"); 282 + } 283 + 284 + check_credit_distribution(); 285 + 286 + #if 0 /* debug */ 287 + print_credit_config(&cpu[0]); 288 + print_credit_config(&gmac[0]); 289 + #endif 290 + }
+204
arch/mips/netlogic/xlr/fmn.c
··· 1 + /* 2 + * Copyright (c) 2003-2012 Broadcom Corporation 3 + * All Rights Reserved 4 + * 5 + * This software is available to you under a choice of one of two 6 + * licenses. You may choose to be licensed under the terms of the GNU 7 + * General Public License (GPL) Version 2, available from the file 8 + * COPYING in the main directory of this source tree, or the Broadcom 9 + * license below: 10 + * 11 + * Redistribution and use in source and binary forms, with or without 12 + * modification, are permitted provided that the following conditions 13 + * are met: 14 + * 15 + * 1. Redistributions of source code must retain the above copyright 16 + * notice, this list of conditions and the following disclaimer. 17 + * 2. Redistributions in binary form must reproduce the above copyright 18 + * notice, this list of conditions and the following disclaimer in 19 + * the documentation and/or other materials provided with the 20 + * distribution. 21 + * 22 + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR 23 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 + * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE 26 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 29 + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 32 + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 + */ 34 + 35 + #include <linux/kernel.h> 36 + #include <linux/irqreturn.h> 37 + #include <linux/irq.h> 38 + #include <linux/interrupt.h> 39 + 40 + #include <asm/mipsregs.h> 41 + #include <asm/netlogic/interrupt.h> 42 + #include <asm/netlogic/xlr/fmn.h> 43 + #include <asm/netlogic/common.h> 44 + 45 + #define COP2_CC_INIT_CPU_DEST(dest, conf) \ 46 + do { \ 47 + nlm_write_c2_cc##dest(0, conf[(dest * 8) + 0]); \ 48 + nlm_write_c2_cc##dest(1, conf[(dest * 8) + 1]); \ 49 + nlm_write_c2_cc##dest(2, conf[(dest * 8) + 2]); \ 50 + nlm_write_c2_cc##dest(3, conf[(dest * 8) + 3]); \ 51 + nlm_write_c2_cc##dest(4, conf[(dest * 8) + 4]); \ 52 + nlm_write_c2_cc##dest(5, conf[(dest * 8) + 5]); \ 53 + nlm_write_c2_cc##dest(6, conf[(dest * 8) + 6]); \ 54 + nlm_write_c2_cc##dest(7, conf[(dest * 8) + 7]); \ 55 + } while (0) 56 + 57 + struct fmn_message_handler { 58 + void (*action)(int, int, int, int, struct nlm_fmn_msg *, void *); 59 + void *arg; 60 + } msg_handlers[128]; 61 + 62 + /* 63 + * FMN interrupt handler. We configure the FMN so that any messages in 64 + * any of the CPU buckets will trigger an interrupt on the CPU. 65 + * The message can be from any device on the FMN (like NAE/SAE/DMA). 66 + * The source station id is used to figure out which of the registered 67 + * handlers have to be called. 68 + */ 69 + static irqreturn_t fmn_message_handler(int irq, void *data) 70 + { 71 + struct fmn_message_handler *hndlr; 72 + int bucket, rv; 73 + int size = 0, code = 0, src_stnid = 0; 74 + struct nlm_fmn_msg msg; 75 + uint32_t mflags, bkt_status; 76 + 77 + mflags = nlm_cop2_enable(); 78 + /* Disable message ring interrupt */ 79 + nlm_fmn_setup_intr(irq, 0); 80 + while (1) { 81 + /* 8 bkts per core, [24:31] each bit represents one bucket 82 + * Bit is Zero if bucket is not empty */ 83 + bkt_status = (nlm_read_c2_status() >> 24) & 0xff; 84 + if (bkt_status == 0xff) 85 + break; 86 + for (bucket = 0; bucket < 8; bucket++) { 87 + /* Continue on empty bucket */ 88 + if (bkt_status & (1 << bucket)) 89 + continue; 90 + rv = nlm_fmn_receive(bucket, &size, &code, &src_stnid, 91 + &msg); 92 + if (rv != 0) 93 + continue; 94 + 95 + hndlr = &msg_handlers[src_stnid]; 96 + if (hndlr->action == NULL) 97 + pr_warn("No msgring handler for stnid %d\n", 98 + src_stnid); 99 + else { 100 + nlm_cop2_restore(mflags); 101 + hndlr->action(bucket, src_stnid, size, code, 102 + &msg, hndlr->arg); 103 + mflags = nlm_cop2_enable(); 104 + } 105 + } 106 + }; 107 + /* Enable message ring intr, to any thread in core */ 108 + nlm_fmn_setup_intr(irq, (1 << nlm_threads_per_core) - 1); 109 + nlm_cop2_restore(mflags); 110 + return IRQ_HANDLED; 111 + } 112 + 113 + struct irqaction fmn_irqaction = { 114 + .handler = fmn_message_handler, 115 + .flags = IRQF_PERCPU, 116 + .name = "fmn", 117 + }; 118 + 119 + void xlr_percpu_fmn_init(void) 120 + { 121 + struct xlr_fmn_info *cpu_fmn_info; 122 + int *bucket_sizes; 123 + uint32_t flags; 124 + int id; 125 + 126 + BUG_ON(nlm_thread_id() != 0); 127 + id = nlm_core_id(); 128 + 129 + bucket_sizes = xlr_board_fmn_config.bucket_size; 130 + cpu_fmn_info = &xlr_board_fmn_config.cpu[id]; 131 + flags = nlm_cop2_enable(); 132 + 133 + /* Setup bucket sizes for the core. */ 134 + nlm_write_c2_bucksize(0, bucket_sizes[id * 8 + 0]); 135 + nlm_write_c2_bucksize(1, bucket_sizes[id * 8 + 1]); 136 + nlm_write_c2_bucksize(2, bucket_sizes[id * 8 + 2]); 137 + nlm_write_c2_bucksize(3, bucket_sizes[id * 8 + 3]); 138 + nlm_write_c2_bucksize(4, bucket_sizes[id * 8 + 4]); 139 + nlm_write_c2_bucksize(5, bucket_sizes[id * 8 + 5]); 140 + nlm_write_c2_bucksize(6, bucket_sizes[id * 8 + 6]); 141 + nlm_write_c2_bucksize(7, bucket_sizes[id * 8 + 7]); 142 + 143 + /* 144 + * For sending FMN messages, we need credits on the destination 145 + * bucket. Program the credits this core has on the 128 possible 146 + * destination buckets. 147 + * We cannot use a loop here, because the the first argument has 148 + * to be a constant integer value. 149 + */ 150 + COP2_CC_INIT_CPU_DEST(0, cpu_fmn_info->credit_config); 151 + COP2_CC_INIT_CPU_DEST(1, cpu_fmn_info->credit_config); 152 + COP2_CC_INIT_CPU_DEST(2, cpu_fmn_info->credit_config); 153 + COP2_CC_INIT_CPU_DEST(3, cpu_fmn_info->credit_config); 154 + COP2_CC_INIT_CPU_DEST(4, cpu_fmn_info->credit_config); 155 + COP2_CC_INIT_CPU_DEST(5, cpu_fmn_info->credit_config); 156 + COP2_CC_INIT_CPU_DEST(6, cpu_fmn_info->credit_config); 157 + COP2_CC_INIT_CPU_DEST(7, cpu_fmn_info->credit_config); 158 + COP2_CC_INIT_CPU_DEST(8, cpu_fmn_info->credit_config); 159 + COP2_CC_INIT_CPU_DEST(9, cpu_fmn_info->credit_config); 160 + COP2_CC_INIT_CPU_DEST(10, cpu_fmn_info->credit_config); 161 + COP2_CC_INIT_CPU_DEST(11, cpu_fmn_info->credit_config); 162 + COP2_CC_INIT_CPU_DEST(12, cpu_fmn_info->credit_config); 163 + COP2_CC_INIT_CPU_DEST(13, cpu_fmn_info->credit_config); 164 + COP2_CC_INIT_CPU_DEST(14, cpu_fmn_info->credit_config); 165 + COP2_CC_INIT_CPU_DEST(15, cpu_fmn_info->credit_config); 166 + 167 + /* enable FMN interrupts on this CPU */ 168 + nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1); 169 + nlm_cop2_restore(flags); 170 + } 171 + 172 + 173 + /* 174 + * Register a FMN message handler with respect to the source station id 175 + * @stnid: source station id 176 + * @action: Handler function pointer 177 + */ 178 + int nlm_register_fmn_handler(int start_stnid, int end_stnid, 179 + void (*action)(int, int, int, int, struct nlm_fmn_msg *, void *), 180 + void *arg) 181 + { 182 + int sstnid; 183 + 184 + for (sstnid = start_stnid; sstnid <= end_stnid; sstnid++) { 185 + msg_handlers[sstnid].arg = arg; 186 + smp_wmb(); 187 + msg_handlers[sstnid].action = action; 188 + } 189 + pr_debug("Registered FMN msg handler for stnid %d-%d\n", 190 + start_stnid, end_stnid); 191 + return 0; 192 + } 193 + 194 + void nlm_setup_fmn_irq(void) 195 + { 196 + uint32_t flags; 197 + 198 + /* setup irq only once */ 199 + setup_irq(IRQ_FMN, &fmn_irqaction); 200 + 201 + flags = nlm_cop2_enable(); 202 + nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1); 203 + nlm_cop2_restore(flags); 204 + }
+28 -9
arch/mips/netlogic/xlr/setup.c
··· 49 49 #include <asm/netlogic/xlr/iomap.h> 50 50 #include <asm/netlogic/xlr/pic.h> 51 51 #include <asm/netlogic/xlr/gpio.h> 52 + #include <asm/netlogic/xlr/fmn.h> 52 53 53 54 uint64_t nlm_io_base = DEFAULT_NETLOGIC_IO_BASE; 54 - uint64_t nlm_pic_base; 55 55 struct psb_info nlm_prom_info; 56 56 57 - unsigned long nlm_common_ebase = 0x0; 58 - 59 57 /* default to uniprocessor */ 60 - uint32_t nlm_coremask = 1, nlm_cpumask = 1; 61 - int nlm_threads_per_core = 1; 58 + unsigned int nlm_threads_per_core = 1; 59 + struct nlm_soc_info nlm_nodes[NLM_NR_NODES]; 60 + cpumask_t nlm_cpumask = CPU_MASK_CPU0; 62 61 63 62 static void __init nlm_early_serial_setup(void) 64 63 { ··· 110 111 void __init prom_free_prom_memory(void) 111 112 { 112 113 /* Nothing yet */ 114 + } 115 + 116 + void nlm_percpu_init(int hwcpuid) 117 + { 118 + if (hwcpuid % 4 == 0) 119 + xlr_percpu_fmn_init(); 113 120 } 114 121 115 122 static void __init build_arcs_cmdline(int *argv) ··· 181 176 } 182 177 } 183 178 179 + static void nlm_init_node(void) 180 + { 181 + struct nlm_soc_info *nodep; 182 + 183 + nodep = nlm_current_node(); 184 + nodep->picbase = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET); 185 + nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1)); 186 + spin_lock_init(&nodep->piclock); 187 + } 188 + 184 189 void __init prom_init(void) 185 190 { 186 - int *argv, *envp; /* passed as 32 bit ptrs */ 191 + int i, *argv, *envp; /* passed as 32 bit ptrs */ 187 192 struct psb_info *prom_infop; 188 193 189 194 /* truncate to 32 bit and sign extend all args */ ··· 202 187 prom_infop = (struct psb_info *)(long)(int)fw_arg3; 203 188 204 189 nlm_prom_info = *prom_infop; 205 - nlm_pic_base = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET); 190 + nlm_init_node(); 206 191 207 192 nlm_early_serial_setup(); 208 193 build_arcs_cmdline(argv); 209 - nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1)); 210 194 prom_add_memory(); 211 195 212 196 #ifdef CONFIG_SMP 213 - nlm_wakeup_secondary_cpus(nlm_prom_info.online_cpu_map); 197 + for (i = 0; i < 32; i++) 198 + if (nlm_prom_info.online_cpu_map & (1 << i)) 199 + cpumask_set_cpu(i, &nlm_cpumask); 200 + nlm_wakeup_secondary_cpus(); 214 201 register_smp_ops(&nlm_smp_ops); 215 202 #endif 203 + xlr_board_info_setup(); 204 + xlr_percpu_fmn_init(); 216 205 }
+20 -3
arch/mips/netlogic/xlr/wakeup.c
··· 33 33 */ 34 34 35 35 #include <linux/init.h> 36 + #include <linux/delay.h> 36 37 #include <linux/threads.h> 37 38 38 39 #include <asm/asm.h> ··· 51 50 52 51 int __cpuinit xlr_wakeup_secondary_cpus(void) 53 52 { 54 - unsigned int i, boot_cpu; 53 + struct nlm_soc_info *nodep; 54 + unsigned int i, j, boot_cpu; 55 55 56 56 /* 57 57 * In case of RMI boot, hit with NMI to get the cores 58 58 * from bootloader to linux code. 59 59 */ 60 + nodep = nlm_get_node(0); 60 61 boot_cpu = hard_smp_processor_id(); 61 62 nlm_set_nmi_handler(nlm_rmiboot_preboot); 62 63 for (i = 0; i < NR_CPUS; i++) { 63 - if (i == boot_cpu || (nlm_cpumask & (1u << i)) == 0) 64 + if (i == boot_cpu || !cpumask_test_cpu(i, &nlm_cpumask)) 64 65 continue; 65 - nlm_pic_send_ipi(nlm_pic_base, i, 1, 1); /* send NMI */ 66 + nlm_pic_send_ipi(nodep->picbase, i, 1, 1); /* send NMI */ 67 + } 68 + 69 + /* Fill up the coremask early */ 70 + nodep->coremask = 1; 71 + for (i = 1; i < NLM_CORES_PER_NODE; i++) { 72 + for (j = 1000000; j > 0; j--) { 73 + if (nlm_cpu_ready[i * NLM_THREADS_PER_CORE]) 74 + break; 75 + udelay(10); 76 + } 77 + if (j != 0) 78 + nodep->coremask |= (1u << i); 79 + else 80 + pr_err("Failed to wakeup core %d\n", i); 66 81 } 67 82 68 83 return 0;
+1
arch/mips/oprofile/Makefile
··· 12 12 oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o 13 13 oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o 14 14 oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o 15 + oprofile-$(CONFIG_CPU_XLR) += op_model_mipsxx.o 15 16 oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o
+1
arch/mips/oprofile/common.c
··· 90 90 case CPU_R10000: 91 91 case CPU_R12000: 92 92 case CPU_R14000: 93 + case CPU_XLR: 93 94 lmodel = &op_model_mipsxx_ops; 94 95 break; 95 96
+29
arch/mips/oprofile/op_model_mipsxx.c
··· 31 31 32 32 #define M_COUNTER_OVERFLOW (1UL << 31) 33 33 34 + /* Netlogic XLR specific, count events in all threads in a core */ 35 + #define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13) 36 + 34 37 static int (*save_perf_irq)(void); 38 + 39 + /* 40 + * XLR has only one set of counters per core. Designate the 41 + * first hardware thread in the core for setup and init. 42 + * Skip CPUs with non-zero hardware thread id (4 hwt per core) 43 + */ 44 + #ifdef CONFIG_CPU_XLR 45 + #define oprofile_skip_cpu(c) ((cpu_logical_map(c) & 0x3) != 0) 46 + #else 47 + #define oprofile_skip_cpu(c) 0 48 + #endif 35 49 36 50 #ifdef CONFIG_MIPS_MT_SMP 37 51 static int cpu_has_mipsmt_pertccounters; ··· 166 152 reg.control[i] |= M_PERFCTL_USER; 167 153 if (ctr[i].exl) 168 154 reg.control[i] |= M_PERFCTL_EXL; 155 + if (current_cpu_type() == CPU_XLR) 156 + reg.control[i] |= M_PERFCTL_COUNT_ALL_THREADS; 169 157 reg.counter[i] = 0x80000000 - ctr[i].count; 170 158 } 171 159 } ··· 177 161 static void mipsxx_cpu_setup(void *args) 178 162 { 179 163 unsigned int counters = op_model_mipsxx_ops.num_counters; 164 + 165 + if (oprofile_skip_cpu(smp_processor_id())) 166 + return; 180 167 181 168 switch (counters) { 182 169 case 4: ··· 202 183 { 203 184 unsigned int counters = op_model_mipsxx_ops.num_counters; 204 185 186 + if (oprofile_skip_cpu(smp_processor_id())) 187 + return; 188 + 205 189 switch (counters) { 206 190 case 4: 207 191 w_c0_perfctrl3(WHAT | reg.control[3]); ··· 221 199 static void mipsxx_cpu_stop(void *args) 222 200 { 223 201 unsigned int counters = op_model_mipsxx_ops.num_counters; 202 + 203 + if (oprofile_skip_cpu(smp_processor_id())) 204 + return; 224 205 225 206 switch (counters) { 226 207 case 4: ··· 395 370 396 371 case CPU_LOONGSON1: 397 372 op_model_mipsxx_ops.cpu_type = "mips/loongson1"; 373 + break; 374 + 375 + case CPU_XLR: 376 + op_model_mipsxx_ops.cpu_type = "mips/xlr"; 398 377 break; 399 378 400 379 default:
+16 -18
arch/mips/pci/pci-bcm63xx.c
··· 11 11 #include <linux/kernel.h> 12 12 #include <linux/init.h> 13 13 #include <linux/delay.h> 14 + #include <linux/clk.h> 14 15 #include <asm/bootinfo.h> 16 + 17 + #include <bcm63xx_reset.h> 15 18 16 19 #include "pci-bcm63xx.h" 17 20 ··· 122 119 { 123 120 u32 val; 124 121 125 - /* enable clock */ 126 - val = bcm_perf_readl(PERF_CKCTL_REG); 127 - val |= CKCTL_6328_PCIE_EN; 128 - bcm_perf_writel(val, PERF_CKCTL_REG); 129 - 130 122 /* enable SERDES */ 131 123 val = bcm_misc_readl(MISC_SERDES_CTRL_REG); 132 124 val |= SERDES_PCIE_EN | SERDES_PCIE_EXD_EN; 133 125 bcm_misc_writel(val, MISC_SERDES_CTRL_REG); 134 126 135 127 /* reset the PCIe core */ 136 - val = bcm_perf_readl(PERF_SOFTRESET_6328_REG); 137 - 138 - val &= ~SOFTRESET_6328_PCIE_MASK; 139 - val &= ~SOFTRESET_6328_PCIE_CORE_MASK; 140 - val &= ~SOFTRESET_6328_PCIE_HARD_MASK; 141 - val &= ~SOFTRESET_6328_PCIE_EXT_MASK; 142 - bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); 128 + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 1); 129 + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 1); 143 130 mdelay(10); 144 131 145 - val |= SOFTRESET_6328_PCIE_MASK; 146 - val |= SOFTRESET_6328_PCIE_CORE_MASK; 147 - val |= SOFTRESET_6328_PCIE_HARD_MASK; 148 - bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); 132 + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 0); 149 133 mdelay(10); 150 134 151 - val |= SOFTRESET_6328_PCIE_EXT_MASK; 152 - bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); 135 + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 0); 153 136 mdelay(200); 154 137 } 138 + 139 + static struct clk *pcie_clk; 155 140 156 141 static int __init bcm63xx_register_pcie(void) 157 142 { 158 143 u32 val; 144 + 145 + /* enable clock */ 146 + pcie_clk = clk_get(NULL, "pcie"); 147 + if (IS_ERR_OR_NULL(pcie_clk)) 148 + return -ENODEV; 149 + 150 + clk_prepare_enable(pcie_clk); 159 151 160 152 bcm63xx_reset_pcie(); 161 153
+34 -35
arch/mips/pci/pci-xlr.c
··· 47 47 48 48 #include <asm/netlogic/interrupt.h> 49 49 #include <asm/netlogic/haldefs.h> 50 + #include <asm/netlogic/common.h> 50 51 51 52 #include <asm/netlogic/xlr/msidef.h> 52 53 #include <asm/netlogic/xlr/iomap.h> ··· 175 174 return p ? bus->self : NULL; 176 175 } 177 176 178 - static int get_irq_vector(const struct pci_dev *dev) 177 + static int nlm_pci_link_to_irq(int link) 179 178 { 180 - struct pci_dev *lnk; 181 - 182 - if (!nlm_chip_is_xls()) 183 - return PIC_PCIX_IRQ; /* for XLR just one IRQ */ 184 - 185 - /* 186 - * For XLS PCIe, there is an IRQ per Link, find out which 187 - * link the device is on to assign interrupts 188 - */ 189 - lnk = xls_get_pcie_link(dev); 190 - if (lnk == NULL) 191 - return 0; 192 - 193 - switch (PCI_SLOT(lnk->devfn)) { 179 + switch (link) { 194 180 case 0: 195 181 return PIC_PCIE_LINK0_IRQ; 196 182 case 1: ··· 193 205 else 194 206 return PIC_PCIE_LINK3_IRQ; 195 207 } 196 - WARN(1, "Unexpected devfn %d\n", lnk->devfn); 208 + WARN(1, "Unexpected link %d\n", link); 197 209 return 0; 210 + } 211 + 212 + static int get_irq_vector(const struct pci_dev *dev) 213 + { 214 + struct pci_dev *lnk; 215 + int link; 216 + 217 + if (!nlm_chip_is_xls()) 218 + return PIC_PCIX_IRQ; /* for XLR just one IRQ */ 219 + 220 + lnk = xls_get_pcie_link(dev); 221 + if (lnk == NULL) 222 + return 0; 223 + 224 + link = PCI_SLOT(lnk->devfn); 225 + return nlm_pci_link_to_irq(link); 198 226 } 199 227 200 228 #ifdef CONFIG_PCI_MSI ··· 336 332 337 333 static int __init pcibios_init(void) 338 334 { 335 + void (*extra_ack)(struct irq_data *); 336 + int link, irq; 337 + 339 338 /* PSB assigns PCI resources */ 340 339 pci_set_flags(PCI_PROBE_ONLY); 341 340 pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20); ··· 357 350 * For PCI interrupts, we need to ack the PCI controller too, overload 358 351 * irq handler data to do this 359 352 */ 360 - if (nlm_chip_is_xls()) { 361 - if (nlm_chip_is_xls_b()) { 362 - irq_set_handler_data(PIC_PCIE_LINK0_IRQ, 363 - xls_pcie_ack_b); 364 - irq_set_handler_data(PIC_PCIE_LINK1_IRQ, 365 - xls_pcie_ack_b); 366 - irq_set_handler_data(PIC_PCIE_XLSB0_LINK2_IRQ, 367 - xls_pcie_ack_b); 368 - irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, 369 - xls_pcie_ack_b); 370 - } else { 371 - irq_set_handler_data(PIC_PCIE_LINK0_IRQ, xls_pcie_ack); 372 - irq_set_handler_data(PIC_PCIE_LINK1_IRQ, xls_pcie_ack); 373 - irq_set_handler_data(PIC_PCIE_LINK2_IRQ, xls_pcie_ack); 374 - irq_set_handler_data(PIC_PCIE_LINK3_IRQ, xls_pcie_ack); 375 - } 376 - } else { 353 + if (!nlm_chip_is_xls()) { 377 354 /* XLR PCI controller ACK */ 378 - irq_set_handler_data(PIC_PCIX_IRQ, xlr_pci_ack); 355 + nlm_set_pic_extra_ack(0, PIC_PCIX_IRQ, xlr_pci_ack); 356 + } else { 357 + if (nlm_chip_is_xls_b()) 358 + extra_ack = xls_pcie_ack_b; 359 + else 360 + extra_ack = xls_pcie_ack; 361 + for (link = 0; link < 4; link++) { 362 + irq = nlm_pci_link_to_irq(link); 363 + nlm_set_pic_extra_ack(0, irq, extra_ack); 364 + } 379 365 } 380 - 381 366 return 0; 382 367 } 383 368
+9
drivers/bcma/Kconfig
··· 65 65 66 66 If unsure, say N 67 67 68 + config BCMA_DRIVER_GPIO 69 + bool "BCMA GPIO driver" 70 + depends on BCMA 71 + select GPIOLIB 72 + help 73 + Driver to provide access to the GPIO pins of the bcma bus. 74 + 75 + If unsure, say N 76 + 68 77 config BCMA_DEBUG 69 78 bool "BCMA debugging" 70 79 depends on BCMA
+1
drivers/bcma/Makefile
··· 6 6 bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o 7 7 bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o 8 8 bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o 9 + bcma-$(CONFIG_BCMA_DRIVER_GPIO) += driver_gpio.o 9 10 bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o 10 11 bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o 11 12 obj-$(CONFIG_BCMA) += bcma.o
+10
drivers/bcma/bcma_private.h
··· 89 89 void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc); 90 90 #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */ 91 91 92 + #ifdef CONFIG_BCMA_DRIVER_GPIO 93 + /* driver_gpio.c */ 94 + int bcma_gpio_init(struct bcma_drv_cc *cc); 95 + #else 96 + static inline int bcma_gpio_init(struct bcma_drv_cc *cc) 97 + { 98 + return -ENOTSUPP; 99 + } 100 + #endif /* CONFIG_BCMA_DRIVER_GPIO */ 101 + 92 102 #endif
+76 -5
drivers/bcma/driver_chipcommon.c
··· 30 30 if (cc->setup_done) 31 31 return; 32 32 33 + spin_lock_init(&cc->gpio_lock); 34 + 33 35 if (cc->core->id.rev >= 11) 34 36 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT); 35 37 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP); ··· 86 84 87 85 u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value) 88 86 { 89 - return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value); 87 + unsigned long flags; 88 + u32 res; 89 + 90 + spin_lock_irqsave(&cc->gpio_lock, flags); 91 + res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value); 92 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 93 + 94 + return res; 90 95 } 91 96 92 97 u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value) 93 98 { 94 - return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value); 99 + unsigned long flags; 100 + u32 res; 101 + 102 + spin_lock_irqsave(&cc->gpio_lock, flags); 103 + res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value); 104 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 105 + 106 + return res; 95 107 } 96 108 109 + /* 110 + * If the bit is set to 0, chipcommon controlls this GPIO, 111 + * if the bit is set to 1, it is used by some part of the chip and not our code. 112 + */ 97 113 u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value) 98 114 { 99 - return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value); 115 + unsigned long flags; 116 + u32 res; 117 + 118 + spin_lock_irqsave(&cc->gpio_lock, flags); 119 + res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value); 120 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 121 + 122 + return res; 100 123 } 101 124 EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control); 102 125 103 126 u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value) 104 127 { 105 - return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value); 128 + unsigned long flags; 129 + u32 res; 130 + 131 + spin_lock_irqsave(&cc->gpio_lock, flags); 132 + res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value); 133 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 134 + 135 + return res; 106 136 } 107 137 108 138 u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value) 109 139 { 110 - return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value); 140 + unsigned long flags; 141 + u32 res; 142 + 143 + spin_lock_irqsave(&cc->gpio_lock, flags); 144 + res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value); 145 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 146 + 147 + return res; 148 + } 149 + 150 + u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value) 151 + { 152 + unsigned long flags; 153 + u32 res; 154 + 155 + if (cc->core->id.rev < 20) 156 + return 0; 157 + 158 + spin_lock_irqsave(&cc->gpio_lock, flags); 159 + res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLUP, mask, value); 160 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 161 + 162 + return res; 163 + } 164 + 165 + u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value) 166 + { 167 + unsigned long flags; 168 + u32 res; 169 + 170 + if (cc->core->id.rev < 20) 171 + return 0; 172 + 173 + spin_lock_irqsave(&cc->gpio_lock, flags); 174 + res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLDOWN, mask, value); 175 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 176 + 177 + return res; 111 178 } 112 179 113 180 #ifdef CONFIG_BCMA_DRIVER_MIPS
+98
drivers/bcma/driver_gpio.c
··· 1 + /* 2 + * Broadcom specific AMBA 3 + * GPIO driver 4 + * 5 + * Copyright 2011, Broadcom Corporation 6 + * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de> 7 + * 8 + * Licensed under the GNU/GPL. See COPYING for details. 9 + */ 10 + 11 + #include <linux/gpio.h> 12 + #include <linux/export.h> 13 + #include <linux/bcma/bcma.h> 14 + 15 + #include "bcma_private.h" 16 + 17 + static inline struct bcma_drv_cc *bcma_gpio_get_cc(struct gpio_chip *chip) 18 + { 19 + return container_of(chip, struct bcma_drv_cc, gpio); 20 + } 21 + 22 + static int bcma_gpio_get_value(struct gpio_chip *chip, unsigned gpio) 23 + { 24 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 25 + 26 + return !!bcma_chipco_gpio_in(cc, 1 << gpio); 27 + } 28 + 29 + static void bcma_gpio_set_value(struct gpio_chip *chip, unsigned gpio, 30 + int value) 31 + { 32 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 33 + 34 + bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0); 35 + } 36 + 37 + static int bcma_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) 38 + { 39 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 40 + 41 + bcma_chipco_gpio_outen(cc, 1 << gpio, 0); 42 + return 0; 43 + } 44 + 45 + static int bcma_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, 46 + int value) 47 + { 48 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 49 + 50 + bcma_chipco_gpio_outen(cc, 1 << gpio, 1 << gpio); 51 + bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0); 52 + return 0; 53 + } 54 + 55 + static int bcma_gpio_request(struct gpio_chip *chip, unsigned gpio) 56 + { 57 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 58 + 59 + bcma_chipco_gpio_control(cc, 1 << gpio, 0); 60 + /* clear pulldown */ 61 + bcma_chipco_gpio_pulldown(cc, 1 << gpio, 0); 62 + /* Set pullup */ 63 + bcma_chipco_gpio_pullup(cc, 1 << gpio, 1 << gpio); 64 + 65 + return 0; 66 + } 67 + 68 + static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio) 69 + { 70 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 71 + 72 + /* clear pullup */ 73 + bcma_chipco_gpio_pullup(cc, 1 << gpio, 0); 74 + } 75 + 76 + int bcma_gpio_init(struct bcma_drv_cc *cc) 77 + { 78 + struct gpio_chip *chip = &cc->gpio; 79 + 80 + chip->label = "bcma_gpio"; 81 + chip->owner = THIS_MODULE; 82 + chip->request = bcma_gpio_request; 83 + chip->free = bcma_gpio_free; 84 + chip->get = bcma_gpio_get_value; 85 + chip->set = bcma_gpio_set_value; 86 + chip->direction_input = bcma_gpio_direction_input; 87 + chip->direction_output = bcma_gpio_direction_output; 88 + chip->ngpio = 16; 89 + /* There is just one SoC in one device and its GPIO addresses should be 90 + * deterministic to address them more easily. The other buses could get 91 + * a random base number. */ 92 + if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) 93 + chip->base = 0; 94 + else 95 + chip->base = -1; 96 + 97 + return gpiochip_add(chip); 98 + }
+5
drivers/bcma/main.c
··· 152 152 bcma_err(bus, "Error registering NAND flash\n"); 153 153 } 154 154 #endif 155 + err = bcma_gpio_init(&bus->drv_cc); 156 + if (err == -ENOTSUPP) 157 + bcma_debug(bus, "GPIO driver not activated\n"); 158 + else if (err) 159 + bcma_err(bus, "Error registering GPIO driver: %i\n", err); 155 160 156 161 return 0; 157 162 }
+9
drivers/ssb/Kconfig
··· 160 160 161 161 If unsure, say N 162 162 163 + config SSB_DRIVER_GPIO 164 + bool "SSB GPIO driver" 165 + depends on SSB 166 + select GPIOLIB 167 + help 168 + Driver to provide access to the GPIO pins on the bus. 169 + 170 + If unsure, say N 171 + 163 172 endmenu
+1
drivers/ssb/Makefile
··· 15 15 ssb-$(CONFIG_SSB_DRIVER_EXTIF) += driver_extif.o 16 16 ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o 17 17 ssb-$(CONFIG_SSB_DRIVER_GIGE) += driver_gige.o 18 + ssb-$(CONFIG_SSB_DRIVER_GPIO) += driver_gpio.o 18 19 19 20 # b43 pci-ssb-bridge driver 20 21 # Not strictly a part of SSB, but kept here for convenience
+73 -5
drivers/ssb/driver_chipcommon.c
··· 284 284 { 285 285 if (!cc->dev) 286 286 return; /* We don't have a ChipCommon */ 287 + 288 + spin_lock_init(&cc->gpio_lock); 289 + 287 290 if (cc->dev->id.revision >= 11) 288 291 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); 289 292 ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status); ··· 421 418 422 419 u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value) 423 420 { 424 - return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value); 421 + unsigned long flags; 422 + u32 res = 0; 423 + 424 + spin_lock_irqsave(&cc->gpio_lock, flags); 425 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value); 426 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 427 + 428 + return res; 425 429 } 426 430 427 431 u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value) 428 432 { 429 - return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value); 433 + unsigned long flags; 434 + u32 res = 0; 435 + 436 + spin_lock_irqsave(&cc->gpio_lock, flags); 437 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value); 438 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 439 + 440 + return res; 430 441 } 431 442 432 443 u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value) 433 444 { 434 - return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value); 445 + unsigned long flags; 446 + u32 res = 0; 447 + 448 + spin_lock_irqsave(&cc->gpio_lock, flags); 449 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value); 450 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 451 + 452 + return res; 435 453 } 436 454 EXPORT_SYMBOL(ssb_chipco_gpio_control); 437 455 438 456 u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value) 439 457 { 440 - return chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value); 458 + unsigned long flags; 459 + u32 res = 0; 460 + 461 + spin_lock_irqsave(&cc->gpio_lock, flags); 462 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value); 463 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 464 + 465 + return res; 441 466 } 442 467 443 468 u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value) 444 469 { 445 - return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value); 470 + unsigned long flags; 471 + u32 res = 0; 472 + 473 + spin_lock_irqsave(&cc->gpio_lock, flags); 474 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value); 475 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 476 + 477 + return res; 478 + } 479 + 480 + u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value) 481 + { 482 + unsigned long flags; 483 + u32 res = 0; 484 + 485 + if (cc->dev->id.revision < 20) 486 + return 0xffffffff; 487 + 488 + spin_lock_irqsave(&cc->gpio_lock, flags); 489 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLUP, mask, value); 490 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 491 + 492 + return res; 493 + } 494 + 495 + u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value) 496 + { 497 + unsigned long flags; 498 + u32 res = 0; 499 + 500 + if (cc->dev->id.revision < 20) 501 + return 0xffffffff; 502 + 503 + spin_lock_irqsave(&cc->gpio_lock, flags); 504 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLDOWN, mask, value); 505 + spin_unlock_irqrestore(&cc->gpio_lock, flags); 506 + 507 + return res; 446 508 } 447 509 448 510 #ifdef CONFIG_SSB_SERIAL
+39 -4
drivers/ssb/driver_extif.c
··· 118 118 extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks); 119 119 } 120 120 121 + void ssb_extif_init(struct ssb_extif *extif) 122 + { 123 + if (!extif->dev) 124 + return; /* We don't have a Extif core */ 125 + spin_lock_init(&extif->gpio_lock); 126 + } 127 + 121 128 u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) 122 129 { 123 130 return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask; ··· 132 125 133 126 u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value) 134 127 { 135 - return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0), 128 + unsigned long flags; 129 + u32 res = 0; 130 + 131 + spin_lock_irqsave(&extif->gpio_lock, flags); 132 + res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0), 136 133 mask, value); 134 + spin_unlock_irqrestore(&extif->gpio_lock, flags); 135 + 136 + return res; 137 137 } 138 138 139 139 u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value) 140 140 { 141 - return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0), 141 + unsigned long flags; 142 + u32 res = 0; 143 + 144 + spin_lock_irqsave(&extif->gpio_lock, flags); 145 + res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0), 142 146 mask, value); 147 + spin_unlock_irqrestore(&extif->gpio_lock, flags); 148 + 149 + return res; 143 150 } 144 151 145 152 u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value) 146 153 { 147 - return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value); 154 + unsigned long flags; 155 + u32 res = 0; 156 + 157 + spin_lock_irqsave(&extif->gpio_lock, flags); 158 + res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value); 159 + spin_unlock_irqrestore(&extif->gpio_lock, flags); 160 + 161 + return res; 148 162 } 149 163 150 164 u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value) 151 165 { 152 - return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value); 166 + unsigned long flags; 167 + u32 res = 0; 168 + 169 + spin_lock_irqsave(&extif->gpio_lock, flags); 170 + res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value); 171 + spin_unlock_irqrestore(&extif->gpio_lock, flags); 172 + 173 + return res; 153 174 }
+176
drivers/ssb/driver_gpio.c
··· 1 + /* 2 + * Sonics Silicon Backplane 3 + * GPIO driver 4 + * 5 + * Copyright 2011, Broadcom Corporation 6 + * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de> 7 + * 8 + * Licensed under the GNU/GPL. See COPYING for details. 9 + */ 10 + 11 + #include <linux/gpio.h> 12 + #include <linux/export.h> 13 + #include <linux/ssb/ssb.h> 14 + 15 + #include "ssb_private.h" 16 + 17 + static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip) 18 + { 19 + return container_of(chip, struct ssb_bus, gpio); 20 + } 21 + 22 + static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio) 23 + { 24 + struct ssb_bus *bus = ssb_gpio_get_bus(chip); 25 + 26 + return !!ssb_chipco_gpio_in(&bus->chipco, 1 << gpio); 27 + } 28 + 29 + static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned gpio, 30 + int value) 31 + { 32 + struct ssb_bus *bus = ssb_gpio_get_bus(chip); 33 + 34 + ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0); 35 + } 36 + 37 + static int ssb_gpio_chipco_direction_input(struct gpio_chip *chip, 38 + unsigned gpio) 39 + { 40 + struct ssb_bus *bus = ssb_gpio_get_bus(chip); 41 + 42 + ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 0); 43 + return 0; 44 + } 45 + 46 + static int ssb_gpio_chipco_direction_output(struct gpio_chip *chip, 47 + unsigned gpio, int value) 48 + { 49 + struct ssb_bus *bus = ssb_gpio_get_bus(chip); 50 + 51 + ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 1 << gpio); 52 + ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0); 53 + return 0; 54 + } 55 + 56 + static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned gpio) 57 + { 58 + struct ssb_bus *bus = ssb_gpio_get_bus(chip); 59 + 60 + ssb_chipco_gpio_control(&bus->chipco, 1 << gpio, 0); 61 + /* clear pulldown */ 62 + ssb_chipco_gpio_pulldown(&bus->chipco, 1 << gpio, 0); 63 + /* Set pullup */ 64 + ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 1 << gpio); 65 + 66 + return 0; 67 + } 68 + 69 + static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio) 70 + { 71 + struct ssb_bus *bus = ssb_gpio_get_bus(chip); 72 + 73 + /* clear pullup */ 74 + ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0); 75 + } 76 + 77 + static int ssb_gpio_chipco_init(struct ssb_bus *bus) 78 + { 79 + struct gpio_chip *chip = &bus->gpio; 80 + 81 + chip->label = "ssb_chipco_gpio"; 82 + chip->owner = THIS_MODULE; 83 + chip->request = ssb_gpio_chipco_request; 84 + chip->free = ssb_gpio_chipco_free; 85 + chip->get = ssb_gpio_chipco_get_value; 86 + chip->set = ssb_gpio_chipco_set_value; 87 + chip->direction_input = ssb_gpio_chipco_direction_input; 88 + chip->direction_output = ssb_gpio_chipco_direction_output; 89 + chip->ngpio = 16; 90 + /* There is just one SoC in one device and its GPIO addresses should be 91 + * deterministic to address them more easily. The other buses could get 92 + * a random base number. */ 93 + if (bus->bustype == SSB_BUSTYPE_SSB) 94 + chip->base = 0; 95 + else 96 + chip->base = -1; 97 + 98 + return gpiochip_add(chip); 99 + } 100 + 101 + #ifdef CONFIG_SSB_DRIVER_EXTIF 102 + 103 + static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio) 104 + { 105 + struct ssb_bus *bus = ssb_gpio_get_bus(chip); 106 + 107 + return !!ssb_extif_gpio_in(&bus->extif, 1 << gpio); 108 + } 109 + 110 + static void ssb_gpio_extif_set_value(struct gpio_chip *chip, unsigned gpio, 111 + int value) 112 + { 113 + struct ssb_bus *bus = ssb_gpio_get_bus(chip); 114 + 115 + ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0); 116 + } 117 + 118 + static int ssb_gpio_extif_direction_input(struct gpio_chip *chip, 119 + unsigned gpio) 120 + { 121 + struct ssb_bus *bus = ssb_gpio_get_bus(chip); 122 + 123 + ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 0); 124 + return 0; 125 + } 126 + 127 + static int ssb_gpio_extif_direction_output(struct gpio_chip *chip, 128 + unsigned gpio, int value) 129 + { 130 + struct ssb_bus *bus = ssb_gpio_get_bus(chip); 131 + 132 + ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 1 << gpio); 133 + ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0); 134 + return 0; 135 + } 136 + 137 + static int ssb_gpio_extif_init(struct ssb_bus *bus) 138 + { 139 + struct gpio_chip *chip = &bus->gpio; 140 + 141 + chip->label = "ssb_extif_gpio"; 142 + chip->owner = THIS_MODULE; 143 + chip->get = ssb_gpio_extif_get_value; 144 + chip->set = ssb_gpio_extif_set_value; 145 + chip->direction_input = ssb_gpio_extif_direction_input; 146 + chip->direction_output = ssb_gpio_extif_direction_output; 147 + chip->ngpio = 5; 148 + /* There is just one SoC in one device and its GPIO addresses should be 149 + * deterministic to address them more easily. The other buses could get 150 + * a random base number. */ 151 + if (bus->bustype == SSB_BUSTYPE_SSB) 152 + chip->base = 0; 153 + else 154 + chip->base = -1; 155 + 156 + return gpiochip_add(chip); 157 + } 158 + 159 + #else 160 + static int ssb_gpio_extif_init(struct ssb_bus *bus) 161 + { 162 + return -ENOTSUPP; 163 + } 164 + #endif 165 + 166 + int ssb_gpio_init(struct ssb_bus *bus) 167 + { 168 + if (ssb_chipco_available(&bus->chipco)) 169 + return ssb_gpio_chipco_init(bus); 170 + else if (ssb_extif_available(&bus->extif)) 171 + return ssb_gpio_extif_init(bus); 172 + else 173 + SSB_WARN_ON(1); 174 + 175 + return -1; 176 + }
+7
drivers/ssb/main.c
··· 796 796 if (err) 797 797 goto err_pcmcia_exit; 798 798 ssb_chipcommon_init(&bus->chipco); 799 + ssb_extif_init(&bus->extif); 799 800 ssb_mipscore_init(&bus->mipscore); 801 + err = ssb_gpio_init(bus); 802 + if (err == -ENOTSUPP) 803 + ssb_dprintk(KERN_DEBUG PFX "GPIO driver not activated\n"); 804 + else if (err) 805 + ssb_dprintk(KERN_ERR PFX 806 + "Error registering GPIO driver: %i\n", err); 800 807 err = ssb_fetch_invariants(bus, get_invariants); 801 808 if (err) { 802 809 ssb_bus_may_powerdown(bus);
+17
drivers/ssb/ssb_private.h
··· 211 211 extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc); 212 212 extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); 213 213 214 + #ifdef CONFIG_SSB_DRIVER_EXTIF 215 + extern void ssb_extif_init(struct ssb_extif *extif); 216 + #else 217 + static inline void ssb_extif_init(struct ssb_extif *extif) 218 + { 219 + } 220 + #endif 221 + 222 + #ifdef CONFIG_SSB_DRIVER_GPIO 223 + extern int ssb_gpio_init(struct ssb_bus *bus); 224 + #else /* CONFIG_SSB_DRIVER_GPIO */ 225 + static inline int ssb_gpio_init(struct ssb_bus *bus) 226 + { 227 + return -ENOTSUPP; 228 + } 229 + #endif /* CONFIG_SSB_DRIVER_GPIO */ 230 + 214 231 #endif /* LINUX_SSB_PRIVATE_H_ */
+10
include/linux/bcma/bcma_driver_chipcommon.h
··· 1 1 #ifndef LINUX_BCMA_DRIVER_CC_H_ 2 2 #define LINUX_BCMA_DRIVER_CC_H_ 3 3 4 + #include <linux/gpio.h> 5 + 4 6 /** ChipCommon core registers. **/ 5 7 #define BCMA_CC_ID 0x0000 6 8 #define BCMA_CC_ID_ID 0x0000FFFF ··· 569 567 int nr_serial_ports; 570 568 struct bcma_serial_port serial_ports[4]; 571 569 #endif /* CONFIG_BCMA_DRIVER_MIPS */ 570 + 571 + /* Lock for GPIO register access. */ 572 + spinlock_t gpio_lock; 573 + #ifdef CONFIG_BCMA_DRIVER_GPIO 574 + struct gpio_chip gpio; 575 + #endif 572 576 }; 573 577 574 578 /* Register access */ ··· 611 603 u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value); 612 604 u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value); 613 605 u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value); 606 + u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value); 607 + u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value); 614 608 615 609 /* PMU support */ 616 610 extern void bcma_pmu_init(struct bcma_drv_cc *cc);
+4
include/linux/ssb/ssb.h
··· 6 6 #include <linux/types.h> 7 7 #include <linux/spinlock.h> 8 8 #include <linux/pci.h> 9 + #include <linux/gpio.h> 9 10 #include <linux/mod_devicetable.h> 10 11 #include <linux/dma-mapping.h> 11 12 ··· 434 433 /* Lock for GPIO register access. */ 435 434 spinlock_t gpio_lock; 436 435 #endif /* EMBEDDED */ 436 + #ifdef CONFIG_SSB_DRIVER_GPIO 437 + struct gpio_chip gpio; 438 + #endif /* DRIVER_GPIO */ 437 439 438 440 /* Internal-only stuff follows. Do not touch. */ 439 441 struct list_head list;
+3
include/linux/ssb/ssb_driver_chipcommon.h
··· 590 590 u32 status; 591 591 /* Fast Powerup Delay constant */ 592 592 u16 fast_pwrup_delay; 593 + spinlock_t gpio_lock; 593 594 struct ssb_chipcommon_pmu pmu; 594 595 }; 595 596 ··· 645 644 u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value); 646 645 u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value); 647 646 u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value); 647 + u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value); 648 + u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value); 648 649 649 650 #ifdef CONFIG_SSB_SERIAL 650 651 extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
+1
include/linux/ssb/ssb_driver_extif.h
··· 158 158 159 159 struct ssb_extif { 160 160 struct ssb_device *dev; 161 + spinlock_t gpio_lock; 161 162 }; 162 163 163 164 static inline bool ssb_extif_available(struct ssb_extif *extif)