aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux
Commit message (Collapse)AuthorAgeFilesLines
...
* brcm47xx: add switch configuration for WNR3500LOlli Asikainen2019-12-081-1/+2
| | | | | | | | | | | | | | | | | | | | Netgear WNR3500L is an already supported device, but out of the box, the device has no switch configuration and there is no wan. The correct configuration for this specific model is similar to some other models. This simple commit adds the correct switch and the out-of-the-box experience is improved. Experimentally determined: Port 0 => WAN Port 1..4 => LAN Port 5..7 => unused Port 8 => CPU Signed-off-by: Olli Asikainen <olli.asikainen@gmail.com> Tested-by: Fabian Zaremba <fabian@youremail.eu> [added port mapping to commit message] Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* ramips: convert mediatek,mtd-eeprom from decimal to hex notationAdrian Schmutzler2019-12-083-6/+6
| | | | | | | | | | A small subset of devices uses decimal notation for mediatek,mtd-eeprom in DTS files. Convert to hexadecimal notation to be consistent with all the rest. Also change "0" to "0x0" in the same files for consistency. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* ramips: fix number of LAN Ports for Mikrotik RBM33GMartin Schiller2019-12-081-1/+4
| | | | | | | | The Mikrotik RBM33G has only 2 LAN ports. Signed-off-by: Martin Schiller <ms@dev.tdt.de> [moved node in 02_network to maintain alphabetic sorting] Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* ramips: fix switch port order for TP-Link Archer C20iWalter Sonius2019-12-081-1/+1
| | | | | | | | | | | | | | | | | | Physical port order watched from the backside of the C20i (from left to right) is: Internet / 1 / 2 / 3 / 4 Physical Port Switch port WAN 0 LAN 3 1 LAN 4 2 LAN 1 3 LAN 2 4 (not used) 5 CPU 6 Signed-off-by: Walter Sonius <walterav1984@gmail.com> [commit message/title improvements] Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* ath79: fix WNDR3700/WNDR3800 wifi reg sizeChristian Lamparter2019-12-071-2/+2
| | | | | | | | "[...] the size component shall be zero." (See "PCI Bus Binding to: IEEE Std 1275-1994 Rev 2.1" section "4.1.1 Open Firmware-defined Properties for Child Nodes") Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
* mediatek: fix pcie bringup issueJohn Crispin2019-12-051-0/+9
| | | | Signed-off-by: John Crispin <john@phrozen.org>
* ath79: add support for Ubiquiti LiteBeam AC Gen2Stijn Tintel2019-12-044-0/+52
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Hardware: * SoC: Atheros AR9342-BL1A * RAM: 64MB DDR2 (Winbond W9751G6KB-25) * Flash: 16MB SPI NOR (Macronix MX25L12835FZ2I-10G) * Ethernet: 1x 10/100/1000 Mbps (Atheros AR8035-A) with 24V PoE support * Wifi 2.4GHz: Atheros AR9340 v2 * WiFi 5GHz: Ubiquiti U-AME-G1-BR4A (rebranded QCA988X v2) * LEDs: 1x Power, 1x Ethernet * Buttons: 1x Reset * UART: 1x TTL 115200n8, 3.3V RX TX GND, 3.3V pin closest to RJ45 port The LEDs do not seem to be connected to any GPIO, so there is currently no way to control them. Installation via U-Boot, TFTP and serial console: * Configure your TFTP server with IP 192.168.1.254 * Connect serial console and power up the device * Hit any key to stop autoboot * tftpboot 0x81000000 openwrt-ath79-generic-ubnt_litebeam-ac-gen2-initramfs-kernel.bin * bootm 0x81000000 * copy openwrt-ath79-generic-ubnt_litebeam-ac-gen2-squashfs-sysupgrade.bin to /tmp * sysupgrade /tmp/openwrt-ath79-generic-ubnt_litebeam-ac-gen2-squashfs-sysupgrade.bin Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be> Acked-by: Petr Štetiar <ynezz@true.cz> Acked-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* ath79: drop IMAGE/factory.bin from ubnt-wa devicesStijn Tintel2019-12-041-4/+0
| | | | | | | | | | The sysupgrade image contains OpenWrt specific metadata. Having this metadata in the factory images makes no sense. Drop IMAGE/factory.bin from Device/ubnt-wa and use the default from Device/ubnt instead. Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be> Acked-by: Petr Štetiar <ynezz@true.cz> Acked-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* kernel: act_ctinfo: fix updated backport on 4.14Kevin Darbyshire-Bryant2019-12-041-21/+8
| | | | | | | | It turns out my 4.14 testing had a rather large flaw in it and the 'extack' mechanism isn't quite ready. Remove the extack stuff from this backport. Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
* kernel: act_ctinfo: update backportKevin Darbyshire-Bryant2019-12-032-72/+210
| | | | | | | | | | Since the original backports from kernel 5.3 a few things have been tweaked by kernel bumps & other upstream changes. Update the backport to reflect upstream as closely as possible and remove the bitrot. Functions remain the same, error reporting improved. Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
* ath79: fix source of label MAC address for Ubiquiti XM devicesAdrian Schmutzler2019-12-031-6/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In d421a8b94489 ("ath79: read label MAC address from flash instead of using phy0/phy1") the source of the label MAC address was changed for devices just reading it from phy0. To get rid of the dependency from phy startup, addresses were read directly from the flash locations that are used to initialize the phy MAC addresses. Unfortunately, it turned out that Ubiquiti XM devices seem to have different flash locations than expected, and also seem to have specific locations for different devices (all in art/EEPROM): 0xe012 AR9280 Nanostation M2 - 0x120c 0xe035 AR9280 Nanostation M3 - 0x120c 0xe1b2 AR9280 Rocket M2 - 0x120c 0xe1c3 AR9280 Rocket M3 - 0x120c 0xe1b5 AR9280 Rocket M5 - 0x120c 0xe2d5 AR9280 Bullet M2 Titanium - 0x120c 0xe2b5 AR9280 Nanobridge M5 - 0x120c 0xe202 AR9280 Bullet M2 - 0x120c 0xe232 AR9287 Nanobridge M2 - 0x110c 0xe4a2 AR9285 AirRouter - 0xa0bf Picostation M2 - 0x120c and 0xa0bf Nanostation Loco M2 - not in 0x120c, other locations not checked An additional problem of the Ubiquiti device support in OpenWrt is that we provide images that match several subvariants of the devices, which might have different MAC address locations. Given that reading the address from phy0 in 02_network _is_ working for the ath79 target in general, it does not seem reasonable to rebuild a complex MAC address retrieval mechanism which is already present in the ath9k driver. So, this patch reverts the label MAC address source for Ubiquiti XM devices (and the Unifi AP) to /sys/class/ieee80211/phy0/macaddress. This doesn't affect XW and Unifi AC devices, where the label MAC address source is defined via device tree. For alfa-network,ap121f the location 0x1002 is kept, as this has been verified during device support preparation in PR #2199. Fixes: d421a8b94489 ("ath79: read label MAC address from flash instead of using phy0/phy1") Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* octeon: fix sysupgradeStijn Tintel2019-11-301-2/+2
| | | | | | | | Sysupgrade was failing due to incorrect replacement of backticks: /sbin/sysupgrade: /lib/upgrade/platform.sh: line 101: syntax error: missing '))' Fixes: 0bbfc3dff719 ("octeon: replace backticks by $(...)") Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
* generic ar8xxx: increase VLAN table for AR83x7David Bauer2019-11-303-9/+13
| | | | | | | | | | | | The Atheros AR8327 and AR8337 have (according to their datasheet) a VLAN table with a maximum of 4096 entries. Currently, there's a hard limit of 128 VLANs, which is the same as for most other Atheros switches. Increase this limit only for the AR83x7 series and modify some shared functions to allow them to work with a variable max VLAN count. Signed-off-by: David Bauer <mail@david-bauer.net>
* mac80211: switch to upstream owl-loader driverChristian Lamparter2019-11-304-402/+0
| | | | | | | | | | | | | | | | | | The Owl Loader (named after the codename that Atheros gave these devices back in the day) has been accepted upstream. This patch removes the "misc" driver OpenWrt had and adds the remaining differences against the version that ships with 5.4-rc1 into a separate "120-owl-loader-compat.patch" file that can be cut down once AR71XX is being dealt with. Note: I decided to keep the existing (kmod-)owl-loader package name around for now. The kernel module file in the kmod package will be called ath9k_pci_owl_loader.ko though. Acked-by: Hauke Mehrtens <hauke@hauke-m.de> Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
* ipq40xx: add support for Crisis Innovation Lab MeshPoint.OneRobert Marko2019-11-307-4/+110
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | MeshPoint.One is Wi-Fi hotspot and smart IoT gateway (based upon Jalapeno module from 8Devices). MeshPoint.One (https://meshpointone.com) is a unique Wi-Fi hotspot and smart city gateway that can be installed and powered from street lighting (even solar power in the future). MeshPoint provides up to 27 hours of interrupted Wi-Fi and IoT services from internal battery even when external power is not available. MeshPoint.One can be used for disaster relief efforts in order to provide instant Wi-Fi coverage that can be easily expanded by just adding more devices that create wide area mesh network. MeshPoint.One devices have standard Luci UI for management. Features: - 1x 1Gpbs WAN - 1x 1Gbps LAN - POE input (eth0) - POE output (eth1) - Sensor for temperature, humidity and pressure (Bosch BME280) - current, voltage and power measurement via TI INA230 - Hardware real time clock - optional power via Li-Ion battery - micro USB port with USB to serial chip for easy OpenWrt terminal access - I2C header for connecting additional sensors Installation: ------------- Simply flash the sysupgrade image from stock firmware. Or use the built in Web recovery into bootloader: Hold Reset button for 5 to 20 seconds or use UART and httpd command. Web UI will appear on 192.168.2.100 by default. For web recovery use the factory.ubi image. Signed-off-by: Damir Samardzic <damir.samardzic@sartura.hr> Signed-off-by: Damir Franusic <damir.franusic@sartura.hr> Signed-off-by: Valent Turkovic <valent@meshpoint.me> Signed-off-by: Robert Marko <robert@meshpoint.me> [commit description long line wrap, usb->USB] Signed-off-by: Petr Štetiar <ynezz@true.cz>
* ipq40xx: use DTSI for JalapenoRobert Marko2019-11-302-260/+272
| | | | | | | | | | | | Lets move common code for Jalapeno into DTSI, this way Jalapeno based boards don't introduce duplicate code. While at it, lets also fix some style issues and update to current DTS style. Signed-off-by: Robert Marko <robert@meshpoint.me> [commit description long line wrap] Signed-off-by: Petr Štetiar <ynezz@true.cz>
* kernel: bump 4.9 to 4.9.205Koen Vandeputte2019-11-292-5/+5
| | | | | | | | | | | | Refreshed all patches. Fixes: - CVE-2019-18660 Compile-tested on: none Runtime-tested on: none Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
* kernel: bump 4.19 to 4.19.86Koen Vandeputte2019-11-2916-223/+44
| | | | | | | | | | | | | | | | | Refreshed all patches. Altered patches: - 950-0064-mfd-Add-Raspberry-Pi-Sense-HAT-core-driver.patch - 0005-mtd-physmap_of-Move-custom-initialization.patch Remove upstreamed: - 0001-pinctrl-gemini-Mask-and-set-properly.patch - 0002-pinctrl-gemini-Fix-up-TVC-clock-group.patch Compile-tested on: cns3xxx Runtime-tested on: cns3xxx Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
* kernel: bump 4.14 to 4.14.156Koen Vandeputte2019-11-2923-61/+61
| | | | | | | | | Refreshed all patches. Compile-tested on: cns3xxx Runtime-tested on: cns3xxx Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
* mpc85xx: add vendor to Makefile node name, derive SUPPORTED_DEVICESAdrian Schmutzler2019-11-271-15/+13
| | | | | | | | | | | | | | By adding the vendor to the Makefile device definition node name, one can derive the standard compatible used in SUPPORTED_DEVICES instead of having to specify it manually. Despite, this moves the naming scheme closer to what is used for other targets (ath79, ramips). Build-tested on all subtargets. Run-tested on TP-Link TL-WDR4900 v1. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* ath79: add support for TP-Link Archer C6 v2 (US) and A6 (US/TW)Anderson Vulczak2019-11-277-120/+270
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch is based on #1689 and adds support for TP-Link Archer C6 v2 (US) and A6 (US/TW). The hardware is the same as EU and RU variant, except for GPIOs (LEDS/Buttons), flash(chip/partitions) and UART being available on the board. - SOC: Qualcomm QCA9563 @ 775MHz - Flash: GigaDevice GD25Q127CS1G (16MiB) - RAM: Zentel A3R1GE40JBF (128 MiB DDR2) - Ethernet: Qualcomm QCA8337N: 4x 1Gbps LAN + 1x 1Gbps WAN - Wireless: - 2.4GHz (bgn) QCA9563 integrated (3x3) - 5GHz (ac) Qualcomm QCA9886 (2x2) - Button: 1x power, 1x reset, 1x wps - LED: 6x LEDs: power, wlan2g, wlan5g, lan, wan, wps - UART: 115200, 8n1 (header available on board) Known issues: - Wireless: 5GHz is known to have lower RSSI signal, it affects speed and range. Flash instructions: Upload openwrt-ath79-generic-tplink_archer-c6-v2-us-squashfs-factory.bin via the router Web interface. Flash instruction using tftp recovery: 1. Connect the computer to one of the LAN ports of the router 2. Set the computer IP to 192.168.0.66 3. Start a tftp server with the OpenWrt factory image in the tftp root directory renamed to ArcherA6v2_tp_recovery.bin. 4. Connect power cable to router, press and hold the reset button and turn the router on 5. Keep the reset button pressed until the WPS LED lights up 6. Wait ~150 seconds to complete flashing Flash partitioning: I've followed #1689 for defining the partition layout for this patch. The partition named as "tplink" @ 0xfd0000 is marked as read only as it is where some config for stock firmware are stored. On stock firmware those stock partitions starts at 0xfd9400 however I had not been able to make it functional starting on the same address as on stock fw, so it has been partitioned following #1689 and not the stock partition layout for this specific partition. Due to that firmware/rootfs partition lenght is 0xf80000 and not 0xf89400 as stock. According to the GPL code, the EU/RU/JP variant does have different GPIO pins assignment to LEDs and buttons, also the flash memory layout is different. GPL Source Code: https://static.tp-link.com/resources/gpl/gpl-A6v2_us.tar.gz Signed-off-by: Anderson Vulczak <andi@andi.com.br> [wrap commit message, remove soft_ver change for C6 v2 EU, move LED aliases to DTS files, remove dts-v1 in DTSI, node/property reorder in DTSI] Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* ath79: rename EEPROM to artAdrian Schmutzler2019-11-2711-33/+31
| | | | | | | | | | | | | This renames all remaining occurrences of "EEPROM" to "art" to further harmonize the partition labelling in ath79. This will help to reduce the amount of user-space code and might be beneficial when code is copy/pasted in the future. Affected are only devices from Ubiquiti, where the XM board is already using "art" in ath79. Acked-by: Piotr Dymacz <pepe2k@gmail.com> Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* ath79: add support for YunCore XD4200 and A782Piotr Dymacz2019-11-256-1/+217
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | YunCore XD4200 ('XD4200_W6.0' marking on PCB) is Qualcomm/Atheros based (QCA9563, QCA9886, QCA8334) dual-band, Wave-2 AC1200 ceiling AP with PoE (802.3at) support. A782 model ('T750_V5.1' marking on PCB) is a smaller version of the XD4200, with similar specification but lower TX power. Specification: - QCA9563 (775 MHz) - 128 MB of RAM (DDR2) - 16 MB of FLASH (SPI NOR) - 2x 10/100/1000 Mbps Ethernet (QCA8334), with 802.3at PoE support (WAN) - Wi-Fi 2.4 GHz: - XD4200: 2T2R (QCA9563), with ext. PA (SKY65174-21) and LNA - A782: 2T2R (QCA9563), with ext. FEM (SKY85329-11) - Wi-Fi 5 GHz: - XD4200: 2T2R (QCA9886), with ext. FEM (SKY85728-11) - A782: 2T2R (QCA9886), with ext. FEM (SKY85735-11) - LEDs: - XD4200: 5x (2x driven by SOC, 1x driven by AC radio, 2x Ethernet) - A782: 3x (1x RGB, driven by SOC and radio, 2x Ethernet) - 1x button (reset) - 1x UART (4-pin, 2.54 mm pitch) header on PCB - 1x DC jack (12 V) Flash instructions: If your device comes with generic QSDK based firmware, you can login over telnet (login: root, empty password, default IP: 192.168.188.253), issue first (important!) 'fw_setenv' command and then perform regular upgrade, using 'sysupgrade -n -F ...' (you can use 'wget' to download image to the device, SSH server is not available): fw_setenv bootcmd "bootm 0x9f050000 || bootm 0x9fe80000" sysupgrade -n -F openwrt-...-yuncore_...-squashfs-sysupgrade.bin In case your device runs firmware with YunCore custom GUI, you can use U-Boot recovery mode: 1. Set a static IP 192.168.0.141/24 on PC and start TFTP server with 'tftp' image renamed to 'upgrade.bin' 2. Power the device with reset button pressed and release it after 5-7 seconds, recovery mode should start downloading image from server (unfortunately, there is no visible indication that recovery got enabled - in case of problems check TFTP server logs) Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
* ath79: add support for YunCore TFTP image generationVincent Wiemann2019-11-252-0/+15
| | | | | | | | | | | | | | | | | | YunCore QCA9k based devices released in 2019 require a custom TFTP image for U-Boot built-in recovery mode (triggered with reset button). Image has to be prepended with 'YUNCORE' keyword followed by U-Boot CLI commands which will be executed later. Images without the custom header will be ignored by U-Boot. To be able to support both the vendor firmware (QSDK) and OpenWrt flash layouts, used here commands change the 'bootcmd' before flashing image. This commit adds generic helper script for YunCore devices with 16 MB of flash and enables TFTP image generation for A770 model. Signed-off-by: Vincent Wiemann <vincent.wiemann@ironai.com> [pepe2k@gmail.com: commit description reworded, recipe renamed] Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
* ath79: generic: base-files: fix indentation in 02_networkPiotr Dymacz2019-11-251-2/+2
| | | | Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
* ramips: reorganize NETGEAR sercomm boardsDavid Bauer2019-11-245-65/+126
| | | | | | | | | | | | This re-organizes the device-tree files for the Sercomm-manufactured NETGEAR routers. They are now split into two different base-boards, from which the respective model is extended. This partially reverts commit c7842ceaaa27 ("ramips: reorganize DTSI files for Netgear R devices"), which introduced inheritance between two completely unrelated base-boards. Signed-off-by: David Bauer <mail@david-bauer.net>
* ath79: remove ath10k drivers from Archer C7 v1 profileStijn Segers2019-11-241-1/+1
| | | | | | | | | | | Ath10k packages were removed from ar71xx in master in commit 34113999ef43 ("ar71xx: Remove ath10k packages from archer-c7-v1 (fixes FS#1743)") but ath79 in master and the 19.07 branch still suffer from the issue. Signed-off-by: Stijn Segers <foss@volatilesystems.org> [commit description facelift] Signed-off-by: Petr Štetiar <ynezz@true.cz>
* treewide: kernel config: remove runtime optionsPetr Štetiar2019-11-2412-15/+0
| | | | | | | Remove CC_HAS_ASM_GOTO, CC_IS_GCC and GCC_VERSION kernel config options which are set at runtime and which should be ignored now. Signed-off-by: Petr Štetiar <ynezz@true.cz>
* kernel: nf_conntrack_rtcache: fix WARNING on rmmodYousong Zhou2019-11-232-6/+2
| | | | | | | Fixes b7c58a1ee ("kernel: nf_conntrack_rtcache: fix cleanup on netns delete and rmmod") Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
* kernel: nf_conntrack_rtcache: fix WARNING on forward pathYousong Zhou2019-11-232-22/+2
| | | | | | | | | Fixes b7c58a1ee ("kernel: nf_conntrack_rtcache: fix cleanup on netns delete and rmmod") Resolves FS#2624 Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
* ath79: improve TP-Link CPE DTSI names for ar9344 SOCAdrian Schmutzler2019-11-2312-11/+11
| | | | | | | | | | | The initial DTSI names for the TP-Link CPE devices have become quite confusing, as several non-V1 devices now use the *-v1.dtsi, the *cpe510-v1.dts does not use the cpe510.dtsi, etc. This introduces a new naming scheme based on whether devices have one or two ports, which should be easier to grasp. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* ath79: DTS style improvement for Ubiquiti XM and BZ devicesAdrian Schmutzler2019-11-234-21/+13
| | | | | | | | | | This applies minor style improvements and removes commented pll clock adjustments from ubnt_xm DTSI. The latter were introduced (already commented out) when adding ath79 target and have never been touched since then. For Unifi (BZ board), similar clock adjustments are employed and used. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* kernel: nf_conntrack_rtcache: fix cleanup on netns delete and rmmodYousong Zhou2019-11-232-2/+26
| | | | | | | | Fixes FS#1472, FS#2353, FS#2426 Fixes: b3f95490 ("kernel: generic: Add kernel 4.14 support") Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com> Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
* kernel: Add missing configuration optionHauke Mehrtens2019-11-222-0/+2
| | | | | | | | This was found by the build bot. Fixes: e29500eb849a ("kernel: bump 4.19 to 4.19.85") Fixes: db9e9e838216 ("kernel: bump 4.14 to 4.14.155") Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
* cns3xxx: use proper macros for defining partition regionsKoen Vandeputte2019-11-221-6/+8
| | | | | | | While at it, also reorder the items for improved readability. Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
* kernel: bump 4.19 to 4.19.85Koen Vandeputte2019-11-2219-151/+57
| | | | | | | | | | | | | | | | | Refreshed all patches. Altered patches: - 080-sata_support.patch Remove upstreamed: - 034-v4.20-MIPS-BCM47XX-Enable-USB-power-on-Netgear-WNDR3400v3.patch - 001-4.21-01-BCM63XX-fix-switch-core-reset-on-BCM6368.patch - 073-qcom-ipq4019-fix-cpu0-s-qcom-saw2-reg-value.patch Compile-tested on: cns3xxx Runtime-tested on: cns3xxx Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
* kernel: bump 4.14 to 4.14.155Koen Vandeputte2019-11-2222-184/+77
| | | | | | | | | | | | | | | | | Refreshed all patches. Altered patches: - 707-dpaa-ethernet-support-layerscape.patch Remove upstreamed: - 034-v4.20-MIPS-BCM47XX-Enable-USB-power-on-Netgear-WNDR3400v3.patch - 001-4.21-01-BCM63XX-fix-switch-core-reset-on-BCM6368.patch - 073-qcom-ipq4019-fix-cpu0-s-qcom-saw2-reg-value.patch Compile-tested on: cns3xxx Runtime-tested on: cns3xxx Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
* ath79: add support for the TP-LINK WBS510 V1Andrew Cameron2019-11-225-0/+28
| | | | | | | | | | | | | | | | | | | | | | This adds support for a popular low-cost 5GHz N based AP Specifications: - SoC: Atheros AR9344 - RAM: 64MB - Storage: 8 MB SPI NOR - Wireless: 5GHz 300 Mbps, 2x RP-SMA connector, 27 dBm TX power - Ethernet: 1x 10/100 Mbps with 24V POE IN, 1x 10/100 Mbps Installation: Flash factory image through stock firmware WEB UI or through TFTP To get to TFTP recovery just hold reset button while powering on for around 4-5 seconds and release. Rename factory image to recovery.bin Stock TFTP server IP:192.168.0.100 Stock device TFTP adress:192.168.0.254 Signed-off-by: Andrew Cameron <apcameron@softhome.net>
* ath79: add support for the TP-LINK WBS510 V2Andrew Cameron2019-11-225-2/+29
| | | | | | | | | | | | | | | | | | | | | | This adds support for a popular low-cost 5GHz N based AP Specifications: - SoC: Atheros AR9344 - RAM: 64MB - Storage: 8 MB SPI NOR - Wireless: 5GHz 300 Mbps, 2x RP-SMA connector, 27 dBm TX power - Ethernet: 1x 10/100 Mbps with 24V POE IN, 1x 10/100 Mbps Installation: Flash factory image through stock firmware WEB UI or through TFTP To get to TFTP recovery just hold reset button while powering on for around 4-5 seconds and release. Rename factory image to recovery.bin Stock TFTP server IP:192.168.0.100 Stock device TFTP adress:192.168.0.254 Signed-off-by: Andrew Cameron <apcameron@softhome.net>
* ar71xx: ubnt-(xm,xw): add rssileds packageLech Perczak2019-11-211-2/+8
| | | | | | | | | | | | | | | | | | In order to make RSSI indicator on the device work out of box, include "rssileds" package in per-device rootfs image by default for Ubiquiti XM and XW devices, namely: - Bullet M (XM/XW) - Rocket M (XM/XW) - Nanostation M (XM/XW) - Nanostation Loco-M (XW) This moves the package addition to the individual devices in order to prevent accidental inclusions of the package when not looking at the parent node carefully enough. Signed-off-by: Lech Perczak <lech.perczak@gmail.com> [add bullet-m-xw, remove rocket-m-ti, extend commit message] Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* ath79: add PoE passthrough switch for Ubiquiti Nanostation (XM/XW)Adrian Schmutzler2019-11-211-0/+6
| | | | | | | | | | | | | This adds the gpio switch to enable PoE passthrough on Ubiquiti Nanostation (XM/XW). Values are copied from the implementation in ar71xx. GPIO values checked on: - NanoStation M5 XW - NanoStation M2 XM Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
* omap: switch from uEnv.txt to generic distro bootingAndre Heider2019-11-201-1/+1
| | | | | | Which makes supporting different boot devices easy. Signed-off-by: Andre Heider <a.heider@gmail.com>
* omap: switch to kernel 4.19Andre Heider2019-11-201-1/+1
| | | | Signed-off-by: Andre Heider <a.heider@gmail.com>
* omap: enable new sound kernel optionsAndre Heider2019-11-201-1/+5
| | | | | | | | This gets rid of a boot time warning about the missing edma module. Enable SND_OMAP_SOC_HDMI_AUDIO while here. All enabled options default to y. Signed-off-by: Andre Heider <a.heider@gmail.com>
* omap: disable excess kernel debug optionsAndre Heider2019-11-201-22/+1
| | | | Signed-off-by: Andre Heider <a.heider@gmail.com>
* omap: run `make oldconfig` for kernel 4.19Andre Heider2019-11-201-34/+72
| | | | | | | The only manually enabled config is the new OMAP4_DSS_HDMI_CEC, which defaults to y. Signed-off-by: Andre Heider <a.heider@gmail.com>
* omap: copy the kernel 4.14 config for 4.19Andre Heider2019-11-201-0/+742
| | | | Signed-off-by: Andre Heider <a.heider@gmail.com>
* ipq40xx: fix build errorKoen Vandeputte2019-11-201-11/+10
| | | | | | | Add missing brace which was accidentally omitted Fixes: d6aea46a50d9 ("kernel: bump 4.14 to 4.14.154") Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
* brcm2708: remove useless patchesKoen Vandeputte2019-11-202-129/+0
| | | | | | | | | | | The first adds some stuff while the second one just reverts it. Remove both patches. This is done is a separate commit on purpose to make it clear. Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
* kernel: bump 4.19 to 4.19.84Koen Vandeputte2019-11-1928-179/+80
| | | | | | | | | | | | | | | | | | | | | | | | Refreshed all patches. Altered patches: - 950-0748-net-bcmgenet-Workaround-for-Pi-4B-network-issue.patch - 950-0754-Revert-net-bcmgenet-Workaround-for-Pi-4B-network-iss.patch - 902-debloat_proc.patch Remove upstreamed: - 150-MIPS-bmips-mark-exception-vectors-as-char-arrays.patch New symbols: X86_INTEL_MPX X86_INTEL_MEMORY_PROTECTION_KEYS X86_INTEL_TSX_MODE_OFF X86_INTEL_TSX_MODE_ON X86_INTEL_TSX_MODE_AUTO Compile-tested on: cns3xxx, x86_64 Runtime-tested on: cns3xxx Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
span class="k">if (!rte) return; /* not an IOSAPIC interrupt */ rte_index = rte->rte_index; addr = rte->addr; pol = iosapic_intr_info[vector].polarity; trigger = iosapic_intr_info[vector].trigger; dmode = iosapic_intr_info[vector].dmode; redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0; #ifdef CONFIG_SMP { unsigned int irq; for (irq = 0; irq < NR_IRQS; ++irq) if (irq_to_vector(irq) == vector) { set_irq_affinity_info(irq, (int)(dest & 0xffff), redir); break; } } #endif low32 = ((pol << IOSAPIC_POLARITY_SHIFT) | (trigger << IOSAPIC_TRIGGER_SHIFT) | (dmode << IOSAPIC_DELIVERY_SHIFT) | ((mask ? 1 : 0) << IOSAPIC_MASK_SHIFT) | vector); /* dest contains both id and eid */ high32 = (dest << IOSAPIC_DEST_SHIFT); iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32); iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); iosapic_intr_info[vector].low32 = low32; iosapic_intr_info[vector].dest = dest; } static void nop (unsigned int vector) { /* do nothing... */ } void kexec_disable_iosapic(void) { struct iosapic_intr_info *info; struct iosapic_rte_info *rte; u8 vec = 0; for (info = iosapic_intr_info; info < iosapic_intr_info + IA64_NUM_VECTORS; ++info, ++vec) { list_for_each_entry(rte, &info->rtes, rte_list) { iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index), IOSAPIC_MASK|vec); iosapic_eoi(rte->addr, vec); } } } static void mask_irq (unsigned int irq) { unsigned long flags; char __iomem *addr; u32 low32; int rte_index; ia64_vector vec = irq_to_vector(irq); struct iosapic_rte_info *rte; if (list_empty(&iosapic_intr_info[vec].rtes)) return; /* not an IOSAPIC interrupt! */ spin_lock_irqsave(&iosapic_lock, flags); { /* set only the mask bit */ low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK; list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { addr = rte->addr; rte_index = rte->rte_index; iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); } } spin_unlock_irqrestore(&iosapic_lock, flags); } static void unmask_irq (unsigned int irq) { unsigned long flags; char __iomem *addr; u32 low32; int rte_index; ia64_vector vec = irq_to_vector(irq); struct iosapic_rte_info *rte; if (list_empty(&iosapic_intr_info[vec].rtes)) return; /* not an IOSAPIC interrupt! */ spin_lock_irqsave(&iosapic_lock, flags); { low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK; list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { addr = rte->addr; rte_index = rte->rte_index; iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); } } spin_unlock_irqrestore(&iosapic_lock, flags); } static void iosapic_set_affinity (unsigned int irq, cpumask_t mask) { #ifdef CONFIG_SMP unsigned long flags; u32 high32, low32; int dest, rte_index; char __iomem *addr; int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0; ia64_vector vec; struct iosapic_rte_info *rte; irq &= (~IA64_IRQ_REDIRECTED); vec = irq_to_vector(irq); if (cpus_empty(mask)) return; dest = cpu_physical_id(first_cpu(mask)); if (list_empty(&iosapic_intr_info[vec].rtes)) return; /* not an IOSAPIC interrupt */ set_irq_affinity_info(irq, dest, redir); /* dest contains both id and eid */ high32 = dest << IOSAPIC_DEST_SHIFT; spin_lock_irqsave(&iosapic_lock, flags); { low32 = iosapic_intr_info[vec].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT); if (redir) /* change delivery mode to lowest priority */ low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT); else /* change delivery mode to fixed */ low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT); iosapic_intr_info[vec].low32 = low32; iosapic_intr_info[vec].dest = dest; list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { addr = rte->addr; rte_index = rte->rte_index; iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32); iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); } } spin_unlock_irqrestore(&iosapic_lock, flags); #endif } /* * Handlers for level-triggered interrupts. */ static unsigned int iosapic_startup_level_irq (unsigned int irq) { unmask_irq(irq); return 0; } static void iosapic_end_level_irq (unsigned int irq) { ia64_vector vec = irq_to_vector(irq); struct iosapic_rte_info *rte; move_irq(irq); list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) iosapic_eoi(rte->addr, vec); } #define iosapic_shutdown_level_irq mask_irq #define iosapic_enable_level_irq unmask_irq #define iosapic_disable_level_irq mask_irq #define iosapic_ack_level_irq nop static hw_irq_controller irq_type_iosapic_level = { .typename = "IO-SAPIC-level", .startup = iosapic_startup_level_irq, .shutdown = iosapic_shutdown_level_irq, .enable = iosapic_enable_level_irq, .disable = iosapic_disable_level_irq, .ack = iosapic_ack_level_irq, .end = iosapic_end_level_irq, .set_affinity = iosapic_set_affinity }; /* * Handlers for edge-triggered interrupts. */ static unsigned int iosapic_startup_edge_irq (unsigned int irq) { unmask_irq(irq); /* * IOSAPIC simply drops interrupts pended while the * corresponding pin was masked, so we can't know if an * interrupt is pending already. Let's hope not... */ return 0; } static void iosapic_ack_edge_irq (unsigned int irq) { irq_desc_t *idesc = irq_descp(irq); move_irq(irq); /* * Once we have recorded IRQ_PENDING already, we can mask the * interrupt for real. This prevents IRQ storms from unhandled * devices. */ if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) == (IRQ_PENDING|IRQ_DISABLED)) mask_irq(irq); } #define iosapic_enable_edge_irq unmask_irq #define iosapic_disable_edge_irq nop #define iosapic_end_edge_irq nop static hw_irq_controller irq_type_iosapic_edge = { .typename = "IO-SAPIC-edge", .startup = iosapic_startup_edge_irq, .shutdown = iosapic_disable_edge_irq, .enable = iosapic_enable_edge_irq, .disable = iosapic_disable_edge_irq, .ack = iosapic_ack_edge_irq, .end = iosapic_end_edge_irq, .set_affinity = iosapic_set_affinity }; unsigned int iosapic_version (char __iomem *addr) { /* * IOSAPIC Version Register return 32 bit structure like: * { * unsigned int version : 8; * unsigned int reserved1 : 8; * unsigned int max_redir : 8; * unsigned int reserved2 : 8; * } */ return iosapic_read(addr, IOSAPIC_VERSION); } static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long pol) { int i, vector = -1, min_count = -1; struct iosapic_intr_info *info; /* * shared vectors for edge-triggered interrupts are not * supported yet */ if (trigger == IOSAPIC_EDGE) return -1; for (i = IA64_FIRST_DEVICE_VECTOR; i <= IA64_LAST_DEVICE_VECTOR; i++) { info = &iosapic_intr_info[i]; if (info->trigger == trigger && info->polarity == pol && (info->dmode == IOSAPIC_FIXED || info->dmode == IOSAPIC_LOWEST_PRIORITY)) { if (min_count == -1 || info->count < min_count) { vector = i; min_count = info->count; } } } return vector; } /* * if the given vector is already owned by other, * assign a new vector for the other and make the vector available */ static void __init iosapic_reassign_vector (int vector) { int new_vector; if (!list_empty(&iosapic_intr_info[vector].rtes)) { new_vector = assign_irq_vector(AUTO_ASSIGN); if (new_vector < 0) panic("%s: out of interrupt vectors!\n", __FUNCTION__); printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector); memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], sizeof(struct iosapic_intr_info)); INIT_LIST_HEAD(&iosapic_intr_info[new_vector].rtes); list_move(iosapic_intr_info[vector].rtes.next, &iosapic_intr_info[new_vector].rtes); memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); iosapic_intr_info[vector].low32 = IOSAPIC_MASK; INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); } } static struct iosapic_rte_info *iosapic_alloc_rte (void) { int i; struct iosapic_rte_info *rte; int preallocated = 0; if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) { #ifdef XEN rte = xmalloc_bytes(sizeof(struct iosapic_rte_info) * NR_PREALLOCATE_RTE_ENTRIES); #else rte = alloc_bootmem(sizeof(struct iosapic_rte_info) * NR_PREALLOCATE_RTE_ENTRIES); #endif if (!rte) return NULL; for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++) list_add(&rte->rte_list, &free_rte_list); } if (!list_empty(&free_rte_list)) { rte = list_entry(free_rte_list.next, struct iosapic_rte_info, rte_list); list_del(&rte->rte_list); preallocated++; } else { rte = kmalloc(sizeof(struct iosapic_rte_info), GFP_ATOMIC); if (!rte) return NULL; } memset(rte, 0, sizeof(struct iosapic_rte_info)); if (preallocated) rte->flags |= RTE_PREALLOCATED; return rte; } static void iosapic_free_rte (struct iosapic_rte_info *rte) { if (rte->flags & RTE_PREALLOCATED) list_add_tail(&rte->rte_list, &free_rte_list); else kfree(rte); } static inline int vector_is_shared (int vector) { return (iosapic_intr_info[vector].count > 1); } static int register_intr (unsigned int gsi, int vector, unsigned char delivery, unsigned long polarity, unsigned long trigger) { irq_desc_t *idesc; hw_irq_controller *irq_type; int rte_index; int index; unsigned long gsi_base; void __iomem *iosapic_address; struct iosapic_rte_info *rte; index = find_iosapic(gsi); if (index < 0) { printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi); return -ENODEV; } iosapic_address = iosapic_lists[index].addr; gsi_base = iosapic_lists[index].gsi_base; rte = gsi_vector_to_rte(gsi, vector); if (!rte) { rte = iosapic_alloc_rte(); if (!rte) { printk(KERN_WARNING "%s: cannot allocate memory\n", __FUNCTION__); return -ENOMEM; } rte_index = gsi - gsi_base; rte->rte_index = rte_index; rte->addr = iosapic_address; rte->gsi_base = gsi_base; rte->refcnt++; list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes); iosapic_intr_info[vector].count++; iosapic_lists[index].rtes_inuse++; } else if (vector_is_shared(vector)) { struct iosapic_intr_info *info = &iosapic_intr_info[vector]; if (info->trigger != trigger || info->polarity != polarity) { printk (KERN_WARNING "%s: cannot override the interrupt\n", __FUNCTION__); return -EINVAL; } } iosapic_intr_info[vector].polarity = polarity; iosapic_intr_info[vector].dmode = delivery; iosapic_intr_info[vector].trigger = trigger; if (trigger == IOSAPIC_EDGE) irq_type = &irq_type_iosapic_edge; else irq_type = &irq_type_iosapic_level; idesc = irq_descp(vector); if (idesc->handler != irq_type) { if (idesc->handler != &no_irq_type) printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", __FUNCTION__, vector, idesc->handler->typename, irq_type->typename); idesc->handler = irq_type; } return 0; } static unsigned int get_target_cpu (unsigned int gsi, int vector) { #ifdef CONFIG_SMP static int cpu = -1; /* * In case of vector shared by multiple RTEs, all RTEs that * share the vector need to use the same destination CPU. */ if (!list_empty(&iosapic_intr_info[vector].rtes)) return iosapic_intr_info[vector].dest; /* * If the platform supports redirection via XTP, let it * distribute interrupts. */ if (smp_int_redirect & SMP_IRQ_REDIRECTION) return cpu_physical_id(smp_processor_id()); /* * Some interrupts (ACPI SCI, for instance) are registered * before the BSP is marked as online. */ if (!cpu_online(smp_processor_id())) return cpu_physical_id(smp_processor_id()); #ifdef CONFIG_NUMA { int num_cpus, cpu_index, iosapic_index, numa_cpu, i = 0; cpumask_t cpu_mask; iosapic_index = find_iosapic(gsi); if (iosapic_index < 0 || iosapic_lists[iosapic_index].node == MAX_NUMNODES) goto skip_numa_setup; cpu_mask = node_to_cpumask(iosapic_lists[iosapic_index].node); for_each_cpu_mask(numa_cpu, cpu_mask) { if (!cpu_online(numa_cpu)) cpu_clear(numa_cpu, cpu_mask); } num_cpus = cpus_weight(cpu_mask); if (!num_cpus) goto skip_numa_setup; /* Use vector assigment to distribute across cpus in node */ cpu_index = vector % num_cpus; for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++) numa_cpu = next_cpu(numa_cpu, cpu_mask); if (numa_cpu != NR_CPUS) return cpu_physical_id(numa_cpu); } skip_numa_setup: #endif /* * Otherwise, round-robin interrupt vectors across all the * processors. (It'd be nice if we could be smarter in the * case of NUMA.) */ do { if (++cpu >= NR_CPUS) cpu = 0; } while (!cpu_online(cpu)); return cpu_physical_id(cpu); #else return cpu_physical_id(smp_processor_id()); #endif } /* * ACPI can describe IOSAPIC interrupts via static tables and namespace * methods. This provides an interface to register those interrupts and * program the IOSAPIC RTE. */ int iosapic_register_intr (unsigned int gsi, unsigned long polarity, unsigned long trigger) { int vector, mask = 1, err; unsigned int dest; unsigned long flags; struct iosapic_rte_info *rte; u32 low32; again: /* * If this GSI has already been registered (i.e., it's a * shared interrupt, or we lost a race to register it), * don't touch the RTE. */ spin_lock_irqsave(&iosapic_lock, flags); { vector = gsi_to_vector(gsi); if (vector > 0) { rte = gsi_vector_to_rte(gsi, vector); rte->refcnt++; spin_unlock_irqrestore(&iosapic_lock, flags); return vector; } } spin_unlock_irqrestore(&iosapic_lock, flags); /* If vector is running out, we try to find a sharable vector */ vector = assign_irq_vector(AUTO_ASSIGN); if (vector < 0) { vector = iosapic_find_sharable_vector(trigger, polarity); if (vector < 0) return -ENOSPC; } spin_lock_irqsave(&irq_descp(vector)->lock, flags); spin_lock(&iosapic_lock); { if (gsi_to_vector(gsi) > 0) { if (list_empty(&iosapic_intr_info[vector].rtes)) free_irq_vector(vector); spin_unlock(&iosapic_lock); spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); goto again; } dest = get_target_cpu(gsi, vector); err = register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger); if (err < 0) { spin_unlock(&iosapic_lock); spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); return err; } /* * If the vector is shared and already unmasked for * other interrupt sources, don't mask it. */ low32 = iosapic_intr_info[vector].low32; if (vector_is_shared(vector) && !(low32 & IOSAPIC_MASK)) mask = 0; set_rte(gsi, vector, dest, mask); } spin_unlock(&iosapic_lock); spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), cpu_logical_id(dest), dest, vector); return vector; } void iosapic_unregister_intr (unsigned int gsi) { unsigned long flags; int irq, vector, index; irq_desc_t *idesc; u32 low32; unsigned long trigger, polarity; unsigned int dest; struct iosapic_rte_info *rte; /* * If the irq associated with the gsi is not found, * iosapic_unregister_intr() is unbalanced. We need to check * this again after getting locks. */ irq = gsi_to_irq(gsi); if (irq < 0) { printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi); WARN_ON(1); return; } vector = irq_to_vector(irq); idesc = irq_descp(irq); spin_lock_irqsave(&idesc->lock, flags); spin_lock(&iosapic_lock); { if ((rte = gsi_vector_to_rte(gsi, vector)) == NULL) { printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi); WARN_ON(1); goto out; } if (--rte->refcnt > 0) goto out; /* Mask the interrupt */ low32 = iosapic_intr_info[vector].low32 | IOSAPIC_MASK; iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index), low32); /* Remove the rte entry from the list */ list_del(&rte->rte_list); iosapic_intr_info[vector].count--; iosapic_free_rte(rte); index = find_iosapic(gsi); iosapic_lists[index].rtes_inuse--; WARN_ON(iosapic_lists[index].rtes_inuse < 0); trigger = iosapic_intr_info[vector].trigger; polarity = iosapic_intr_info[vector].polarity; dest = iosapic_intr_info[vector].dest; printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d unregistered\n", gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), cpu_logical_id(dest), dest, vector); if (list_empty(&iosapic_intr_info[vector].rtes)) { /* Sanity check */ BUG_ON(iosapic_intr_info[vector].count); /* Clear the interrupt controller descriptor */ idesc->handler = &no_irq_type; /* Clear the interrupt information */ memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); iosapic_intr_info[vector].low32 |= IOSAPIC_MASK; INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); if (idesc->action) { printk(KERN_ERR "interrupt handlers still exist on IRQ %u\n", irq); WARN_ON(1); } /* Free the interrupt vector */ free_irq_vector(vector); } } out: spin_unlock(&iosapic_lock); spin_unlock_irqrestore(&idesc->lock, flags); } /* * ACPI calls this when it finds an entry for a platform interrupt. * Note that the irq_base and IOSAPIC address must be set in iosapic_init(). */ int __init iosapic_register_platform_intr (u32 int_type, unsigned int gsi, int iosapic_vector, u16 eid, u16 id, unsigned long polarity, unsigned long trigger) { static const char * const name[] = {"unknown", "PMI", "INIT", "CPEI"}; unsigned char delivery; int vector, mask = 0; unsigned int dest = ((id << 8) | eid) & 0xffff; switch (int_type) { case ACPI_INTERRUPT_PMI: vector = iosapic_vector; /* * since PMI vector is alloc'd by FW(ACPI) not by kernel, * we need to make sure the vector is available */ iosapic_reassign_vector(vector); delivery = IOSAPIC_PMI; break; case ACPI_INTERRUPT_INIT: vector = assign_irq_vector(AUTO_ASSIGN); if (vector < 0) panic("%s: out of interrupt vectors!\n", __FUNCTION__); delivery = IOSAPIC_INIT; break; case ACPI_INTERRUPT_CPEI: vector = IA64_CPE_VECTOR; delivery = IOSAPIC_LOWEST_PRIORITY; mask = 1; break; default: printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type 0x%x\n", int_type); return -1; } register_intr(gsi, vector, delivery, polarity, trigger); printk(KERN_INFO "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown", int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), cpu_logical_id(dest), dest, vector); set_rte(gsi, vector, dest, mask); return vector; } /* * ACPI calls this when it finds an entry for a legacy ISA IRQ override. * Note that the gsi_base and IOSAPIC address must be set in iosapic_init(). */ void __init iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, unsigned long polarity, unsigned long trigger) { int vector; unsigned int dest = cpu_physical_id(smp_processor_id()); vector = isa_irq_to_vector(isa_irq); register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger); DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n", isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level", polarity == IOSAPIC_POL_HIGH ? "high" : "low", cpu_logical_id(dest), dest, vector); set_rte(gsi, vector, dest, 1); } void __init iosapic_system_init (int system_pcat_compat) { int vector; for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) { iosapic_intr_info[vector].low32 = IOSAPIC_MASK; INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); /* mark as unused */ } pcat_compat = system_pcat_compat; if (pcat_compat) { /* * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support * enabled. */ printk(KERN_INFO "%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__); outb(0xff, 0xA1); outb(0xff, 0x21); } } static inline int iosapic_alloc (void) { int index; for (index = 0; index < NR_IOSAPICS; index++) if (!iosapic_lists[index].addr) return index; printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__); return -1; } static inline void iosapic_free (int index) { memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0])); } static inline int iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver) { int index; unsigned int gsi_end, base, end; /* check gsi range */ gsi_end = gsi_base + ((ver >> 16) & 0xff); for (index = 0; index < NR_IOSAPICS; index++) { if (!iosapic_lists[index].addr) continue; base = iosapic_lists[index].gsi_base; end = base + iosapic_lists[index].num_rte - 1; if (gsi_base < base && gsi_end < base) continue;/* OK */ if (gsi_base > end && gsi_end > end) continue; /* OK */ return -EBUSY; } return 0; } int __devinit #ifndef XEN iosapic_init (unsigned long phys_addr, unsigned int gsi_base) #else iosapic_init (unsigned long phys_addr, unsigned int gsi_base, unsigned int id) #endif { int num_rte, err, index; unsigned int isa_irq, ver; char __iomem *addr; unsigned long flags; spin_lock_irqsave(&iosapic_lock, flags); { addr = ioremap(phys_addr, 0); ver = iosapic_version(addr); if ((err = iosapic_check_gsi_range(gsi_base, ver))) { iounmap(addr); spin_unlock_irqrestore(&iosapic_lock, flags); return err; } /* * The MAX_REDIR register holds the highest input pin * number (starting from 0). * We add 1 so that we can use it for number of pins (= RTEs) */ num_rte = ((ver >> 16) & 0xff) + 1; index = iosapic_alloc(); iosapic_lists[index].addr = addr; iosapic_lists[index].gsi_base = gsi_base; iosapic_lists[index].num_rte = num_rte; #ifdef XEN iosapic_lists[index].id = id; #endif #ifdef CONFIG_NUMA iosapic_lists[index].node = MAX_NUMNODES; #endif } spin_unlock_irqrestore(&iosapic_lock, flags); if ((gsi_base == 0) && pcat_compat) { /* * Map the legacy ISA devices into the IOSAPIC data. Some of these may * get reprogrammed later on with data from the ACPI Interrupt Source * Override table. */ for (isa_irq = 0; isa_irq < 16; ++isa_irq) iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); } return 0; } #ifdef CONFIG_HOTPLUG int iosapic_remove (unsigned int gsi_base) { int index, err = 0; unsigned long flags; spin_lock_irqsave(&iosapic_lock, flags); { index = find_iosapic(gsi_base); if (index < 0) { printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n", __FUNCTION__, gsi_base); goto out; } if (iosapic_lists[index].rtes_inuse) { err = -EBUSY; printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", __FUNCTION__, gsi_base); goto out; } iounmap(iosapic_lists[index].addr); iosapic_free(index); } out: spin_unlock_irqrestore(&iosapic_lock, flags); return err; } #endif /* CONFIG_HOTPLUG */ #ifdef CONFIG_NUMA void __devinit map_iosapic_to_node(unsigned int gsi_base, int node) { int index; index = find_iosapic(gsi_base); if (index < 0) { printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi_base); return; } iosapic_lists[index].node = node; return; } #endif #ifndef XEN static int __init iosapic_enable_kmalloc (void) { iosapic_kmalloc_ok = 1; return 0; } core_initcall (iosapic_enable_kmalloc); #endif #ifdef XEN /* nop for now */ void set_irq_affinity_info(unsigned int irq, int hwid, int redir) {} static int iosapic_physbase_to_id(unsigned long physbase) { int i; unsigned long addr = physbase | __IA64_UNCACHED_OFFSET; for (i = 0; i < NR_IOSAPICS; i++) { if ((unsigned long)(iosapic_lists[i].addr) == addr) return i; } return -1; } int iosapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval) { int id; unsigned long flags; if ((id = (iosapic_physbase_to_id(physbase))) < 0) return id; spin_lock_irqsave(&iosapic_lock, flags); *pval = iosapic_read(iosapic_lists[id].addr, reg); spin_unlock_irqrestore(&iosapic_lock, flags); return 0; } int iosapic_guest_write(unsigned long physbase, unsigned int reg, u32 val) { unsigned int id, gsi, vec, xen_vec, dest, high32; char rte_index; struct iosapic *ios; struct iosapic_intr_info *info; struct rte_entry rte; unsigned long flags; if ((id = (iosapic_physbase_to_id(physbase))) < 0) return -EINVAL; ios = &iosapic_lists[id]; /* Only handle first half of RTE update */ if ((reg < 0x10) || (reg & 1)) return 0; rte.val = val; rte_index = IOSAPIC_RTEINDEX(reg); vec = rte.lo.vector; #if 0 /* Take PMI/NMI/INIT/EXTINT handled by xen */ if (rte.delivery_mode > IOSAPIC_LOWEST_PRIORITY) { printk("Attempt to write IOSAPIC dest mode owned by xen!\n"); printk("IOSAPIC/PIN = (%d/%d), lo = 0x%x\n", id, rte_index, val); return -EINVAL; } #endif /* Sanity check. Vector should be allocated before this update */ if ((rte_index > ios->num_rte) || ((vec > IA64_FIRST_DEVICE_VECTOR) && (vec < IA64_LAST_DEVICE_VECTOR) && (!test_bit(vec - IA64_FIRST_DEVICE_VECTOR, ia64_vector_mask)))) return -EINVAL; gsi = ios->gsi_base + rte_index; xen_vec = gsi_to_vector(gsi); if (xen_vec >= 0 && test_bit(xen_vec, ia64_xen_vector)) { printk("WARN: GSI %d in use by Xen.\n", gsi); return -EINVAL; } info = &iosapic_intr_info[vec]; spin_lock_irqsave(&irq_descp(vec)->lock, flags); spin_lock(&iosapic_lock); if (!gsi_vector_to_rte(gsi, vec)) { register_intr(gsi, vec, IOSAPIC_LOWEST_PRIORITY, rte.lo.polarity, rte.lo.trigger); } else if (vector_is_shared(vec)) { if ((info->trigger != rte.lo.trigger) || (info->polarity != rte.lo.polarity)) { printk("WARN: can't override shared interrupt vec\n"); printk("IOSAPIC/PIN = (%d/%d), ori = 0x%x, new = 0x%x\n", id, rte_index, info->low32, rte.val); spin_unlock(&iosapic_lock); spin_unlock_irqrestore(&irq_descp(vec)->lock, flags); return -EINVAL; } /* If the vector is shared and already unmasked for other * interrupt sources, don't mask it. * * Same check may also apply to single gsi pin, which may * be shared by devices belonging to different domain. But * let's see how to act later on demand. */ if (!(info->low32 & IOSAPIC_MASK)) rte.lo.mask = 0; } /* time to update physical RTE */ dest = cpu_physical_id(smp_processor_id()); high32 = (dest << IOSAPIC_DEST_SHIFT); iosapic_write(iosapic_lists[id].addr, reg + 1, high32); iosapic_write(iosapic_lists[id].addr, reg, rte.val); info->low32 = rte.val; info->dest = dest; spin_unlock(&iosapic_lock); spin_unlock_irqrestore(&irq_descp(vec)->lock, flags); return 0; } /* for vtd interrupt remapping. xen/drivers/vtd/intremap.c */ int iosapic_get_nr_iosapics(void) { int index; for (index = NR_IOSAPICS - 1; index >= 0; index--) { if (iosapic_lists[index].addr) break; } return index + 1; } int iosapic_get_nr_pins(int index) { return iosapic_lists[index].num_rte; } #endif /* XEN */