···106106107107config BCM47XX108108 bool "Broadcom BCM47XX based boards"109109+ select ARCH_WANT_OPTIONAL_GPIOLIB109110 select CEVT_R4K110111 select CSRC_R4K111112 select DMA_NONCOHERENT···115114 select IRQ_CPU116115 select SYS_SUPPORTS_32BIT_KERNEL117116 select SYS_SUPPORTS_LITTLE_ENDIAN118118- select GENERIC_GPIO119117 select SYS_HAS_EARLY_PRINTK120118 help121119 Support for BCM47XX based boards···798798 select CSRC_R4K799799 select IRQ_CPU800800 select ARCH_SUPPORTS_MSI801801- select ZONE_DMA if 64BIT801801+ select ZONE_DMA32 if 64BIT802802 select SYNC_R4K803803 select SYS_HAS_EARLY_PRINTK804804 select USB_ARCH_HAS_OHCI if USB_SUPPORT···826826 select CEVT_R4K827827 select CSRC_R4K828828 select IRQ_CPU829829- select ZONE_DMA if 64BIT829829+ select ZONE_DMA32 if 64BIT830830 select SYNC_R4K831831 select SYS_HAS_EARLY_PRINTK832832 select USE_OF···15071507 select WEAK_ORDERING15081508 select WEAK_REORDERING_BEYOND_LLSC15091509 select CPU_HAS_PREFETCH15101510+ select CPU_MIPSR215101511 help15111512 Netlogic Microsystems XLP processors.15121513endchoice···17191718 bool17201719config MIPS_PGD_C0_CONTEXT17211720 bool17221722- default y if 64BIT && CPU_MIPSR217211721+ default y if 64BIT && CPU_MIPSR2 && !CPU_XLP1723172217241723#17251724# Set to y for ptrace access to watch registers.···2150214921512150config HW_PERF_EVENTS21522151 bool "Enable hardware performance counter support for perf events"21532153- depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON)21522152+ depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP)21542153 default y21552154 help21562155 Enable hardware performance counter support for perf events. If
+2
arch/mips/bcm47xx/Kconfig
···99 select SSB_EMBEDDED1010 select SSB_B43_PCI_BRIDGE if PCI1111 select SSB_PCICORE_HOSTMODE if PCI1212+ select SSB_DRIVER_GPIO1213 default y1314 help1415 Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support.···2423 select BCMA_DRIVER_MIPS2524 select BCMA_HOST_PCI if PCI2625 select BCMA_DRIVER_PCI_HOSTMODE if PCI2626+ select BCMA_DRIVER_GPIO2727 default y2828 help2929 Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
···11-/*22- * This file is subject to the terms and conditions of the GNU General Public33- * License. See the file "COPYING" in the main directory of this archive44- * for more details.55- *66- * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>77- */88-99-#include <linux/export.h>1010-#include <linux/ssb/ssb.h>1111-#include <linux/ssb/ssb_driver_chipcommon.h>1212-#include <linux/ssb/ssb_driver_extif.h>1313-#include <asm/mach-bcm47xx/bcm47xx.h>1414-#include <asm/mach-bcm47xx/gpio.h>1515-1616-#if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES)1717-static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES);1818-#else1919-static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);2020-#endif2121-2222-int gpio_request(unsigned gpio, const char *tag)2323-{2424- switch (bcm47xx_bus_type) {2525-#ifdef CONFIG_BCM47XX_SSB2626- case BCM47XX_BUS_TYPE_SSB:2727- if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&2828- ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))2929- return -EINVAL;3030-3131- if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&3232- ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))3333- return -EINVAL;3434-3535- if (test_and_set_bit(gpio, gpio_in_use))3636- return -EBUSY;3737-3838- return 0;3939-#endif4040-#ifdef CONFIG_BCM47XX_BCMA4141- case BCM47XX_BUS_TYPE_BCMA:4242- if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)4343- return -EINVAL;4444-4545- if (test_and_set_bit(gpio, gpio_in_use))4646- return -EBUSY;4747-4848- return 0;4949-#endif5050- }5151- return -EINVAL;5252-}5353-EXPORT_SYMBOL(gpio_request);5454-5555-void gpio_free(unsigned gpio)5656-{5757- switch (bcm47xx_bus_type) {5858-#ifdef CONFIG_BCM47XX_SSB5959- case BCM47XX_BUS_TYPE_SSB:6060- if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&6161- ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))6262- return;6363-6464- if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&6565- ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))6666- return;6767-6868- clear_bit(gpio, gpio_in_use);6969- return;7070-#endif7171-#ifdef CONFIG_BCM47XX_BCMA7272- case BCM47XX_BUS_TYPE_BCMA:7373- if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)7474- return;7575-7676- clear_bit(gpio, gpio_in_use);7777- return;7878-#endif7979- }8080-}8181-EXPORT_SYMBOL(gpio_free);8282-8383-int gpio_to_irq(unsigned gpio)8484-{8585- switch (bcm47xx_bus_type) {8686-#ifdef CONFIG_BCM47XX_SSB8787- case BCM47XX_BUS_TYPE_SSB:8888- if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco))8989- return ssb_mips_irq(bcm47xx_bus.ssb.chipco.dev) + 2;9090- else if (ssb_extif_available(&bcm47xx_bus.ssb.extif))9191- return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2;9292- else9393- return -EINVAL;9494-#endif9595-#ifdef CONFIG_BCM47XX_BCMA9696- case BCM47XX_BUS_TYPE_BCMA:9797- return bcma_core_mips_irq(bcm47xx_bus.bcma.bus.drv_cc.core) + 2;9898-#endif9999- }100100- return -EINVAL;101101-}102102-EXPORT_SYMBOL_GPL(gpio_to_irq);
+16-4
arch/mips/bcm47xx/prom.c
···11/*22 * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>33 * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>44+ * Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>45 *56 * This program is free software; you can redistribute it and/or modify it67 * under the terms of the GNU General Public License as published by the···2827#include <linux/types.h>2928#include <linux/kernel.h>3029#include <linux/spinlock.h>3030+#include <linux/smp.h>3131#include <asm/bootinfo.h>3232#include <asm/fw/cfe/cfe_api.h>3333#include <asm/fw/cfe/cfe_error.h>···129127{130128 unsigned long mem;131129 unsigned long max;130130+ unsigned long off;131131+ struct cpuinfo_mips *c = ¤t_cpu_data;132132133133 /* Figure out memory size by finding aliases.134134 *···147143 * max contains the biggest possible address supported by the platform.148144 * If the method wants to try something above we assume 128MB ram.149145 */150150- max = ((unsigned long)(prom_init) | ((128 << 20) - 1));146146+ off = (unsigned long)prom_init;147147+ max = off | ((128 << 20) - 1);151148 for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {152152- if (((unsigned long)(prom_init) + mem) > max) {149149+ if ((off + mem) > max) {153150 mem = (128 << 20);154151 printk(KERN_DEBUG "assume 128MB RAM\n");155152 break;156153 }157157- if (*(unsigned long *)((unsigned long)(prom_init) + mem) ==158158- *(unsigned long *)(prom_init))154154+ if (!memcmp(prom_init, prom_init + mem, 32))159155 break;160156 }157157+158158+ /* Ignoring the last page when ddr size is 128M. Cached159159+ * accesses to last page is causing the processor to prefetch160160+ * using address above 128M stepping out of the ddr address161161+ * space.162162+ */163163+ if (c->cputype == CPU_74K && (mem == (128 << 20)))164164+ mem -= 0x1000;161165162166 add_memory_region(0, mem, BOOT_MEM_RAM);163167}
···11+CONFIG_ATH79=y22+CONFIG_ATH79_MACH_AP121=y33+CONFIG_ATH79_MACH_AP81=y44+CONFIG_ATH79_MACH_DB120=y55+CONFIG_ATH79_MACH_PB44=y66+CONFIG_ATH79_MACH_UBNT_XM=y77+CONFIG_HZ_100=y88+# CONFIG_SECCOMP is not set99+CONFIG_EXPERIMENTAL=y1010+# CONFIG_LOCALVERSION_AUTO is not set1111+CONFIG_SYSVIPC=y1212+CONFIG_HIGH_RES_TIMERS=y1313+CONFIG_BLK_DEV_INITRD=y1414+# CONFIG_RD_GZIP is not set1515+CONFIG_RD_LZMA=y1616+# CONFIG_KALLSYMS is not set1717+# CONFIG_AIO is not set1818+CONFIG_EMBEDDED=y1919+# CONFIG_VM_EVENT_COUNTERS is not set2020+# CONFIG_SLUB_DEBUG is not set2121+# CONFIG_COMPAT_BRK is not set2222+CONFIG_MODULES=y2323+CONFIG_MODULE_UNLOAD=y2424+# CONFIG_BLK_DEV_BSG is not set2525+# CONFIG_IOSCHED_CFQ is not set2626+CONFIG_PCI=y2727+# CONFIG_SUSPEND is not set2828+CONFIG_NET=y2929+CONFIG_PACKET=y3030+CONFIG_UNIX=y3131+CONFIG_INET=y3232+CONFIG_IP_MULTICAST=y3333+CONFIG_IP_ADVANCED_ROUTER=y3434+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set3535+# CONFIG_INET_XFRM_MODE_TUNNEL is not set3636+# CONFIG_INET_XFRM_MODE_BEET is not set3737+# CONFIG_INET_LRO is not set3838+# CONFIG_IPV6 is not set3939+CONFIG_CFG80211=m4040+CONFIG_MAC80211=m4141+CONFIG_MAC80211_DEBUGFS=y4242+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"4343+# CONFIG_FIRMWARE_IN_KERNEL is not set4444+CONFIG_MTD=y4545+CONFIG_MTD_REDBOOT_PARTS=y4646+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-24747+CONFIG_MTD_CMDLINE_PARTS=y4848+CONFIG_MTD_CHAR=y4949+CONFIG_MTD_BLOCK=y5050+CONFIG_MTD_CFI=y5151+CONFIG_MTD_JEDECPROBE=y5252+CONFIG_MTD_CFI_AMDSTD=y5353+CONFIG_MTD_COMPLEX_MAPPINGS=y5454+CONFIG_MTD_PHYSMAP=y5555+CONFIG_MTD_M25P80=y5656+# CONFIG_M25PXX_USE_FAST_READ is not set5757+CONFIG_NETDEVICES=y5858+# CONFIG_NET_PACKET_ENGINE is not set5959+CONFIG_ATH_COMMON=m6060+CONFIG_ATH9K=m6161+CONFIG_ATH9K_AHB=y6262+CONFIG_INPUT=m6363+# CONFIG_INPUT_MOUSEDEV is not set6464+# CONFIG_KEYBOARD_ATKBD is not set6565+CONFIG_KEYBOARD_GPIO_POLLED=m6666+# CONFIG_INPUT_MOUSE is not set6767+CONFIG_INPUT_MISC=y6868+# CONFIG_SERIO is not set6969+# CONFIG_VT is not set7070+# CONFIG_LEGACY_PTYS is not set7171+# CONFIG_DEVKMEM is not set7272+CONFIG_SERIAL_8250=y7373+CONFIG_SERIAL_8250_CONSOLE=y7474+# CONFIG_SERIAL_8250_PCI is not set7575+CONFIG_SERIAL_8250_NR_UARTS=17676+CONFIG_SERIAL_8250_RUNTIME_UARTS=17777+CONFIG_SERIAL_AR933X=y7878+CONFIG_SERIAL_AR933X_CONSOLE=y7979+# CONFIG_HW_RANDOM is not set8080+CONFIG_I2C=y8181+# CONFIG_I2C_COMPAT is not set8282+# CONFIG_I2C_HELPER_AUTO is not set8383+CONFIG_I2C_GPIO=y8484+CONFIG_SPI=y8585+CONFIG_SPI_ATH79=y8686+CONFIG_SPI_GPIO=y8787+CONFIG_GPIO_SYSFS=y8888+CONFIG_GPIO_PCF857X=y8989+# CONFIG_HWMON is not set9090+CONFIG_WATCHDOG=y9191+CONFIG_ATH79_WDT=y9292+# CONFIG_VGA_ARB is not set9393+# CONFIG_HID is not set9494+# CONFIG_USB_HID is not set9595+CONFIG_USB=y9696+CONFIG_USB_EHCI_HCD=y9797+# CONFIG_USB_EHCI_TT_NEWSCHED is not set9898+CONFIG_USB_OHCI_HCD=y9999+CONFIG_LEDS_CLASS=y100100+CONFIG_LEDS_GPIO=y101101+# CONFIG_IOMMU_SUPPORT is not set102102+# CONFIG_DNOTIFY is not set103103+# CONFIG_PROC_PAGE_MONITOR is not set104104+# CONFIG_ENABLE_MUST_CHECK is not set105105+CONFIG_STRIP_ASM_SYMS=y106106+CONFIG_DEBUG_FS=y107107+# CONFIG_SCHED_DEBUG is not set108108+# CONFIG_FTRACE is not set109109+CONFIG_CRYPTO=y110110+# CONFIG_CRYPTO_ANSI_CPRNG is not set111111+CONFIG_CRC_ITU_T=m
···11+#ifndef BCM63XX_NVRAM_H22+#define BCM63XX_NVRAM_H33+44+#include <linux/types.h>55+66+/**77+ * bcm63xx_nvram_init() - initializes nvram88+ * @nvram: address of the nvram data99+ *1010+ * Initialized the local nvram copy from the target address and checks1111+ * its checksum.1212+ *1313+ * Returns 0 on success.1414+ */1515+int __init bcm63xx_nvram_init(void *nvram);1616+1717+/**1818+ * bcm63xx_nvram_get_name() - returns the board name according to nvram1919+ *2020+ * Returns the board name field from nvram. Note that it might not be2121+ * null terminated if it is exactly 16 bytes long.2222+ */2323+u8 *bcm63xx_nvram_get_name(void);2424+2525+/**2626+ * bcm63xx_nvram_get_mac_address() - register & return a new mac address2727+ * @mac: pointer to array for allocated mac2828+ *2929+ * Registers and returns a mac address from the allocated macs from nvram.3030+ *3131+ * Returns 0 on success.3232+ */3333+int bcm63xx_nvram_get_mac_address(u8 *mac);3434+3535+#endif /* BCM63XX_NVRAM_H */
+22-7
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
···5353 CKCTL_6338_SAR_EN | \5454 CKCTL_6338_SPI_EN)55555656-#define CKCTL_6345_CPU_EN (1 << 0)5757-#define CKCTL_6345_BUS_EN (1 << 1)5858-#define CKCTL_6345_EBI_EN (1 << 2)5959-#define CKCTL_6345_UART_EN (1 << 3)6060-#define CKCTL_6345_ADSLPHY_EN (1 << 4)6161-#define CKCTL_6345_ENET_EN (1 << 7)6262-#define CKCTL_6345_USBH_EN (1 << 8)5656+/* BCM6345 clock bits are shifted by 16 on the left, because of the test5757+ * control register which is 16-bits wide. That way we do not have any5858+ * specific BCM6345 code for handling clocks, and writing 0 to the test5959+ * control register is fine.6060+ */6161+#define CKCTL_6345_CPU_EN (1 << 16)6262+#define CKCTL_6345_BUS_EN (1 << 17)6363+#define CKCTL_6345_EBI_EN (1 << 18)6464+#define CKCTL_6345_UART_EN (1 << 19)6565+#define CKCTL_6345_ADSLPHY_EN (1 << 20)6666+#define CKCTL_6345_ENET_EN (1 << 23)6767+#define CKCTL_6345_USBH_EN (1 << 24)63686469#define CKCTL_6345_ALL_SAFE_EN (CKCTL_6345_ENET_EN | \6570 CKCTL_6345_USBH_EN | \···196191/* Soft Reset register */197192#define PERF_SOFTRESET_REG 0x28198193#define PERF_SOFTRESET_6328_REG 0x10194194+#define PERF_SOFTRESET_6358_REG 0x34199195#define PERF_SOFTRESET_6368_REG 0x10200196201197#define SOFTRESET_6328_SPI_MASK (1 << 0)···249243 SOFTRESET_6348_SAR_MASK | \250244 SOFTRESET_6348_ACLC_MASK | \251245 SOFTRESET_6348_ADSLMIPSPLL_MASK)246246+247247+#define SOFTRESET_6358_SPI_MASK (1 << 0)248248+#define SOFTRESET_6358_ENET_MASK (1 << 2)249249+#define SOFTRESET_6358_MPI_MASK (1 << 3)250250+#define SOFTRESET_6358_EPHY_MASK (1 << 6)251251+#define SOFTRESET_6358_SAR_MASK (1 << 7)252252+#define SOFTRESET_6358_USBH_MASK (1 << 12)253253+#define SOFTRESET_6358_PCM_MASK (1 << 13)254254+#define SOFTRESET_6358_ADSL_MASK (1 << 14)252255253256#define SOFTRESET_6368_SPI_MASK (1 << 0)254257#define SOFTRESET_6368_MPI_MASK (1 << 3)
···11+/*22+ * Copyright (c) 2003-2012 Broadcom Corporation33+ * All Rights Reserved44+ *55+ * This software is available to you under a choice of one of two66+ * licenses. You may choose to be licensed under the terms of the GNU77+ * General Public License (GPL) Version 2, available from the file88+ * COPYING in the main directory of this source tree, or the Broadcom99+ * license below:1010+ *1111+ * Redistribution and use in source and binary forms, with or without1212+ * modification, are permitted provided that the following conditions1313+ * are met:1414+ *1515+ * 1. Redistributions of source code must retain the above copyright1616+ * notice, this list of conditions and the following disclaimer.1717+ * 2. Redistributions in binary form must reproduce the above copyright1818+ * notice, this list of conditions and the following disclaimer in1919+ * the documentation and/or other materials provided with the2020+ * distribution.2121+ *2222+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR2323+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED2424+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE2525+ * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE2626+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR2727+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF2828+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR2929+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,3030+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE3131+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN3232+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3333+ */3434+3535+#ifndef _NETLOGIC_MULTI_NODE_H_3636+#define _NETLOGIC_MULTI_NODE_H_3737+3838+#ifndef CONFIG_NLM_MULTINODE3939+#define NLM_NR_NODES 14040+#else4141+#if defined(CONFIG_NLM_MULTINODE_2)4242+#define NLM_NR_NODES 24343+#elif defined(CONFIG_NLM_MULTINODE_4)4444+#define NLM_NR_NODES 44545+#else4646+#define NLM_NR_NODES 14747+#endif4848+#endif4949+5050+#define NLM_CORES_PER_NODE 85151+#define NLM_THREADS_PER_CORE 45252+#define NLM_CPUS_PER_NODE (NLM_CORES_PER_NODE * NLM_THREADS_PER_CORE)5353+5454+#endif
+44-7
arch/mips/include/asm/netlogic/common.h
···4545#define BOOT_NMI_HANDLER 846464747#ifndef __ASSEMBLY__4848+#include <linux/cpumask.h>4949+#include <linux/spinlock.h>5050+#include <asm/irq.h>5151+#include <asm/mach-netlogic/multi-node.h>5252+4853struct irq_desc;4949-extern struct plat_smp_ops nlm_smp_ops;5050-extern char nlm_reset_entry[], nlm_reset_entry_end[];5154void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc);5255void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc);5353-void nlm_smp_irq_init(void);5656+void nlm_smp_irq_init(int hwcpuid);5457void nlm_boot_secondary_cpus(void);5555-int nlm_wakeup_secondary_cpus(u32 wakeup_mask);5858+int nlm_wakeup_secondary_cpus(void);5659void nlm_rmiboot_preboot(void);6060+void nlm_percpu_init(int hwcpuid);57615862static inline void5963nlm_set_nmi_handler(void *handler)···7268 * Misc.7369 */7470unsigned int nlm_get_cpu_frequency(void);7171+void nlm_node_init(int node);7272+extern struct plat_smp_ops nlm_smp_ops;7373+extern char nlm_reset_entry[], nlm_reset_entry_end[];75747676-extern unsigned long nlm_common_ebase;7777-extern int nlm_threads_per_core;7878-extern uint32_t nlm_cpumask, nlm_coremask;7575+extern unsigned int nlm_threads_per_core;7676+extern cpumask_t nlm_cpumask;7777+7878+struct nlm_soc_info {7979+ unsigned long coremask; /* cores enabled on the soc */8080+ unsigned long ebase;8181+ uint64_t irqmask;8282+ uint64_t sysbase; /* only for XLP */8383+ uint64_t picbase;8484+ spinlock_t piclock;8585+};8686+8787+#define nlm_get_node(i) (&nlm_nodes[i])8888+#ifdef CONFIG_CPU_XLR8989+#define nlm_current_node() (&nlm_nodes[0])9090+#else9191+#define nlm_current_node() (&nlm_nodes[nlm_nodeid()])9292+#endif9393+9494+struct irq_data;9595+uint64_t nlm_pci_irqmask(int node);9696+void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *));9797+9898+/*9999+ * The NR_IRQs is divided between nodes, each of them has a separate irq space100100+ */101101+static inline int nlm_irq_to_xirq(int node, int irq)102102+{103103+ return node * NR_IRQS / NLM_NR_NODES + irq;104104+}105105+106106+extern struct nlm_soc_info nlm_nodes[NLM_NR_NODES];107107+extern int nlm_cpu_ready[];79108#endif80109#endif /* _NETLOGIC_COMMON_H_ */
···183183184184static int __cpuinitdata hazard_instance;185185186186-static void uasm_bgezl_hazard(u32 **p, struct uasm_reloc **r, int instance)186186+static void __cpuinit uasm_bgezl_hazard(u32 **p,187187+ struct uasm_reloc **r,188188+ int instance)187189{188190 switch (instance) {189191 case 0 ... 7:···196194 }197195}198196199199-static void uasm_bgezl_label(struct uasm_label **l, u32 **p, int instance)197197+static void __cpuinit uasm_bgezl_label(struct uasm_label **l,198198+ u32 **p,199199+ int instance)200200{201201 switch (instance) {202202 case 0 ... 7:
+28
arch/mips/netlogic/Kconfig
···99 This DTB will be used if the firmware does not pass in a DTB1010 pointer to the kernel. The corresponding DTS file is at1111 arch/mips/netlogic/dts/xlp_evp.dts1212+1313+config NLM_MULTINODE1414+ bool "Support for multi-chip boards"1515+ depends on NLM_XLP_BOARD1616+ default n1717+ help1818+ Add support for boards with 2 or 4 XLPs connected over ICI.1919+2020+if NLM_MULTINODE2121+choice2222+ prompt "Number of XLPs on the board"2323+ default NLM_MULTINODE_22424+ help2525+ In the multi-node case, specify the number of SoCs on the board.2626+2727+config NLM_MULTINODE_22828+ bool "Dual-XLP board"2929+ help3030+ Support boards with upto two XLPs connected over ICI.3131+3232+config NLM_MULTINODE_43333+ bool "Quad-XLP board"3434+ help3535+ Support boards with upto four XLPs connected over ICI.3636+3737+endchoice3838+3939+endif1240endif13411442config NLM_COMMON
+105-60
arch/mips/netlogic/common/irq.c
···3636#include <linux/init.h>3737#include <linux/linkage.h>3838#include <linux/interrupt.h>3939-#include <linux/spinlock.h>4039#include <linux/mm.h>4140#include <linux/slab.h>4241#include <linux/irq.h>···5859#elif defined(CONFIG_CPU_XLR)5960#include <asm/netlogic/xlr/iomap.h>6061#include <asm/netlogic/xlr/pic.h>6262+#include <asm/netlogic/xlr/fmn.h>6163#else6264#error "Unknown CPU"6365#endif6464-/*6565- * These are the routines that handle all the low level interrupt stuff.6666- * Actions handled here are: initialization of the interrupt map, requesting of6767- * interrupt lines by handlers, dispatching if interrupts to handlers, probing6868- * for interrupt lines6969- */70667171-/* Globals */7272-static uint64_t nlm_irq_mask;7373-static DEFINE_SPINLOCK(nlm_pic_lock);6767+#ifdef CONFIG_SMP6868+#define SMP_IRQ_MASK ((1ULL << IRQ_IPI_SMP_FUNCTION) | \6969+ (1ULL << IRQ_IPI_SMP_RESCHEDULE))7070+#else7171+#define SMP_IRQ_MASK 07272+#endif7373+#define PERCPU_IRQ_MASK (SMP_IRQ_MASK | (1ull << IRQ_TIMER) | \7474+ (1ull << IRQ_FMN))7575+7676+struct nlm_pic_irq {7777+ void (*extra_ack)(struct irq_data *);7878+ struct nlm_soc_info *node;7979+ int picirq;8080+ int irt;8181+ int flags;8282+};74837584static void xlp_pic_enable(struct irq_data *d)7685{7786 unsigned long flags;7878- int irt;8787+ struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);79888080- irt = nlm_irq_to_irt(d->irq);8181- if (irt == -1)8282- return;8383- spin_lock_irqsave(&nlm_pic_lock, flags);8484- nlm_pic_enable_irt(nlm_pic_base, irt);8585- spin_unlock_irqrestore(&nlm_pic_lock, flags);8989+ BUG_ON(!pd);9090+ spin_lock_irqsave(&pd->node->piclock, flags);9191+ nlm_pic_enable_irt(pd->node->picbase, pd->irt);9292+ spin_unlock_irqrestore(&pd->node->piclock, flags);8693}87948895static void xlp_pic_disable(struct irq_data *d)8996{9797+ struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);9098 unsigned long flags;9191- int irt;92999393- irt = nlm_irq_to_irt(d->irq);9494- if (irt == -1)9595- return;9696- spin_lock_irqsave(&nlm_pic_lock, flags);9797- nlm_pic_disable_irt(nlm_pic_base, irt);9898- spin_unlock_irqrestore(&nlm_pic_lock, flags);100100+ BUG_ON(!pd);101101+ spin_lock_irqsave(&pd->node->piclock, flags);102102+ nlm_pic_disable_irt(pd->node->picbase, pd->irt);103103+ spin_unlock_irqrestore(&pd->node->piclock, flags);99104}100105101106static void xlp_pic_mask_ack(struct irq_data *d)102107{103103- uint64_t mask = 1ull << d->irq;108108+ struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);109109+ uint64_t mask = 1ull << pd->picirq;104110105111 write_c0_eirr(mask); /* ack by writing EIRR */106112}107113108114static void xlp_pic_unmask(struct irq_data *d)109115{110110- void *hd = irq_data_get_irq_handler_data(d);111111- int irt;116116+ struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);112117113113- irt = nlm_irq_to_irt(d->irq);114114- if (irt == -1)118118+ if (!pd)115119 return;116120117117- if (hd) {118118- void (*extra_ack)(void *) = hd;119119- extra_ack(d);120120- }121121+ if (pd->extra_ack)122122+ pd->extra_ack(d);123123+121124 /* Ack is a single write, no need to lock */122122- nlm_pic_ack(nlm_pic_base, irt);125125+ nlm_pic_ack(pd->node->picbase, pd->irt);123126}124127125128static struct irq_chip xlp_pic = {···175174 .irq_eoi = cpuintr_ack,176175};177176178178-void __init init_nlm_common_irqs(void)177177+static void __init nlm_init_percpu_irqs(void)179178{180180- int i, irq, irt;179179+ int i;181180182181 for (i = 0; i < PIC_IRT_FIRST_IRQ; i++)183182 irq_set_chip_and_handler(i, &nlm_cpu_intr, handle_percpu_irq);184184-185185- for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ ; i++)186186- irq_set_chip_and_handler(i, &xlp_pic, handle_level_irq);187187-188183#ifdef CONFIG_SMP189184 irq_set_chip_and_handler(IRQ_IPI_SMP_FUNCTION, &nlm_cpu_intr,190185 nlm_smp_function_ipi_handler);191186 irq_set_chip_and_handler(IRQ_IPI_SMP_RESCHEDULE, &nlm_cpu_intr,192187 nlm_smp_resched_ipi_handler);193193- nlm_irq_mask |=194194- ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE));195188#endif189189+}196190197197- for (irq = PIC_IRT_FIRST_IRQ; irq <= PIC_IRT_LAST_IRQ; irq++) {198198- irt = nlm_irq_to_irt(irq);191191+void nlm_setup_pic_irq(int node, int picirq, int irq, int irt)192192+{193193+ struct nlm_pic_irq *pic_data;194194+ int xirq;195195+196196+ xirq = nlm_irq_to_xirq(node, irq);197197+ pic_data = kzalloc(sizeof(*pic_data), GFP_KERNEL);198198+ BUG_ON(pic_data == NULL);199199+ pic_data->irt = irt;200200+ pic_data->picirq = picirq;201201+ pic_data->node = nlm_get_node(node);202202+ irq_set_chip_and_handler(xirq, &xlp_pic, handle_level_irq);203203+ irq_set_handler_data(xirq, pic_data);204204+}205205+206206+void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *))207207+{208208+ struct nlm_pic_irq *pic_data;209209+ int xirq;210210+211211+ xirq = nlm_irq_to_xirq(node, irq);212212+ pic_data = irq_get_handler_data(xirq);213213+ pic_data->extra_ack = xack;214214+}215215+216216+static void nlm_init_node_irqs(int node)217217+{218218+ int i, irt;219219+ uint64_t irqmask;220220+ struct nlm_soc_info *nodep;221221+222222+ pr_info("Init IRQ for node %d\n", node);223223+ nodep = nlm_get_node(node);224224+ irqmask = PERCPU_IRQ_MASK;225225+ for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ; i++) {226226+ irt = nlm_irq_to_irt(i);199227 if (irt == -1)200228 continue;201201- nlm_irq_mask |= (1ULL << irq);202202- nlm_pic_init_irt(nlm_pic_base, irt, irq, 0);229229+ nlm_setup_pic_irq(node, i, i, irt);230230+ /* set interrupts to first cpu in node */231231+ nlm_pic_init_irt(nodep->picbase, irt, i,232232+ node * NLM_CPUS_PER_NODE);233233+ irqmask |= (1ull << i);203234 }204204-205205- nlm_irq_mask |= (1ULL << IRQ_TIMER);235235+ nodep->irqmask = irqmask;206236}207237208238void __init arch_init_irq(void)209239{210240 /* Initialize the irq descriptors */211211- init_nlm_common_irqs();212212-213213- write_c0_eimr(nlm_irq_mask);241241+ nlm_init_percpu_irqs();242242+ nlm_init_node_irqs(0);243243+ write_c0_eimr(nlm_current_node()->irqmask);244244+#if defined(CONFIG_CPU_XLR)245245+ nlm_setup_fmn_irq();246246+#endif214247}215248216216-void __cpuinit nlm_smp_irq_init(void)249249+void nlm_smp_irq_init(int hwcpuid)217250{218218- /* set interrupt mask for non-zero cpus */219219- write_c0_eimr(nlm_irq_mask);251251+ int node, cpu;252252+253253+ node = hwcpuid / NLM_CPUS_PER_NODE;254254+ cpu = hwcpuid % NLM_CPUS_PER_NODE;255255+256256+ if (cpu == 0 && node != 0)257257+ nlm_init_node_irqs(node);258258+ write_c0_eimr(nlm_current_node()->irqmask);220259}221260222261asmlinkage void plat_irq_dispatch(void)223262{224263 uint64_t eirr;225225- int i;264264+ int i, node;226265266266+ node = nlm_nodeid();227267 eirr = read_c0_eirr() & read_c0_eimr();228228- if (eirr & (1 << IRQ_TIMER)) {229229- do_IRQ(IRQ_TIMER);230230- return;231231- }232268233269 i = __ilog2_u64(eirr);234270 if (i == -1)235271 return;236272237237- do_IRQ(i);273273+ /* per-CPU IRQs don't need translation */274274+ if (eirr & PERCPU_IRQ_MASK) {275275+ do_IRQ(i);276276+ return;277277+ }278278+279279+ /* top level irq handling */280280+ do_IRQ(nlm_irq_to_xirq(node, i));238281}
+51-38
arch/mips/netlogic/common/smp.c
···59596060void nlm_send_ipi_single(int logical_cpu, unsigned int action)6161{6262- int cpu = cpu_logical_map(logical_cpu);6262+ int cpu, node;6363+ uint64_t picbase;6464+6565+ cpu = cpu_logical_map(logical_cpu);6666+ node = cpu / NLM_CPUS_PER_NODE;6767+ picbase = nlm_get_node(node)->picbase;63686469 if (action & SMP_CALL_FUNCTION)6565- nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_FUNCTION, 0);7070+ nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_FUNCTION, 0);6671 if (action & SMP_RESCHEDULE_YOURSELF)6767- nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_RESCHEDULE, 0);7272+ nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_RESCHEDULE, 0);6873}69747075void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action)···10196void nlm_early_init_secondary(int cpu)10297{10398 change_c0_config(CONF_CM_CMASK, 0x3);104104- write_c0_ebase((uint32_t)nlm_common_ebase);10599#ifdef CONFIG_CPU_XLP106106- if (hard_smp_processor_id() % 4 == 0)100100+ /* mmu init, once per core */101101+ if (cpu % NLM_THREADS_PER_CORE == 0)107102 xlp_mmu_init();108103#endif104104+ write_c0_ebase(nlm_current_node()->ebase);109105}110106111107/*···114108 */115109static void __cpuinit nlm_init_secondary(void)116110{117117- current_cpu_data.core = hard_smp_processor_id() / 4;118118- nlm_smp_irq_init();111111+ int hwtid;112112+113113+ hwtid = hard_smp_processor_id();114114+ current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE;115115+ nlm_percpu_init(hwtid);116116+ nlm_smp_irq_init(hwtid);119117}120118121119void nlm_prepare_cpus(unsigned int max_cpus)···130120131121void nlm_smp_finish(void)132122{133133-#ifdef notyet134134- nlm_common_msgring_cpu_init();135135-#endif136123 local_irq_enable();137124}138125···149142150143void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)151144{152152- unsigned long gp = (unsigned long)task_thread_info(idle);153153- unsigned long sp = (unsigned long)__KSTK_TOS(idle);154154- int cpu = cpu_logical_map(logical_cpu);145145+ int cpu, node;155146156156- nlm_next_sp = sp;157157- nlm_next_gp = gp;147147+ cpu = cpu_logical_map(logical_cpu);148148+ node = cpu / NLM_CPUS_PER_NODE;149149+ nlm_next_sp = (unsigned long)__KSTK_TOS(idle);150150+ nlm_next_gp = (unsigned long)task_thread_info(idle);158151159159- /* barrier */152152+ /* barrier for sp/gp store above */160153 __sync();161161- nlm_pic_send_ipi(nlm_pic_base, cpu, 1, 1);154154+ nlm_pic_send_ipi(nlm_get_node(node)->picbase, cpu, 1, 1); /* NMI */162155}163156164157void __init nlm_smp_setup(void)165158{166159 unsigned int boot_cpu;167167- int num_cpus, i;160160+ int num_cpus, i, ncore;168161169162 boot_cpu = hard_smp_processor_id();170170- cpus_clear(phys_cpu_present_map);163163+ cpumask_clear(&phys_cpu_present_map);171164172172- cpu_set(boot_cpu, phys_cpu_present_map);165165+ cpumask_set_cpu(boot_cpu, &phys_cpu_present_map);173166 __cpu_number_map[boot_cpu] = 0;174167 __cpu_logical_map[0] = boot_cpu;175168 set_cpu_possible(0, true);···181174 * it is only set for ASPs (see smpboot.S)182175 */183176 if (nlm_cpu_ready[i]) {184184- cpu_set(i, phys_cpu_present_map);177177+ cpumask_set_cpu(i, &phys_cpu_present_map);185178 __cpu_number_map[i] = num_cpus;186179 __cpu_logical_map[num_cpus] = i;187180 set_cpu_possible(num_cpus, true);···189182 }190183 }191184185185+ /* check with the cores we have worken up */186186+ for (ncore = 0, i = 0; i < NLM_NR_NODES; i++)187187+ ncore += hweight32(nlm_get_node(i)->coremask);188188+192189 pr_info("Phys CPU present map: %lx, possible map %lx\n",193193- (unsigned long)phys_cpu_present_map.bits[0],190190+ (unsigned long)cpumask_bits(&phys_cpu_present_map)[0],194191 (unsigned long)cpumask_bits(cpu_possible_mask)[0]);195192196196- pr_info("Detected %i Slave CPU(s)\n", num_cpus);193193+ pr_info("Detected (%dc%dt) %d Slave CPU(s)\n", ncore,194194+ nlm_threads_per_core, num_cpus);197195 nlm_set_nmi_handler(nlm_boot_secondary_cpus);198196}199197200200-static int nlm_parse_cpumask(u32 cpu_mask)198198+static int nlm_parse_cpumask(cpumask_t *wakeup_mask)201199{202200 uint32_t core0_thr_mask, core_thr_mask;203203- int threadmode, i;201201+ int threadmode, i, j;204202205205- core0_thr_mask = cpu_mask & 0xf;203203+ core0_thr_mask = 0;204204+ for (i = 0; i < NLM_THREADS_PER_CORE; i++)205205+ if (cpumask_test_cpu(i, wakeup_mask))206206+ core0_thr_mask |= (1 << i);206207 switch (core0_thr_mask) {207208 case 1:208209 nlm_threads_per_core = 1;···229214 }230215231216 /* Verify other cores CPU masks */232232- nlm_coremask = 1;233233- nlm_cpumask = core0_thr_mask;234234- for (i = 1; i < 8; i++) {235235- core_thr_mask = (cpu_mask >> (i * 4)) & 0xf;236236- if (core_thr_mask) {237237- if (core_thr_mask != core0_thr_mask)217217+ for (i = 0; i < NR_CPUS; i += NLM_THREADS_PER_CORE) {218218+ core_thr_mask = 0;219219+ for (j = 0; j < NLM_THREADS_PER_CORE; j++)220220+ if (cpumask_test_cpu(i + j, wakeup_mask))221221+ core_thr_mask |= (1 << j);222222+ if (core_thr_mask != 0 && core_thr_mask != core0_thr_mask)238223 goto unsupp;239239- nlm_coremask |= 1 << i;240240- nlm_cpumask |= core0_thr_mask << (4 * i);241241- }242224 }243225 return threadmode;244226245227unsupp:246246- panic("Unsupported CPU mask %x\n", cpu_mask);228228+ panic("Unsupported CPU mask %lx\n",229229+ (unsigned long)cpumask_bits(wakeup_mask)[0]);247230 return 0;248231}249232250250-int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask)233233+int __cpuinit nlm_wakeup_secondary_cpus(void)251234{252235 unsigned long reset_vec;253236 char *reset_data;···257244 (nlm_reset_entry_end - nlm_reset_entry));258245259246 /* verify the mask and setup core config variables */260260- threadmode = nlm_parse_cpumask(wakeup_mask);247247+ threadmode = nlm_parse_cpumask(&nlm_cpumask);261248262249 /* Setup CPU init parameters */263250 reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS);
+4-2
arch/mips/netlogic/common/smpboot.S
···6161 li t0, LSU_DEFEATURE6262 mfcr t1, t063636464- lui t2, 0x4080 /* Enable Unaligned Access, L2HPE */6464+ lui t2, 0xc080 /* SUE, Enable Unaligned Access, L2HPE */6565 or t1, t1, t26666#ifdef XLP_AX_WORKAROUND6767 li t2, ~0xe /* S1RCM */···186186 * jump to the secondary wait function.187187 */188188 mfc0 v0, CP0_EBASE, 1189189- andi v0, 0x7f /* v0 <- node/core */189189+ andi v0, 0x3ff /* v0 <- node/core */190190191191 /* Init MMU in the first thread after changing THREAD_MODE192192 * register (Ax Errata?)···263263 PTR_L gp, 0(t1)264264265265 /* a0 has the processor id */266266+ mfc0 a0, CP0_EBASE, 1267267+ andi a0, 0x3ff /* a0 <- node/core */266268 PTR_LA t0, nlm_early_init_secondary267269 jalr t0268270 nop
+15-52
arch/mips/netlogic/xlp/nlm_hal.c
···4040#include <asm/mipsregs.h>4141#include <asm/time.h>42424343+#include <asm/netlogic/common.h>4344#include <asm/netlogic/haldefs.h>4445#include <asm/netlogic/xlp-hal/iomap.h>4546#include <asm/netlogic/xlp-hal/xlp.h>4647#include <asm/netlogic/xlp-hal/pic.h>4748#include <asm/netlogic/xlp-hal/sys.h>48494949-/* These addresses are computed by the nlm_hal_init() */5050-uint64_t nlm_io_base;5151-uint64_t nlm_sys_base;5252-uint64_t nlm_pic_base;5353-5450/* Main initialization */5555-void nlm_hal_init(void)5151+void nlm_node_init(int node)5652{5757- nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE);5858- nlm_sys_base = nlm_get_sys_regbase(0); /* node 0 */5959- nlm_pic_base = nlm_get_pic_regbase(0); /* node 0 */5353+ struct nlm_soc_info *nodep;5454+5555+ nodep = nlm_get_node(node);5656+ nodep->sysbase = nlm_get_sys_regbase(node);5757+ nodep->picbase = nlm_get_pic_regbase(node);5858+ nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1));5959+ spin_lock_init(&nodep->piclock);6060}61616262int nlm_irq_to_irt(int irq)···100100 }101101}102102103103-int nlm_irt_to_irq(int irt)104104-{105105- switch (irt) {106106- case PIC_IRT_UART_0_INDEX:107107- return PIC_UART_0_IRQ;108108- case PIC_IRT_UART_1_INDEX:109109- return PIC_UART_1_IRQ;110110- case PIC_IRT_PCIE_LINK_0_INDEX:111111- return PIC_PCIE_LINK_0_IRQ;112112- case PIC_IRT_PCIE_LINK_1_INDEX:113113- return PIC_PCIE_LINK_1_IRQ;114114- case PIC_IRT_PCIE_LINK_2_INDEX:115115- return PIC_PCIE_LINK_2_IRQ;116116- case PIC_IRT_PCIE_LINK_3_INDEX:117117- return PIC_PCIE_LINK_3_IRQ;118118- case PIC_IRT_EHCI_0_INDEX:119119- return PIC_EHCI_0_IRQ;120120- case PIC_IRT_EHCI_1_INDEX:121121- return PIC_EHCI_1_IRQ;122122- case PIC_IRT_OHCI_0_INDEX:123123- return PIC_OHCI_0_IRQ;124124- case PIC_IRT_OHCI_1_INDEX:125125- return PIC_OHCI_1_IRQ;126126- case PIC_IRT_OHCI_2_INDEX:127127- return PIC_OHCI_2_IRQ;128128- case PIC_IRT_OHCI_3_INDEX:129129- return PIC_OHCI_3_IRQ;130130- case PIC_IRT_MMC_INDEX:131131- return PIC_MMC_IRQ;132132- case PIC_IRT_I2C_0_INDEX:133133- return PIC_I2C_0_IRQ;134134- case PIC_IRT_I2C_1_INDEX:135135- return PIC_I2C_1_IRQ;136136- default:137137- return -1;138138- }139139-}140140-141141-unsigned int nlm_get_core_frequency(int core)103103+unsigned int nlm_get_core_frequency(int node, int core)142104{143105 unsigned int pll_divf, pll_divr, dfs_div, ext_div;144106 unsigned int rstval, dfsval, denom;145145- uint64_t num;107107+ uint64_t num, sysbase;146108147147- rstval = nlm_read_sys_reg(nlm_sys_base, SYS_POWER_ON_RESET_CFG);148148- dfsval = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIV_VALUE);109109+ sysbase = nlm_get_node(node)->sysbase;110110+ rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);111111+ dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE);149112 pll_divf = ((rstval >> 10) & 0x7f) + 1;150113 pll_divr = ((rstval >> 8) & 0x3) + 1;151114 ext_div = ((rstval >> 30) & 0x3) + 1;···122159123160unsigned int nlm_get_cpu_frequency(void)124161{125125- return nlm_get_core_frequency(0);162162+ return nlm_get_core_frequency(0, 0);126163}
+28-22
arch/mips/netlogic/xlp/setup.c
···5252#include <asm/netlogic/xlp-hal/xlp.h>5353#include <asm/netlogic/xlp-hal/sys.h>54545555-unsigned long nlm_common_ebase = 0x0;5656-5757-/* default to uniprocessor */5858-uint32_t nlm_coremask = 1, nlm_cpumask = 1;5959-int nlm_threads_per_core = 1;5555+uint64_t nlm_io_base;5656+struct nlm_soc_info nlm_nodes[NLM_NR_NODES];5757+cpumask_t nlm_cpumask = CPU_MASK_CPU0;5858+unsigned int nlm_threads_per_core;6059extern u32 __dtb_start[];61606261static void nlm_linux_exit(void)6362{6464- nlm_write_sys_reg(nlm_sys_base, SYS_CHIP_RESET, 1);6363+ uint64_t sysbase = nlm_get_node(0)->sysbase;6464+6565+ nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1);6566 for ( ; ; )6667 cpu_wait();6768}68696970void __init plat_mem_setup(void)7071{7272+ void *fdtp;7373+7174 panic_timeout = 5;7275 _machine_restart = (void (*)(char *))nlm_linux_exit;7376 _machine_halt = nlm_linux_exit;7477 pm_power_off = nlm_linux_exit;7878+7979+ /*8080+ * If no FDT pointer is passed in, use the built-in FDT.8181+ * device_tree_init() does not handle CKSEG0 pointers in8282+ * 64-bit, so convert pointer.8383+ */8484+ fdtp = (void *)(long)fw_arg0;8585+ if (!fdtp)8686+ fdtp = __dtb_start;8787+ fdtp = phys_to_virt(__pa(fdtp));8888+ early_init_devtree(fdtp);7589}76907791const char *get_system_type(void)···10894 (13 + (ffz(PM_DEFAULT_MASK >> 13) / 2)));10995}110969797+void nlm_percpu_init(int hwcpuid)9898+{9999+}100100+111101void __init prom_init(void)112102{113113- void *fdtp;114114-103103+ nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE);115104 xlp_mmu_init();116116- nlm_hal_init();105105+ nlm_node_init(0);117106118118- /*119119- * If no FDT pointer is passed in, use the built-in FDT.120120- * device_tree_init() does not handle CKSEG0 pointers in121121- * 64-bit, so convert pointer.122122- */123123- fdtp = (void *)(long)fw_arg0;124124- if (!fdtp)125125- fdtp = __dtb_start;126126- fdtp = phys_to_virt(__pa(fdtp));127127- early_init_devtree(fdtp);128128-129129- nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));130107#ifdef CONFIG_SMP131131- nlm_wakeup_secondary_cpus(0xffffffff);108108+ cpumask_setall(&nlm_cpumask);109109+ nlm_wakeup_secondary_cpus();132110133111 /* update TLB size after waking up threads */134112 current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1;
+55-28
arch/mips/netlogic/xlp/wakeup.c
···5151#include <asm/netlogic/xlp-hal/xlp.h>5252#include <asm/netlogic/xlp-hal/sys.h>53535454-static void xlp_enable_secondary_cores(void)5454+static int xlp_wakeup_core(uint64_t sysbase, int core)5555{5656- uint32_t core, value, coremask, syscoremask;5656+ uint32_t coremask, value;5757 int count;58585959- /* read cores in reset from SYS block */6060- syscoremask = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET);5959+ coremask = (1 << core);61606262- /* update user specified */6363- nlm_coremask = nlm_coremask & (syscoremask | 1);6161+ /* Enable CPU clock */6262+ value = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL);6363+ value &= ~coremask;6464+ nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value);64656565- for (core = 1; core < 8; core++) {6666- coremask = 1 << core;6767- if ((nlm_coremask & coremask) == 0)6868- continue;6666+ /* Remove CPU Reset */6767+ value = nlm_read_sys_reg(sysbase, SYS_CPU_RESET);6868+ value &= ~coremask;6969+ nlm_write_sys_reg(sysbase, SYS_CPU_RESET, value);69707070- /* Enable CPU clock */7171- value = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL);7272- value &= ~coremask;7373- nlm_write_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL, value);7171+ /* Poll for CPU to mark itself coherent */7272+ count = 100000;7373+ do {7474+ value = nlm_read_sys_reg(sysbase, SYS_CPU_NONCOHERENT_MODE);7575+ } while ((value & coremask) != 0 && --count > 0);74767575- /* Remove CPU Reset */7676- value = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET);7777- value &= ~coremask;7878- nlm_write_sys_reg(nlm_sys_base, SYS_CPU_RESET, value);7777+ return count != 0;7878+}79798080- /* Poll for CPU to mark itself coherent */8181- count = 100000;8282- do {8383- value = nlm_read_sys_reg(nlm_sys_base,8484- SYS_CPU_NONCOHERENT_MODE);8585- } while ((value & coremask) != 0 && count-- > 0);8080+static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)8181+{8282+ struct nlm_soc_info *nodep;8383+ uint64_t syspcibase;8484+ uint32_t syscoremask;8585+ int core, n, cpu;86868787- if (count == 0)8888- pr_err("Failed to enable core %d\n", core);8787+ for (n = 0; n < NLM_NR_NODES; n++) {8888+ syspcibase = nlm_get_sys_pcibase(n);8989+ if (nlm_read_reg(syspcibase, 0) == 0xffffffff)9090+ break;9191+9292+ /* read cores in reset from SYS and account for boot cpu */9393+ nlm_node_init(n);9494+ nodep = nlm_get_node(n);9595+ syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET);9696+ if (n == 0)9797+ syscoremask |= 1;9898+9999+ for (core = 0; core < NLM_CORES_PER_NODE; core++) {100100+ /* see if the core exists */101101+ if ((syscoremask & (1 << core)) == 0)102102+ continue;103103+104104+ /* see if at least the first thread is enabled */105105+ cpu = (n * NLM_CORES_PER_NODE + core)106106+ * NLM_THREADS_PER_CORE;107107+ if (!cpumask_test_cpu(cpu, wakeup_mask))108108+ continue;109109+110110+ /* wake up the core */111111+ if (xlp_wakeup_core(nodep->sysbase, core))112112+ nodep->coremask |= 1u << core;113113+ else114114+ pr_err("Failed to enable core %d\n", core);115115+ }89116 }90117}911189292-void xlp_wakeup_secondary_cpus(void)119119+void xlp_wakeup_secondary_cpus()93120{94121 /*95122 * In case of u-boot, the secondaries are in reset···12598 xlp_boot_core0_siblings();12699127100 /* now get other cores out of reset */128128- xlp_enable_secondary_cores();101101+ xlp_enable_secondary_cores(&nlm_cpumask);129102}
···11+/*22+ * Copyright (c) 2003-2012 Broadcom Corporation33+ * All Rights Reserved44+ *55+ * This software is available to you under a choice of one of two66+ * licenses. You may choose to be licensed under the terms of the GNU77+ * General Public License (GPL) Version 2, available from the file88+ * COPYING in the main directory of this source tree, or the Broadcom99+ * license below:1010+ *1111+ * Redistribution and use in source and binary forms, with or without1212+ * modification, are permitted provided that the following conditions1313+ * are met:1414+ *1515+ * 1. Redistributions of source code must retain the above copyright1616+ * notice, this list of conditions and the following disclaimer.1717+ * 2. Redistributions in binary form must reproduce the above copyright1818+ * notice, this list of conditions and the following disclaimer in1919+ * the documentation and/or other materials provided with the2020+ * distribution.2121+ *2222+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR2323+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED2424+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE2525+ * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE2626+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR2727+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF2828+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR2929+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,3030+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE3131+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN3232+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3333+ */3434+3535+#include <asm/cpu-info.h>3636+#include <linux/irq.h>3737+#include <linux/interrupt.h>3838+3939+#include <asm/mipsregs.h>4040+#include <asm/netlogic/xlr/fmn.h>4141+#include <asm/netlogic/xlr/xlr.h>4242+#include <asm/netlogic/common.h>4343+#include <asm/netlogic/haldefs.h>4444+4545+struct xlr_board_fmn_config xlr_board_fmn_config;4646+4747+static void __maybe_unused print_credit_config(struct xlr_fmn_info *fmn_info)4848+{4949+ int bkt;5050+5151+ pr_info("Bucket size :\n");5252+ pr_info("Station\t: Size\n");5353+ for (bkt = 0; bkt < 16; bkt++)5454+ pr_info(" %d %d %d %d %d %d %d %d\n",5555+ xlr_board_fmn_config.bucket_size[(bkt * 8) + 0],5656+ xlr_board_fmn_config.bucket_size[(bkt * 8) + 1],5757+ xlr_board_fmn_config.bucket_size[(bkt * 8) + 2],5858+ xlr_board_fmn_config.bucket_size[(bkt * 8) + 3],5959+ xlr_board_fmn_config.bucket_size[(bkt * 8) + 4],6060+ xlr_board_fmn_config.bucket_size[(bkt * 8) + 5],6161+ xlr_board_fmn_config.bucket_size[(bkt * 8) + 6],6262+ xlr_board_fmn_config.bucket_size[(bkt * 8) + 7]);6363+ pr_info("\n");6464+6565+ pr_info("Credits distribution :\n");6666+ pr_info("Station\t: Size\n");6767+ for (bkt = 0; bkt < 16; bkt++)6868+ pr_info(" %d %d %d %d %d %d %d %d\n",6969+ fmn_info->credit_config[(bkt * 8) + 0],7070+ fmn_info->credit_config[(bkt * 8) + 1],7171+ fmn_info->credit_config[(bkt * 8) + 2],7272+ fmn_info->credit_config[(bkt * 8) + 3],7373+ fmn_info->credit_config[(bkt * 8) + 4],7474+ fmn_info->credit_config[(bkt * 8) + 5],7575+ fmn_info->credit_config[(bkt * 8) + 6],7676+ fmn_info->credit_config[(bkt * 8) + 7]);7777+ pr_info("\n");7878+}7979+8080+static void check_credit_distribution(void)8181+{8282+ struct xlr_board_fmn_config *cfg = &xlr_board_fmn_config;8383+ int bkt, n, total_credits, ncores;8484+8585+ ncores = hweight32(nlm_current_node()->coremask);8686+ for (bkt = 0; bkt < 128; bkt++) {8787+ total_credits = 0;8888+ for (n = 0; n < ncores; n++)8989+ total_credits += cfg->cpu[n].credit_config[bkt];9090+ total_credits += cfg->gmac[0].credit_config[bkt];9191+ total_credits += cfg->gmac[1].credit_config[bkt];9292+ total_credits += cfg->dma.credit_config[bkt];9393+ total_credits += cfg->cmp.credit_config[bkt];9494+ total_credits += cfg->sae.credit_config[bkt];9595+ total_credits += cfg->xgmac[0].credit_config[bkt];9696+ total_credits += cfg->xgmac[1].credit_config[bkt];9797+ if (total_credits > cfg->bucket_size[bkt])9898+ pr_err("ERROR: Bucket %d: credits (%d) > size (%d)\n",9999+ bkt, total_credits, cfg->bucket_size[bkt]);100100+ }101101+ pr_info("Credit distribution complete.\n");102102+}103103+104104+/**105105+ * Configure bucket size and credits for a device. 'size' is the size of106106+ * the buckets for the device. This size is distributed among all the CPUs107107+ * so that all of them can send messages to the device.108108+ *109109+ * The device is also given 'cpu_credits' to send messages to the CPUs110110+ *111111+ * @dev_info: FMN information structure for each devices112112+ * @start_stn_id: Starting station id of dev_info113113+ * @end_stn_id: End station id of dev_info114114+ * @num_buckets: Total number of buckets for den_info115115+ * @cpu_credits: Allowed credits to cpu for each devices pointing by dev_info116116+ * @size: Size of the each buckets in the device station117117+ */118118+static void setup_fmn_cc(struct xlr_fmn_info *dev_info, int start_stn_id,119119+ int end_stn_id, int num_buckets, int cpu_credits, int size)120120+{121121+ int i, j, num_core, n, credits_per_cpu;122122+ struct xlr_fmn_info *cpu = xlr_board_fmn_config.cpu;123123+124124+ num_core = hweight32(nlm_current_node()->coremask);125125+ dev_info->num_buckets = num_buckets;126126+ dev_info->start_stn_id = start_stn_id;127127+ dev_info->end_stn_id = end_stn_id;128128+129129+ n = num_core;130130+ if (num_core == 3)131131+ n = 4;132132+133133+ for (i = start_stn_id; i <= end_stn_id; i++) {134134+ xlr_board_fmn_config.bucket_size[i] = size;135135+136136+ /* Dividing device credits equally to cpus */137137+ credits_per_cpu = size / n;138138+ for (j = 0; j < num_core; j++)139139+ cpu[j].credit_config[i] = credits_per_cpu;140140+141141+ /* credits left to distribute */142142+ credits_per_cpu = size - (credits_per_cpu * num_core);143143+144144+ /* distribute the remaining credits (if any), among cores */145145+ for (j = 0; (j < num_core) && (credits_per_cpu >= 4); j++) {146146+ cpu[j].credit_config[i] += 4;147147+ credits_per_cpu -= 4;148148+ }149149+ }150150+151151+ /* Distributing cpu per bucket credits to devices */152152+ for (i = 0; i < num_core; i++) {153153+ for (j = 0; j < FMN_CORE_NBUCKETS; j++)154154+ dev_info->credit_config[(i * 8) + j] = cpu_credits;155155+ }156156+}157157+158158+/*159159+ * Each core has 256 slots and 8 buckets,160160+ * Configure the 8 buckets each with 32 slots161161+ */162162+static void setup_cpu_fmninfo(struct xlr_fmn_info *cpu, int num_core)163163+{164164+ int i, j;165165+166166+ for (i = 0; i < num_core; i++) {167167+ cpu[i].start_stn_id = (8 * i);168168+ cpu[i].end_stn_id = (8 * i + 8);169169+170170+ for (j = cpu[i].start_stn_id; j < cpu[i].end_stn_id; j++)171171+ xlr_board_fmn_config.bucket_size[j] = 32;172172+ }173173+}174174+175175+/**176176+ * Setup the FMN details for each devices according to the device available177177+ * in each variant of XLR/XLS processor178178+ */179179+void xlr_board_info_setup(void)180180+{181181+ struct xlr_fmn_info *cpu = xlr_board_fmn_config.cpu;182182+ struct xlr_fmn_info *gmac = xlr_board_fmn_config.gmac;183183+ struct xlr_fmn_info *xgmac = xlr_board_fmn_config.xgmac;184184+ struct xlr_fmn_info *dma = &xlr_board_fmn_config.dma;185185+ struct xlr_fmn_info *cmp = &xlr_board_fmn_config.cmp;186186+ struct xlr_fmn_info *sae = &xlr_board_fmn_config.sae;187187+ int processor_id, num_core;188188+189189+ num_core = hweight32(nlm_current_node()->coremask);190190+ processor_id = read_c0_prid() & 0xff00;191191+192192+ setup_cpu_fmninfo(cpu, num_core);193193+ switch (processor_id) {194194+ case PRID_IMP_NETLOGIC_XLS104:195195+ case PRID_IMP_NETLOGIC_XLS108:196196+ setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,197197+ FMN_STNID_GMAC0_TX3, 8, 16, 32);198198+ setup_fmn_cc(dma, FMN_STNID_DMA_0,199199+ FMN_STNID_DMA_3, 4, 8, 64);200200+ setup_fmn_cc(sae, FMN_STNID_SEC0,201201+ FMN_STNID_SEC1, 2, 8, 128);202202+ break;203203+204204+ case PRID_IMP_NETLOGIC_XLS204:205205+ case PRID_IMP_NETLOGIC_XLS208:206206+ setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,207207+ FMN_STNID_GMAC0_TX3, 8, 16, 32);208208+ setup_fmn_cc(dma, FMN_STNID_DMA_0,209209+ FMN_STNID_DMA_3, 4, 8, 64);210210+ setup_fmn_cc(sae, FMN_STNID_SEC0,211211+ FMN_STNID_SEC1, 2, 8, 128);212212+ break;213213+214214+ case PRID_IMP_NETLOGIC_XLS404:215215+ case PRID_IMP_NETLOGIC_XLS408:216216+ case PRID_IMP_NETLOGIC_XLS404B:217217+ case PRID_IMP_NETLOGIC_XLS408B:218218+ case PRID_IMP_NETLOGIC_XLS416B:219219+ setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,220220+ FMN_STNID_GMAC0_TX3, 8, 8, 32);221221+ setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0,222222+ FMN_STNID_GMAC1_TX3, 8, 8, 32);223223+ setup_fmn_cc(dma, FMN_STNID_DMA_0,224224+ FMN_STNID_DMA_3, 4, 4, 64);225225+ setup_fmn_cc(cmp, FMN_STNID_CMP_0,226226+ FMN_STNID_CMP_3, 4, 4, 64);227227+ setup_fmn_cc(sae, FMN_STNID_SEC0,228228+ FMN_STNID_SEC1, 2, 8, 128);229229+ break;230230+231231+ case PRID_IMP_NETLOGIC_XLS412B:232232+ setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,233233+ FMN_STNID_GMAC0_TX3, 8, 8, 32);234234+ setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0,235235+ FMN_STNID_GMAC1_TX3, 8, 8, 32);236236+ setup_fmn_cc(dma, FMN_STNID_DMA_0,237237+ FMN_STNID_DMA_3, 4, 4, 64);238238+ setup_fmn_cc(cmp, FMN_STNID_CMP_0,239239+ FMN_STNID_CMP_3, 4, 4, 64);240240+ setup_fmn_cc(sae, FMN_STNID_SEC0,241241+ FMN_STNID_SEC1, 2, 8, 128);242242+ break;243243+244244+ case PRID_IMP_NETLOGIC_XLR308:245245+ case PRID_IMP_NETLOGIC_XLR308C:246246+ setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,247247+ FMN_STNID_GMAC0_TX3, 8, 16, 32);248248+ setup_fmn_cc(dma, FMN_STNID_DMA_0,249249+ FMN_STNID_DMA_3, 4, 8, 64);250250+ setup_fmn_cc(sae, FMN_STNID_SEC0,251251+ FMN_STNID_SEC1, 2, 4, 128);252252+ break;253253+254254+ case PRID_IMP_NETLOGIC_XLR532:255255+ case PRID_IMP_NETLOGIC_XLR532C:256256+ case PRID_IMP_NETLOGIC_XLR516C:257257+ case PRID_IMP_NETLOGIC_XLR508C:258258+ setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,259259+ FMN_STNID_GMAC0_TX3, 8, 16, 32);260260+ setup_fmn_cc(dma, FMN_STNID_DMA_0,261261+ FMN_STNID_DMA_3, 4, 8, 64);262262+ setup_fmn_cc(sae, FMN_STNID_SEC0,263263+ FMN_STNID_SEC1, 2, 4, 128);264264+ break;265265+266266+ case PRID_IMP_NETLOGIC_XLR732:267267+ case PRID_IMP_NETLOGIC_XLR716:268268+ setup_fmn_cc(&xgmac[0], FMN_STNID_XMAC0_00_TX,269269+ FMN_STNID_XMAC0_15_TX, 8, 0, 32);270270+ setup_fmn_cc(&xgmac[1], FMN_STNID_XMAC1_00_TX,271271+ FMN_STNID_XMAC1_15_TX, 8, 0, 32);272272+ setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,273273+ FMN_STNID_GMAC0_TX3, 8, 24, 32);274274+ setup_fmn_cc(dma, FMN_STNID_DMA_0,275275+ FMN_STNID_DMA_3, 4, 4, 64);276276+ setup_fmn_cc(sae, FMN_STNID_SEC0,277277+ FMN_STNID_SEC1, 2, 4, 128);278278+ break;279279+ default:280280+ pr_err("Unknown CPU with processor ID [%d]\n", processor_id);281281+ pr_err("Error: Cannot initialize FMN credits.\n");282282+ }283283+284284+ check_credit_distribution();285285+286286+#if 0 /* debug */287287+ print_credit_config(&cpu[0]);288288+ print_credit_config(&gmac[0]);289289+#endif290290+}
+204
arch/mips/netlogic/xlr/fmn.c
···11+/*22+ * Copyright (c) 2003-2012 Broadcom Corporation33+ * All Rights Reserved44+ *55+ * This software is available to you under a choice of one of two66+ * licenses. You may choose to be licensed under the terms of the GNU77+ * General Public License (GPL) Version 2, available from the file88+ * COPYING in the main directory of this source tree, or the Broadcom99+ * license below:1010+ *1111+ * Redistribution and use in source and binary forms, with or without1212+ * modification, are permitted provided that the following conditions1313+ * are met:1414+ *1515+ * 1. Redistributions of source code must retain the above copyright1616+ * notice, this list of conditions and the following disclaimer.1717+ * 2. Redistributions in binary form must reproduce the above copyright1818+ * notice, this list of conditions and the following disclaimer in1919+ * the documentation and/or other materials provided with the2020+ * distribution.2121+ *2222+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR2323+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED2424+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE2525+ * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE2626+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR2727+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF2828+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR2929+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,3030+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE3131+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN3232+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3333+ */3434+3535+#include <linux/kernel.h>3636+#include <linux/irqreturn.h>3737+#include <linux/irq.h>3838+#include <linux/interrupt.h>3939+4040+#include <asm/mipsregs.h>4141+#include <asm/netlogic/interrupt.h>4242+#include <asm/netlogic/xlr/fmn.h>4343+#include <asm/netlogic/common.h>4444+4545+#define COP2_CC_INIT_CPU_DEST(dest, conf) \4646+do { \4747+ nlm_write_c2_cc##dest(0, conf[(dest * 8) + 0]); \4848+ nlm_write_c2_cc##dest(1, conf[(dest * 8) + 1]); \4949+ nlm_write_c2_cc##dest(2, conf[(dest * 8) + 2]); \5050+ nlm_write_c2_cc##dest(3, conf[(dest * 8) + 3]); \5151+ nlm_write_c2_cc##dest(4, conf[(dest * 8) + 4]); \5252+ nlm_write_c2_cc##dest(5, conf[(dest * 8) + 5]); \5353+ nlm_write_c2_cc##dest(6, conf[(dest * 8) + 6]); \5454+ nlm_write_c2_cc##dest(7, conf[(dest * 8) + 7]); \5555+} while (0)5656+5757+struct fmn_message_handler {5858+ void (*action)(int, int, int, int, struct nlm_fmn_msg *, void *);5959+ void *arg;6060+} msg_handlers[128];6161+6262+/*6363+ * FMN interrupt handler. We configure the FMN so that any messages in6464+ * any of the CPU buckets will trigger an interrupt on the CPU.6565+ * The message can be from any device on the FMN (like NAE/SAE/DMA).6666+ * The source station id is used to figure out which of the registered6767+ * handlers have to be called.6868+ */6969+static irqreturn_t fmn_message_handler(int irq, void *data)7070+{7171+ struct fmn_message_handler *hndlr;7272+ int bucket, rv;7373+ int size = 0, code = 0, src_stnid = 0;7474+ struct nlm_fmn_msg msg;7575+ uint32_t mflags, bkt_status;7676+7777+ mflags = nlm_cop2_enable();7878+ /* Disable message ring interrupt */7979+ nlm_fmn_setup_intr(irq, 0);8080+ while (1) {8181+ /* 8 bkts per core, [24:31] each bit represents one bucket8282+ * Bit is Zero if bucket is not empty */8383+ bkt_status = (nlm_read_c2_status() >> 24) & 0xff;8484+ if (bkt_status == 0xff)8585+ break;8686+ for (bucket = 0; bucket < 8; bucket++) {8787+ /* Continue on empty bucket */8888+ if (bkt_status & (1 << bucket))8989+ continue;9090+ rv = nlm_fmn_receive(bucket, &size, &code, &src_stnid,9191+ &msg);9292+ if (rv != 0)9393+ continue;9494+9595+ hndlr = &msg_handlers[src_stnid];9696+ if (hndlr->action == NULL)9797+ pr_warn("No msgring handler for stnid %d\n",9898+ src_stnid);9999+ else {100100+ nlm_cop2_restore(mflags);101101+ hndlr->action(bucket, src_stnid, size, code,102102+ &msg, hndlr->arg);103103+ mflags = nlm_cop2_enable();104104+ }105105+ }106106+ };107107+ /* Enable message ring intr, to any thread in core */108108+ nlm_fmn_setup_intr(irq, (1 << nlm_threads_per_core) - 1);109109+ nlm_cop2_restore(mflags);110110+ return IRQ_HANDLED;111111+}112112+113113+struct irqaction fmn_irqaction = {114114+ .handler = fmn_message_handler,115115+ .flags = IRQF_PERCPU,116116+ .name = "fmn",117117+};118118+119119+void xlr_percpu_fmn_init(void)120120+{121121+ struct xlr_fmn_info *cpu_fmn_info;122122+ int *bucket_sizes;123123+ uint32_t flags;124124+ int id;125125+126126+ BUG_ON(nlm_thread_id() != 0);127127+ id = nlm_core_id();128128+129129+ bucket_sizes = xlr_board_fmn_config.bucket_size;130130+ cpu_fmn_info = &xlr_board_fmn_config.cpu[id];131131+ flags = nlm_cop2_enable();132132+133133+ /* Setup bucket sizes for the core. */134134+ nlm_write_c2_bucksize(0, bucket_sizes[id * 8 + 0]);135135+ nlm_write_c2_bucksize(1, bucket_sizes[id * 8 + 1]);136136+ nlm_write_c2_bucksize(2, bucket_sizes[id * 8 + 2]);137137+ nlm_write_c2_bucksize(3, bucket_sizes[id * 8 + 3]);138138+ nlm_write_c2_bucksize(4, bucket_sizes[id * 8 + 4]);139139+ nlm_write_c2_bucksize(5, bucket_sizes[id * 8 + 5]);140140+ nlm_write_c2_bucksize(6, bucket_sizes[id * 8 + 6]);141141+ nlm_write_c2_bucksize(7, bucket_sizes[id * 8 + 7]);142142+143143+ /*144144+ * For sending FMN messages, we need credits on the destination145145+ * bucket. Program the credits this core has on the 128 possible146146+ * destination buckets.147147+ * We cannot use a loop here, because the the first argument has148148+ * to be a constant integer value.149149+ */150150+ COP2_CC_INIT_CPU_DEST(0, cpu_fmn_info->credit_config);151151+ COP2_CC_INIT_CPU_DEST(1, cpu_fmn_info->credit_config);152152+ COP2_CC_INIT_CPU_DEST(2, cpu_fmn_info->credit_config);153153+ COP2_CC_INIT_CPU_DEST(3, cpu_fmn_info->credit_config);154154+ COP2_CC_INIT_CPU_DEST(4, cpu_fmn_info->credit_config);155155+ COP2_CC_INIT_CPU_DEST(5, cpu_fmn_info->credit_config);156156+ COP2_CC_INIT_CPU_DEST(6, cpu_fmn_info->credit_config);157157+ COP2_CC_INIT_CPU_DEST(7, cpu_fmn_info->credit_config);158158+ COP2_CC_INIT_CPU_DEST(8, cpu_fmn_info->credit_config);159159+ COP2_CC_INIT_CPU_DEST(9, cpu_fmn_info->credit_config);160160+ COP2_CC_INIT_CPU_DEST(10, cpu_fmn_info->credit_config);161161+ COP2_CC_INIT_CPU_DEST(11, cpu_fmn_info->credit_config);162162+ COP2_CC_INIT_CPU_DEST(12, cpu_fmn_info->credit_config);163163+ COP2_CC_INIT_CPU_DEST(13, cpu_fmn_info->credit_config);164164+ COP2_CC_INIT_CPU_DEST(14, cpu_fmn_info->credit_config);165165+ COP2_CC_INIT_CPU_DEST(15, cpu_fmn_info->credit_config);166166+167167+ /* enable FMN interrupts on this CPU */168168+ nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1);169169+ nlm_cop2_restore(flags);170170+}171171+172172+173173+/*174174+ * Register a FMN message handler with respect to the source station id175175+ * @stnid: source station id176176+ * @action: Handler function pointer177177+ */178178+int nlm_register_fmn_handler(int start_stnid, int end_stnid,179179+ void (*action)(int, int, int, int, struct nlm_fmn_msg *, void *),180180+ void *arg)181181+{182182+ int sstnid;183183+184184+ for (sstnid = start_stnid; sstnid <= end_stnid; sstnid++) {185185+ msg_handlers[sstnid].arg = arg;186186+ smp_wmb();187187+ msg_handlers[sstnid].action = action;188188+ }189189+ pr_debug("Registered FMN msg handler for stnid %d-%d\n",190190+ start_stnid, end_stnid);191191+ return 0;192192+}193193+194194+void nlm_setup_fmn_irq(void)195195+{196196+ uint32_t flags;197197+198198+ /* setup irq only once */199199+ setup_irq(IRQ_FMN, &fmn_irqaction);200200+201201+ flags = nlm_cop2_enable();202202+ nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1);203203+ nlm_cop2_restore(flags);204204+}
+28-9
arch/mips/netlogic/xlr/setup.c
···4949#include <asm/netlogic/xlr/iomap.h>5050#include <asm/netlogic/xlr/pic.h>5151#include <asm/netlogic/xlr/gpio.h>5252+#include <asm/netlogic/xlr/fmn.h>52535354uint64_t nlm_io_base = DEFAULT_NETLOGIC_IO_BASE;5454-uint64_t nlm_pic_base;5555struct psb_info nlm_prom_info;56565757-unsigned long nlm_common_ebase = 0x0;5858-5957/* default to uniprocessor */6060-uint32_t nlm_coremask = 1, nlm_cpumask = 1;6161-int nlm_threads_per_core = 1;5858+unsigned int nlm_threads_per_core = 1;5959+struct nlm_soc_info nlm_nodes[NLM_NR_NODES];6060+cpumask_t nlm_cpumask = CPU_MASK_CPU0;62616362static void __init nlm_early_serial_setup(void)6463{···110111void __init prom_free_prom_memory(void)111112{112113 /* Nothing yet */114114+}115115+116116+void nlm_percpu_init(int hwcpuid)117117+{118118+ if (hwcpuid % 4 == 0)119119+ xlr_percpu_fmn_init();113120}114121115122static void __init build_arcs_cmdline(int *argv)···181176 }182177}183178179179+static void nlm_init_node(void)180180+{181181+ struct nlm_soc_info *nodep;182182+183183+ nodep = nlm_current_node();184184+ nodep->picbase = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET);185185+ nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1));186186+ spin_lock_init(&nodep->piclock);187187+}188188+184189void __init prom_init(void)185190{186186- int *argv, *envp; /* passed as 32 bit ptrs */191191+ int i, *argv, *envp; /* passed as 32 bit ptrs */187192 struct psb_info *prom_infop;188193189194 /* truncate to 32 bit and sign extend all args */···202187 prom_infop = (struct psb_info *)(long)(int)fw_arg3;203188204189 nlm_prom_info = *prom_infop;205205- nlm_pic_base = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET);190190+ nlm_init_node();206191207192 nlm_early_serial_setup();208193 build_arcs_cmdline(argv);209209- nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));210194 prom_add_memory();211195212196#ifdef CONFIG_SMP213213- nlm_wakeup_secondary_cpus(nlm_prom_info.online_cpu_map);197197+ for (i = 0; i < 32; i++)198198+ if (nlm_prom_info.online_cpu_map & (1 << i))199199+ cpumask_set_cpu(i, &nlm_cpumask);200200+ nlm_wakeup_secondary_cpus();214201 register_smp_ops(&nlm_smp_ops);215202#endif203203+ xlr_board_info_setup();204204+ xlr_percpu_fmn_init();216205}
+20-3
arch/mips/netlogic/xlr/wakeup.c
···3333 */34343535#include <linux/init.h>3636+#include <linux/delay.h>3637#include <linux/threads.h>37383839#include <asm/asm.h>···51505251int __cpuinit xlr_wakeup_secondary_cpus(void)5352{5454- unsigned int i, boot_cpu;5353+ struct nlm_soc_info *nodep;5454+ unsigned int i, j, boot_cpu;55555656 /*5757 * In case of RMI boot, hit with NMI to get the cores5858 * from bootloader to linux code.5959 */6060+ nodep = nlm_get_node(0);6061 boot_cpu = hard_smp_processor_id();6162 nlm_set_nmi_handler(nlm_rmiboot_preboot);6263 for (i = 0; i < NR_CPUS; i++) {6363- if (i == boot_cpu || (nlm_cpumask & (1u << i)) == 0)6464+ if (i == boot_cpu || !cpumask_test_cpu(i, &nlm_cpumask))6465 continue;6565- nlm_pic_send_ipi(nlm_pic_base, i, 1, 1); /* send NMI */6666+ nlm_pic_send_ipi(nodep->picbase, i, 1, 1); /* send NMI */6767+ }6868+6969+ /* Fill up the coremask early */7070+ nodep->coremask = 1;7171+ for (i = 1; i < NLM_CORES_PER_NODE; i++) {7272+ for (j = 1000000; j > 0; j--) {7373+ if (nlm_cpu_ready[i * NLM_THREADS_PER_CORE])7474+ break;7575+ udelay(10);7676+ }7777+ if (j != 0)7878+ nodep->coremask |= (1u << i);7979+ else8080+ pr_err("Failed to wakeup core %d\n", i);6681 }67826883 return 0;
···9090 case CPU_R10000:9191 case CPU_R12000:9292 case CPU_R14000:9393+ case CPU_XLR:9394 lmodel = &op_model_mipsxx_ops;9495 break;9596
+29
arch/mips/oprofile/op_model_mipsxx.c
···31313232#define M_COUNTER_OVERFLOW (1UL << 31)33333434+/* Netlogic XLR specific, count events in all threads in a core */3535+#define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13)3636+3437static int (*save_perf_irq)(void);3838+3939+/*4040+ * XLR has only one set of counters per core. Designate the4141+ * first hardware thread in the core for setup and init.4242+ * Skip CPUs with non-zero hardware thread id (4 hwt per core)4343+ */4444+#ifdef CONFIG_CPU_XLR4545+#define oprofile_skip_cpu(c) ((cpu_logical_map(c) & 0x3) != 0)4646+#else4747+#define oprofile_skip_cpu(c) 04848+#endif35493650#ifdef CONFIG_MIPS_MT_SMP3751static int cpu_has_mipsmt_pertccounters;···166152 reg.control[i] |= M_PERFCTL_USER;167153 if (ctr[i].exl)168154 reg.control[i] |= M_PERFCTL_EXL;155155+ if (current_cpu_type() == CPU_XLR)156156+ reg.control[i] |= M_PERFCTL_COUNT_ALL_THREADS;169157 reg.counter[i] = 0x80000000 - ctr[i].count;170158 }171159}···177161static void mipsxx_cpu_setup(void *args)178162{179163 unsigned int counters = op_model_mipsxx_ops.num_counters;164164+165165+ if (oprofile_skip_cpu(smp_processor_id()))166166+ return;180167181168 switch (counters) {182169 case 4:···202183{203184 unsigned int counters = op_model_mipsxx_ops.num_counters;204185186186+ if (oprofile_skip_cpu(smp_processor_id()))187187+ return;188188+205189 switch (counters) {206190 case 4:207191 w_c0_perfctrl3(WHAT | reg.control[3]);···221199static void mipsxx_cpu_stop(void *args)222200{223201 unsigned int counters = op_model_mipsxx_ops.num_counters;202202+203203+ if (oprofile_skip_cpu(smp_processor_id()))204204+ return;224205225206 switch (counters) {226207 case 4:···395370396371 case CPU_LOONGSON1:397372 op_model_mipsxx_ops.cpu_type = "mips/loongson1";373373+ break;374374+375375+ case CPU_XLR:376376+ op_model_mipsxx_ops.cpu_type = "mips/xlr";398377 break;399378400379 default:
+16-18
arch/mips/pci/pci-bcm63xx.c
···1111#include <linux/kernel.h>1212#include <linux/init.h>1313#include <linux/delay.h>1414+#include <linux/clk.h>1415#include <asm/bootinfo.h>1616+1717+#include <bcm63xx_reset.h>15181619#include "pci-bcm63xx.h"1720···122119{123120 u32 val;124121125125- /* enable clock */126126- val = bcm_perf_readl(PERF_CKCTL_REG);127127- val |= CKCTL_6328_PCIE_EN;128128- bcm_perf_writel(val, PERF_CKCTL_REG);129129-130122 /* enable SERDES */131123 val = bcm_misc_readl(MISC_SERDES_CTRL_REG);132124 val |= SERDES_PCIE_EN | SERDES_PCIE_EXD_EN;133125 bcm_misc_writel(val, MISC_SERDES_CTRL_REG);134126135127 /* reset the PCIe core */136136- val = bcm_perf_readl(PERF_SOFTRESET_6328_REG);137137-138138- val &= ~SOFTRESET_6328_PCIE_MASK;139139- val &= ~SOFTRESET_6328_PCIE_CORE_MASK;140140- val &= ~SOFTRESET_6328_PCIE_HARD_MASK;141141- val &= ~SOFTRESET_6328_PCIE_EXT_MASK;142142- bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);128128+ bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 1);129129+ bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 1);143130 mdelay(10);144131145145- val |= SOFTRESET_6328_PCIE_MASK;146146- val |= SOFTRESET_6328_PCIE_CORE_MASK;147147- val |= SOFTRESET_6328_PCIE_HARD_MASK;148148- bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);132132+ bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 0);149133 mdelay(10);150134151151- val |= SOFTRESET_6328_PCIE_EXT_MASK;152152- bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);135135+ bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 0);153136 mdelay(200);154137}138138+139139+static struct clk *pcie_clk;155140156141static int __init bcm63xx_register_pcie(void)157142{158143 u32 val;144144+145145+ /* enable clock */146146+ pcie_clk = clk_get(NULL, "pcie");147147+ if (IS_ERR_OR_NULL(pcie_clk))148148+ return -ENODEV;149149+150150+ clk_prepare_enable(pcie_clk);159151160152 bcm63xx_reset_pcie();161153
+34-35
arch/mips/pci/pci-xlr.c
···47474848#include <asm/netlogic/interrupt.h>4949#include <asm/netlogic/haldefs.h>5050+#include <asm/netlogic/common.h>50515152#include <asm/netlogic/xlr/msidef.h>5253#include <asm/netlogic/xlr/iomap.h>···175174 return p ? bus->self : NULL;176175}177176178178-static int get_irq_vector(const struct pci_dev *dev)177177+static int nlm_pci_link_to_irq(int link)179178{180180- struct pci_dev *lnk;181181-182182- if (!nlm_chip_is_xls())183183- return PIC_PCIX_IRQ; /* for XLR just one IRQ */184184-185185- /*186186- * For XLS PCIe, there is an IRQ per Link, find out which187187- * link the device is on to assign interrupts188188- */189189- lnk = xls_get_pcie_link(dev);190190- if (lnk == NULL)191191- return 0;192192-193193- switch (PCI_SLOT(lnk->devfn)) {179179+ switch (link) {194180 case 0:195181 return PIC_PCIE_LINK0_IRQ;196182 case 1:···193205 else194206 return PIC_PCIE_LINK3_IRQ;195207 }196196- WARN(1, "Unexpected devfn %d\n", lnk->devfn);208208+ WARN(1, "Unexpected link %d\n", link);197209 return 0;210210+}211211+212212+static int get_irq_vector(const struct pci_dev *dev)213213+{214214+ struct pci_dev *lnk;215215+ int link;216216+217217+ if (!nlm_chip_is_xls())218218+ return PIC_PCIX_IRQ; /* for XLR just one IRQ */219219+220220+ lnk = xls_get_pcie_link(dev);221221+ if (lnk == NULL)222222+ return 0;223223+224224+ link = PCI_SLOT(lnk->devfn);225225+ return nlm_pci_link_to_irq(link);198226}199227200228#ifdef CONFIG_PCI_MSI···336332337333static int __init pcibios_init(void)338334{335335+ void (*extra_ack)(struct irq_data *);336336+ int link, irq;337337+339338 /* PSB assigns PCI resources */340339 pci_set_flags(PCI_PROBE_ONLY);341340 pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20);···357350 * For PCI interrupts, we need to ack the PCI controller too, overload358351 * irq handler data to do this359352 */360360- if (nlm_chip_is_xls()) {361361- if (nlm_chip_is_xls_b()) {362362- irq_set_handler_data(PIC_PCIE_LINK0_IRQ,363363- xls_pcie_ack_b);364364- irq_set_handler_data(PIC_PCIE_LINK1_IRQ,365365- xls_pcie_ack_b);366366- irq_set_handler_data(PIC_PCIE_XLSB0_LINK2_IRQ,367367- xls_pcie_ack_b);368368- irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ,369369- xls_pcie_ack_b);370370- } else {371371- irq_set_handler_data(PIC_PCIE_LINK0_IRQ, xls_pcie_ack);372372- irq_set_handler_data(PIC_PCIE_LINK1_IRQ, xls_pcie_ack);373373- irq_set_handler_data(PIC_PCIE_LINK2_IRQ, xls_pcie_ack);374374- irq_set_handler_data(PIC_PCIE_LINK3_IRQ, xls_pcie_ack);375375- }376376- } else {353353+ if (!nlm_chip_is_xls()) {377354 /* XLR PCI controller ACK */378378- irq_set_handler_data(PIC_PCIX_IRQ, xlr_pci_ack);355355+ nlm_set_pic_extra_ack(0, PIC_PCIX_IRQ, xlr_pci_ack);356356+ } else {357357+ if (nlm_chip_is_xls_b())358358+ extra_ack = xls_pcie_ack_b;359359+ else360360+ extra_ack = xls_pcie_ack;361361+ for (link = 0; link < 4; link++) {362362+ irq = nlm_pci_link_to_irq(link);363363+ nlm_set_pic_extra_ack(0, irq, extra_ack);364364+ }379365 }380380-381366 return 0;382367}383368
+9
drivers/bcma/Kconfig
···65656666 If unsure, say N67676868+config BCMA_DRIVER_GPIO6969+ bool "BCMA GPIO driver"7070+ depends on BCMA7171+ select GPIOLIB7272+ help7373+ Driver to provide access to the GPIO pins of the bcma bus.7474+7575+ If unsure, say N7676+6877config BCMA_DEBUG6978 bool "BCMA debugging"7079 depends on BCMA
···160160161161 If unsure, say N162162163163+config SSB_DRIVER_GPIO164164+ bool "SSB GPIO driver"165165+ depends on SSB166166+ select GPIOLIB167167+ help168168+ Driver to provide access to the GPIO pins on the bus.169169+170170+ If unsure, say N171171+163172endmenu
+1
drivers/ssb/Makefile
···1515ssb-$(CONFIG_SSB_DRIVER_EXTIF) += driver_extif.o1616ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o1717ssb-$(CONFIG_SSB_DRIVER_GIGE) += driver_gige.o1818+ssb-$(CONFIG_SSB_DRIVER_GPIO) += driver_gpio.o18191920# b43 pci-ssb-bridge driver2021# Not strictly a part of SSB, but kept here for convenience
+73-5
drivers/ssb/driver_chipcommon.c
···284284{285285 if (!cc->dev)286286 return; /* We don't have a ChipCommon */287287+288288+ spin_lock_init(&cc->gpio_lock);289289+287290 if (cc->dev->id.revision >= 11)288291 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);289292 ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);···421418422419u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value)423420{424424- return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);421421+ unsigned long flags;422422+ u32 res = 0;423423+424424+ spin_lock_irqsave(&cc->gpio_lock, flags);425425+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);426426+ spin_unlock_irqrestore(&cc->gpio_lock, flags);427427+428428+ return res;425429}426430427431u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value)428432{429429- return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);433433+ unsigned long flags;434434+ u32 res = 0;435435+436436+ spin_lock_irqsave(&cc->gpio_lock, flags);437437+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);438438+ spin_unlock_irqrestore(&cc->gpio_lock, flags);439439+440440+ return res;430441}431442432443u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value)433444{434434- return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);445445+ unsigned long flags;446446+ u32 res = 0;447447+448448+ spin_lock_irqsave(&cc->gpio_lock, flags);449449+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);450450+ spin_unlock_irqrestore(&cc->gpio_lock, flags);451451+452452+ return res;435453}436454EXPORT_SYMBOL(ssb_chipco_gpio_control);437455438456u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value)439457{440440- return chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value);458458+ unsigned long flags;459459+ u32 res = 0;460460+461461+ spin_lock_irqsave(&cc->gpio_lock, flags);462462+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value);463463+ spin_unlock_irqrestore(&cc->gpio_lock, flags);464464+465465+ return res;441466}442467443468u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value)444469{445445- return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value);470470+ unsigned long flags;471471+ u32 res = 0;472472+473473+ spin_lock_irqsave(&cc->gpio_lock, flags);474474+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value);475475+ spin_unlock_irqrestore(&cc->gpio_lock, flags);476476+477477+ return res;478478+}479479+480480+u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value)481481+{482482+ unsigned long flags;483483+ u32 res = 0;484484+485485+ if (cc->dev->id.revision < 20)486486+ return 0xffffffff;487487+488488+ spin_lock_irqsave(&cc->gpio_lock, flags);489489+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLUP, mask, value);490490+ spin_unlock_irqrestore(&cc->gpio_lock, flags);491491+492492+ return res;493493+}494494+495495+u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value)496496+{497497+ unsigned long flags;498498+ u32 res = 0;499499+500500+ if (cc->dev->id.revision < 20)501501+ return 0xffffffff;502502+503503+ spin_lock_irqsave(&cc->gpio_lock, flags);504504+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLDOWN, mask, value);505505+ spin_unlock_irqrestore(&cc->gpio_lock, flags);506506+507507+ return res;446508}447509448510#ifdef CONFIG_SSB_SERIAL
+39-4
drivers/ssb/driver_extif.c
···118118 extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks);119119}120120121121+void ssb_extif_init(struct ssb_extif *extif)122122+{123123+ if (!extif->dev)124124+ return; /* We don't have a Extif core */125125+ spin_lock_init(&extif->gpio_lock);126126+}127127+121128u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)122129{123130 return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask;···132125133126u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value)134127{135135- return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),128128+ unsigned long flags;129129+ u32 res = 0;130130+131131+ spin_lock_irqsave(&extif->gpio_lock, flags);132132+ res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),136133 mask, value);134134+ spin_unlock_irqrestore(&extif->gpio_lock, flags);135135+136136+ return res;137137}138138139139u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value)140140{141141- return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),141141+ unsigned long flags;142142+ u32 res = 0;143143+144144+ spin_lock_irqsave(&extif->gpio_lock, flags);145145+ res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),142146 mask, value);147147+ spin_unlock_irqrestore(&extif->gpio_lock, flags);148148+149149+ return res;143150}144151145152u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value)146153{147147- return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);154154+ unsigned long flags;155155+ u32 res = 0;156156+157157+ spin_lock_irqsave(&extif->gpio_lock, flags);158158+ res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);159159+ spin_unlock_irqrestore(&extif->gpio_lock, flags);160160+161161+ return res;148162}149163150164u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value)151165{152152- return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);166166+ unsigned long flags;167167+ u32 res = 0;168168+169169+ spin_lock_irqsave(&extif->gpio_lock, flags);170170+ res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);171171+ spin_unlock_irqrestore(&extif->gpio_lock, flags);172172+173173+ return res;153174}
+176
drivers/ssb/driver_gpio.c
···11+/*22+ * Sonics Silicon Backplane33+ * GPIO driver44+ *55+ * Copyright 2011, Broadcom Corporation66+ * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>77+ *88+ * Licensed under the GNU/GPL. See COPYING for details.99+ */1010+1111+#include <linux/gpio.h>1212+#include <linux/export.h>1313+#include <linux/ssb/ssb.h>1414+1515+#include "ssb_private.h"1616+1717+static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip)1818+{1919+ return container_of(chip, struct ssb_bus, gpio);2020+}2121+2222+static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio)2323+{2424+ struct ssb_bus *bus = ssb_gpio_get_bus(chip);2525+2626+ return !!ssb_chipco_gpio_in(&bus->chipco, 1 << gpio);2727+}2828+2929+static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned gpio,3030+ int value)3131+{3232+ struct ssb_bus *bus = ssb_gpio_get_bus(chip);3333+3434+ ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0);3535+}3636+3737+static int ssb_gpio_chipco_direction_input(struct gpio_chip *chip,3838+ unsigned gpio)3939+{4040+ struct ssb_bus *bus = ssb_gpio_get_bus(chip);4141+4242+ ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 0);4343+ return 0;4444+}4545+4646+static int ssb_gpio_chipco_direction_output(struct gpio_chip *chip,4747+ unsigned gpio, int value)4848+{4949+ struct ssb_bus *bus = ssb_gpio_get_bus(chip);5050+5151+ ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 1 << gpio);5252+ ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0);5353+ return 0;5454+}5555+5656+static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned gpio)5757+{5858+ struct ssb_bus *bus = ssb_gpio_get_bus(chip);5959+6060+ ssb_chipco_gpio_control(&bus->chipco, 1 << gpio, 0);6161+ /* clear pulldown */6262+ ssb_chipco_gpio_pulldown(&bus->chipco, 1 << gpio, 0);6363+ /* Set pullup */6464+ ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 1 << gpio);6565+6666+ return 0;6767+}6868+6969+static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio)7070+{7171+ struct ssb_bus *bus = ssb_gpio_get_bus(chip);7272+7373+ /* clear pullup */7474+ ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0);7575+}7676+7777+static int ssb_gpio_chipco_init(struct ssb_bus *bus)7878+{7979+ struct gpio_chip *chip = &bus->gpio;8080+8181+ chip->label = "ssb_chipco_gpio";8282+ chip->owner = THIS_MODULE;8383+ chip->request = ssb_gpio_chipco_request;8484+ chip->free = ssb_gpio_chipco_free;8585+ chip->get = ssb_gpio_chipco_get_value;8686+ chip->set = ssb_gpio_chipco_set_value;8787+ chip->direction_input = ssb_gpio_chipco_direction_input;8888+ chip->direction_output = ssb_gpio_chipco_direction_output;8989+ chip->ngpio = 16;9090+ /* There is just one SoC in one device and its GPIO addresses should be9191+ * deterministic to address them more easily. The other buses could get9292+ * a random base number. */9393+ if (bus->bustype == SSB_BUSTYPE_SSB)9494+ chip->base = 0;9595+ else9696+ chip->base = -1;9797+9898+ return gpiochip_add(chip);9999+}100100+101101+#ifdef CONFIG_SSB_DRIVER_EXTIF102102+103103+static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio)104104+{105105+ struct ssb_bus *bus = ssb_gpio_get_bus(chip);106106+107107+ return !!ssb_extif_gpio_in(&bus->extif, 1 << gpio);108108+}109109+110110+static void ssb_gpio_extif_set_value(struct gpio_chip *chip, unsigned gpio,111111+ int value)112112+{113113+ struct ssb_bus *bus = ssb_gpio_get_bus(chip);114114+115115+ ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);116116+}117117+118118+static int ssb_gpio_extif_direction_input(struct gpio_chip *chip,119119+ unsigned gpio)120120+{121121+ struct ssb_bus *bus = ssb_gpio_get_bus(chip);122122+123123+ ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 0);124124+ return 0;125125+}126126+127127+static int ssb_gpio_extif_direction_output(struct gpio_chip *chip,128128+ unsigned gpio, int value)129129+{130130+ struct ssb_bus *bus = ssb_gpio_get_bus(chip);131131+132132+ ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 1 << gpio);133133+ ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);134134+ return 0;135135+}136136+137137+static int ssb_gpio_extif_init(struct ssb_bus *bus)138138+{139139+ struct gpio_chip *chip = &bus->gpio;140140+141141+ chip->label = "ssb_extif_gpio";142142+ chip->owner = THIS_MODULE;143143+ chip->get = ssb_gpio_extif_get_value;144144+ chip->set = ssb_gpio_extif_set_value;145145+ chip->direction_input = ssb_gpio_extif_direction_input;146146+ chip->direction_output = ssb_gpio_extif_direction_output;147147+ chip->ngpio = 5;148148+ /* There is just one SoC in one device and its GPIO addresses should be149149+ * deterministic to address them more easily. The other buses could get150150+ * a random base number. */151151+ if (bus->bustype == SSB_BUSTYPE_SSB)152152+ chip->base = 0;153153+ else154154+ chip->base = -1;155155+156156+ return gpiochip_add(chip);157157+}158158+159159+#else160160+static int ssb_gpio_extif_init(struct ssb_bus *bus)161161+{162162+ return -ENOTSUPP;163163+}164164+#endif165165+166166+int ssb_gpio_init(struct ssb_bus *bus)167167+{168168+ if (ssb_chipco_available(&bus->chipco))169169+ return ssb_gpio_chipco_init(bus);170170+ else if (ssb_extif_available(&bus->extif))171171+ return ssb_gpio_extif_init(bus);172172+ else173173+ SSB_WARN_ON(1);174174+175175+ return -1;176176+}
+7
drivers/ssb/main.c
···796796 if (err)797797 goto err_pcmcia_exit;798798 ssb_chipcommon_init(&bus->chipco);799799+ ssb_extif_init(&bus->extif);799800 ssb_mipscore_init(&bus->mipscore);801801+ err = ssb_gpio_init(bus);802802+ if (err == -ENOTSUPP)803803+ ssb_dprintk(KERN_DEBUG PFX "GPIO driver not activated\n");804804+ else if (err)805805+ ssb_dprintk(KERN_ERR PFX806806+ "Error registering GPIO driver: %i\n", err);800807 err = ssb_fetch_invariants(bus, get_invariants);801808 if (err) {802809 ssb_bus_may_powerdown(bus);