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

Merge tag 'ixp4xx-for-armsoc' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik into arm/soc

This modernizes the IXP4xx platform and adds initial Device Tree
Support. We migrate to MULTI_IRQ_HANDLER, bumps the IRQs to
offset 16, converts to SPARSE_IRQ, then we add proper subsystem
drivers in each subsystem for irqchip, GPIO and clocksource and
switch over to using these new drivers.

Next we modernize the NPE and QMGR drivers and push them down
into drivers/soc.

This has been tested on the IXP4xx NSLU2 and the Gateworks
GW2358-4.

* tag 'ixp4xx-for-armsoc' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik: (31 commits)
ARM: dts: Add queue manager and NPE to the IXP4xx DTSI
soc: ixp4xx: qmgr: Add DT probe code
soc: ixp4xx: qmgr: Add DT bindings for IXP4xx qmgr
soc: ixp4xx: npe: Add DT probe code
soc: ixp4xx: Add DT bindings for IXP4xx NPE
soc: ixp4xx: qmgr: Pass resources
soc: ixp4xx: Remove unused functions
soc: ixp4xx: Uninline several functions
soc: ixp4xx: npe: Pass addresses as resources
ARM: ixp4xx: Turn the QMGR into a platform device
ARM: ixp4xx: Turn the NPE into a platform device
ARM: ixp4xx: Move IXP4xx QMGR and NPE headers
ARM: ixp4xx: Move NPE and QMGR to drivers/soc
ARM: dts: Add some initial IXP4xx device trees
ARM: ixp4xx: Add device tree boot support
ARM: ixp4xx: Add DT bindings
gpio: ixp4xx: Add OF probing support
gpio: ixp4xx: Add DT bindings
clocksource/drivers/ixp4xx: Add OF initialization support
clocksource/drivers/ixp4xx: Add DT bindings
...

Signed-off-by: Olof Johansson <olof@lixom.net>

+2416 -914
+22
Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/arm/intel-ixp4xx.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Intel IXP4xx Device Tree Bindings 8 + 9 + maintainers: 10 + - Linus Walleij <linus.walleij@linaro.org> 11 + 12 + properties: 13 + compatible: 14 + oneOf: 15 + - items: 16 + - enum: 17 + - linksys,nslu2 18 + - const: intel,ixp42x 19 + - items: 20 + - enum: 21 + - gateworks,gw2358 22 + - const: intel,ixp43x
+44
Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + # Copyright 2019 Linaro Ltd. 3 + %YAML 1.2 4 + --- 5 + $id: "http://devicetree.org/schemas/firmware/intel-ixp4xx-network-processing-engine.yaml#" 6 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 7 + 8 + title: Intel IXP4xx Network Processing Engine 9 + 10 + maintainers: 11 + - Linus Walleij <linus.walleij@linaro.org> 12 + 13 + description: | 14 + On the IXP4xx SoCs, the Network Processing Engine (NPE) is a small 15 + processor that can load a firmware to perform offloading of networking 16 + and crypto tasks. It also manages the MDIO bus to the ethernet PHYs 17 + on the IXP4xx platform. All IXP4xx platforms have three NPEs at 18 + consecutive memory locations. They are all included in the same 19 + device node since they are not independent of each other. 20 + 21 + properties: 22 + compatible: 23 + oneOf: 24 + - items: 25 + - const: intel,ixp4xx-network-processing-engine 26 + 27 + reg: 28 + minItems: 3 29 + maxItems: 3 30 + items: 31 + - description: NPE0 register range 32 + - description: NPE1 register range 33 + - description: NPE2 register range 34 + 35 + required: 36 + - compatible 37 + - reg 38 + 39 + examples: 40 + - | 41 + npe@c8006000 { 42 + compatible = "intel,ixp4xx-network-processing-engine"; 43 + reg = <0xc8006000 0x1000>, <0xc8007000 0x1000>, <0xc8008000 0x1000>; 44 + };
+54
Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + # Copyright 2018 Linaro Ltd. 3 + %YAML 1.2 4 + --- 5 + $id: "http://devicetree.org/schemas/interrupt/intel-ixp4xx-interrupt.yaml#" 6 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 7 + 8 + title: Intel IXP4xx XScale Networking Processors Interrupt Controller 9 + 10 + maintainers: 11 + - Linus Walleij <linus.walleij@linaro.org> 12 + 13 + description: | 14 + This interrupt controller is found in the Intel IXP4xx processors. 15 + Some processors have 32 interrupts, some have up to 64 interrupts. 16 + The exact number of interrupts is determined from the compatible 17 + string. 18 + 19 + The distinct IXP4xx families with different interrupt controller 20 + variations are IXP42x, IXP43x, IXP45x and IXP46x. Those four 21 + families were the only ones to reach the developer and consumer 22 + market. 23 + 24 + properties: 25 + compatible: 26 + items: 27 + - enum: 28 + - intel,ixp42x-interrupt 29 + - intel,ixp43x-interrupt 30 + - intel,ixp45x-interrupt 31 + - intel,ixp46x-interrupt 32 + 33 + reg: 34 + maxItems: 1 35 + 36 + interrupt-controller: true 37 + 38 + '#interrupt-cells': 39 + const: 2 40 + 41 + required: 42 + - compatible 43 + - reg 44 + - interrupt-controller 45 + - '#interrupt-cells' 46 + 47 + examples: 48 + - | 49 + intcon: interrupt-controller@c8003000 { 50 + compatible = "intel,ixp43x-interrupt"; 51 + reg = <0xc8003000 0x100>; 52 + interrupt-controller; 53 + #interrupt-cells = <2>; 54 + };
+49
Documentation/devicetree/bindings/misc/intel,ixp4xx-queue-manager.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + # Copyright 2019 Linaro Ltd. 3 + %YAML 1.2 4 + --- 5 + $id: "http://devicetree.org/schemas/misc/intel-ixp4xx-ahb-queue-manager.yaml#" 6 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 7 + 8 + title: Intel IXP4xx AHB Queue Manager 9 + 10 + maintainers: 11 + - Linus Walleij <linus.walleij@linaro.org> 12 + 13 + description: | 14 + The IXP4xx AHB Queue Manager maintains queues as circular buffers in 15 + an 8KB embedded SRAM along with hardware pointers. It is used by both 16 + the XScale processor and the NPEs (Network Processing Units) in the 17 + IXP4xx for accelerating queues, especially for networking. Clients pick 18 + queues from the queue manager with foo-queue = <&qmgr N> where the 19 + &qmgr is a phandle to the queue manager and N is the queue resource 20 + number. The queue resources available and their specific purpose 21 + on a certain IXP4xx system will vary. 22 + 23 + properties: 24 + compatible: 25 + items: 26 + - const: intel,ixp4xx-ahb-queue-manager 27 + 28 + reg: 29 + maxItems: 1 30 + 31 + interrupts: 32 + items: 33 + - description: Interrupt for queues 0-31 34 + - description: Interrupt for queues 32-63 35 + 36 + required: 37 + - compatible 38 + - reg 39 + - interrupts 40 + 41 + examples: 42 + - | 43 + #include <dt-bindings/interrupt-controller/irq.h> 44 + 45 + qmgr: queue-manager@60000000 { 46 + compatible = "intel,ixp4xx-ahb-queue-manager"; 47 + reg = <0x60000000 0x4000>; 48 + interrupts = <3 IRQ_TYPE_LEVEL_HIGH>, <4 IRQ_TYPE_LEVEL_HIGH>; 49 + };
+42
Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + # Copyright 2018 Linaro Ltd. 3 + %YAML 1.2 4 + --- 5 + $id: "http://devicetree.org/schemas/timer/intel-ixp4xx-timer.yaml#" 6 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 7 + 8 + title: Intel IXP4xx XScale Networking Processors Timers 9 + 10 + maintainers: 11 + - Linus Walleij <linus.walleij@linaro.org> 12 + 13 + description: This timer is found in the Intel IXP4xx processors. 14 + 15 + properties: 16 + compatible: 17 + items: 18 + - const: intel,ixp4xx-timer 19 + 20 + reg: 21 + description: Should contain registers location and length 22 + 23 + interrupts: 24 + minItems: 1 25 + maxItems: 2 26 + items: 27 + - description: Timer 1 interrupt 28 + - description: Timer 2 interrupt 29 + 30 + required: 31 + - compatible 32 + - reg 33 + - interrupts 34 + 35 + examples: 36 + - | 37 + #include <dt-bindings/interrupt-controller/irq.h> 38 + timer@c8005000 { 39 + compatible = "intel,ixp4xx-timer"; 40 + reg = <0xc8005000 0x100>; 41 + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; 42 + };
+14 -4
MAINTAINERS
··· 1685 1685 S: Maintained 1686 1686 1687 1687 ARM/INTEL IXP4XX ARM ARCHITECTURE 1688 + M: Linus Walleij <linusw@kernel.org> 1688 1689 M: Imre Kaloz <kaloz@openwrt.org> 1689 1690 M: Krzysztof Halasa <khalasa@piap.pl> 1690 1691 L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 1691 1692 S: Maintained 1693 + F: Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml 1694 + F: Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.txt 1695 + F: Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml 1696 + F: Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml 1692 1697 F: arch/arm/mach-ixp4xx/ 1698 + F: drivers/clocksource/timer-ixp4xx.c 1699 + F: drivers/gpio/gpio-ixp4xx.c 1700 + F: drivers/irqchip/irq-ixp4xx.c 1701 + F: include/linux/irqchip/irq-ixp4xx.h 1702 + F: include/linux/platform_data/timer-ixp4xx.h 1693 1703 1694 1704 ARM/INTEL RESEARCH IMOTE/STARGATE 2 MACHINE SUPPORT 1695 1705 M: Jonathan Cameron <jic23@cam.ac.uk> ··· 7886 7876 INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT 7887 7877 M: Krzysztof Halasa <khalasa@piap.pl> 7888 7878 S: Maintained 7889 - F: arch/arm/mach-ixp4xx/include/mach/qmgr.h 7890 - F: arch/arm/mach-ixp4xx/include/mach/npe.h 7891 - F: arch/arm/mach-ixp4xx/ixp4xx_qmgr.c 7892 - F: arch/arm/mach-ixp4xx/ixp4xx_npe.c 7879 + F: include/linux/soc/ixp4xx/qmgr.h 7880 + F: include/linux/soc/ixp4xx/npe.h 7881 + F: drivers/soc/ixp4xx/ixp4xx-qmgr.c 7882 + F: drivers/soc/ixp4xx/ixp4xx-npe.c 7893 7883 F: drivers/net/ethernet/xscale/ixp4xx_eth.c 7894 7884 F: drivers/net/wan/ixp4xx_hss.c 7895 7885
+4 -1
arch/arm/Kconfig
··· 429 429 depends on MMU 430 430 select ARCH_HAS_DMA_SET_COHERENT_MASK 431 431 select ARCH_SUPPORTS_BIG_ENDIAN 432 - select CLKSRC_MMIO 433 432 select CPU_XSCALE 434 433 select DMABOUNCE if PCI 435 434 select GENERIC_CLOCKEVENTS 435 + select GENERIC_IRQ_MULTI_HANDLER 436 + select GPIO_IXP4XX 436 437 select GPIOLIB 437 438 select HAVE_PCI 439 + select IXP4XX_IRQ 440 + select IXP4XX_TIMER 438 441 select NEED_MACH_IO_H 439 442 select USB_EHCI_BIG_ENDIAN_DESC 440 443 select USB_EHCI_BIG_ENDIAN_MMIO
+3
arch/arm/boot/dts/Makefile
··· 229 229 dtb-$(CONFIG_ARCH_INTEGRATOR) += \ 230 230 integratorap.dtb \ 231 231 integratorcp.dtb 232 + dtb-$(CONFIG_ARCH_IXP4XX) += \ 233 + intel-ixp42x-linksys-nslu2.dtb \ 234 + intel-ixp43x-gateworks-gw2358.dtb 232 235 dtb-$(CONFIG_ARCH_KEYSTONE) += \ 233 236 keystone-k2hk-evm.dtb \ 234 237 keystone-k2l-evm.dtb \
+109
arch/arm/boot/dts/intel-ixp42x-linksys-nslu2.dts
··· 1 + // SPDX-License-Identifier: ISC 2 + /* 3 + * Device Tree file for Linksys NSLU2 4 + */ 5 + 6 + /dts-v1/; 7 + 8 + #include "intel-ixp42x.dtsi" 9 + #include <dt-bindings/input/input.h> 10 + 11 + / { 12 + model = "Linksys NSLU2 (Network Storage Link for USB 2.0 Disk Drives)"; 13 + compatible = "linksys,nslu2", "intel,ixp42x"; 14 + #address-cells = <1>; 15 + #size-cells = <1>; 16 + 17 + memory@0 { 18 + /* 32 MB SDRAM */ 19 + device_type = "memory"; 20 + reg = <0x00000000 0x2000000>; 21 + }; 22 + 23 + chosen { 24 + bootargs = "console=ttyS0,115200n8 root=/dev/mtdblock2 rw rootfstype=squashfs,jffs2 rootwait"; 25 + stdout-path = "uart0:115200n8"; 26 + }; 27 + 28 + aliases { 29 + serial0 = &uart0; 30 + }; 31 + 32 + leds { 33 + compatible = "gpio-leds"; 34 + led-status { 35 + label = "nslu2:red:status"; 36 + gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; 37 + default-state = "on"; 38 + linux,default-trigger = "heartbeat"; 39 + }; 40 + led-ready { 41 + label = "nslu2:green:ready"; 42 + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; 43 + default-state = "on"; 44 + }; 45 + led-disk-1 { 46 + label = "nslu2:green:disk-1"; 47 + gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; 48 + default-state = "off"; 49 + }; 50 + led-disk-2 { 51 + label = "nslu2:green:disk-2"; 52 + gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; 53 + default-state = "off"; 54 + }; 55 + }; 56 + 57 + gpio_keys { 58 + compatible = "gpio-keys"; 59 + 60 + button-power { 61 + wakeup-source; 62 + linux,code = <KEY_POWER>; 63 + label = "power"; 64 + gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; 65 + }; 66 + button-reset { 67 + wakeup-source; 68 + linux,code = <KEY_ESC>; 69 + label = "reset"; 70 + gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; 71 + }; 72 + }; 73 + 74 + i2c { 75 + compatible = "i2c-gpio"; 76 + sda-gpios = <&gpio0 7 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; 77 + scl-gpios = <&gpio0 6 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; 78 + #address-cells = <1>; 79 + #size-cells = <0>; 80 + 81 + rtc@6f { 82 + compatible = "xicor,x1205"; 83 + reg = <0x6f>; 84 + }; 85 + }; 86 + 87 + gpio-poweroff { 88 + compatible = "gpio-poweroff"; 89 + gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; 90 + timeout-ms = <5000>; 91 + }; 92 + 93 + /* The first 16MB region on the expansion bus */ 94 + flash@50000000 { 95 + compatible = "intel,ixp4xx-flash", "cfi-flash"; 96 + bank-width = <2>; 97 + /* 98 + * 8 MB of Flash in 0x20000 byte blocks 99 + * mapped in at 0x50000000 100 + */ 101 + reg = <0x50000000 0x800000>; 102 + 103 + partitions { 104 + compatible = "redboot-fis"; 105 + /* Eraseblock at 0x7e0000 */ 106 + fis-index-block = <0x3f>; 107 + }; 108 + }; 109 + };
+25
arch/arm/boot/dts/intel-ixp42x.dtsi
··· 1 + // SPDX-License-Identifier: ISC 2 + /* 3 + * Device Tree file for Intel XScale Network Processors 4 + * in the IXP 42x series. This series has 32 interrupts. 5 + */ 6 + #include "intel-ixp4xx.dtsi" 7 + 8 + / { 9 + soc { 10 + interrupt-controller@c8003000 { 11 + compatible = "intel,ixp42x-interrupt"; 12 + }; 13 + 14 + /* 15 + * This is the USB Device Mode (UDC) controller, which is used 16 + * to present the IXP4xx as a device on a USB bus. 17 + */ 18 + usb@c800b000 { 19 + compatible = "intel,ixp4xx-udc"; 20 + reg = <0xc800b000 0x1000>; 21 + interrupts = <12 IRQ_TYPE_LEVEL_HIGH>; 22 + status = "disabled"; 23 + }; 24 + }; 25 + };
+94
arch/arm/boot/dts/intel-ixp43x-gateworks-gw2358.dts
··· 1 + // SPDX-License-Identifier: ISC 2 + /* 3 + * Device Tree file for Gateworks IXP43x-based Cambria GW2358 4 + */ 5 + 6 + /dts-v1/; 7 + 8 + #include "intel-ixp43x.dtsi" 9 + 10 + / { 11 + model = "Gateworks Cambria GW2358"; 12 + compatible = "gateworks,gw2358", "intel,ixp43x"; 13 + #address-cells = <1>; 14 + #size-cells = <1>; 15 + 16 + memory@0 { 17 + /* 128 MB SDRAM */ 18 + device_type = "memory"; 19 + reg = <0x00000000 0x8000000>; 20 + }; 21 + 22 + chosen { 23 + bootargs = "console=ttyS0,115200n8 root=/dev/mtdblock2 rw rootfstype=squashfs,jffs2 rootwait"; 24 + stdout-path = "uart0:115200n8"; 25 + }; 26 + 27 + aliases { 28 + serial0 = &uart0; 29 + }; 30 + 31 + leds { 32 + compatible = "gpio-leds"; 33 + led-user { 34 + label = "gw2358:green:LED"; 35 + gpios = <&pld1 0 GPIO_ACTIVE_LOW>; 36 + default-state = "on"; 37 + linux,default-trigger = "heartbeat"; 38 + }; 39 + }; 40 + 41 + 42 + i2c { 43 + compatible = "i2c-gpio"; 44 + sda-gpios = <&gpio0 7 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; 45 + scl-gpios = <&gpio0 6 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; 46 + #address-cells = <1>; 47 + #size-cells = <0>; 48 + 49 + hwmon@28 { 50 + compatible = "adi,ad7418"; 51 + reg = <0x28>; 52 + }; 53 + rtc: ds1672@68 { 54 + compatible = "dallas,ds1672"; 55 + reg = <0x68>; 56 + }; 57 + eeprom@51 { 58 + compatible = "atmel,24c08"; 59 + reg = <0x51>; 60 + pagesize = <16>; 61 + size = <1024>; 62 + read-only; 63 + }; 64 + pld0: pld@56 { 65 + compatible = "gateworks,pld-gpio"; 66 + reg = <0x56>; 67 + gpio-controller; 68 + #gpio-cells = <2>; 69 + }; 70 + /* This PLD just handles the LED and user button */ 71 + pld1: pld@57 { 72 + compatible = "gateworks,pld-gpio"; 73 + reg = <0x57>; 74 + gpio-controller; 75 + #gpio-cells = <2>; 76 + }; 77 + }; 78 + 79 + flash@50000000 { 80 + compatible = "intel,ixp4xx-flash", "cfi-flash"; 81 + bank-width = <2>; 82 + /* 83 + * 32 MB of Flash in 0x20000 byte blocks 84 + * mapped in at 0x50000000 85 + */ 86 + reg = <0x50000000 0x2000000>; 87 + 88 + partitions { 89 + compatible = "redboot-fis"; 90 + /* Eraseblock at 0x1fe0000 */ 91 + fis-index-block = <0xff>; 92 + }; 93 + }; 94 + };
+15
arch/arm/boot/dts/intel-ixp43x.dtsi
··· 1 + // SPDX-License-Identifier: ISC 2 + /* 3 + * Device Tree file for Intel XScale Network Processors 4 + * in the IXP 43x series. This series has 64 interrupts and adds a few more 5 + * peripherals over the 42x series. 6 + */ 7 + #include "intel-ixp4xx.dtsi" 8 + 9 + / { 10 + soc { 11 + interrupt-controller@c8003000 { 12 + compatible = "intel,ixp43x-interrupt"; 13 + }; 14 + }; 15 + };
+34
arch/arm/boot/dts/intel-ixp45x-ixp46x.dtsi
··· 1 + // SPDX-License-Identifier: ISC 2 + /* 3 + * Device Tree file for Intel XScale Network Processors 4 + * in the IXP45x and IXP46x series. This series has 64 interrupts and adds a 5 + * few more peripherals over the 42x and 43x series so this extends the 6 + * basic IXP4xx DTSI. 7 + */ 8 + #include "intel-ixp4xx.dtsi" 9 + 10 + / { 11 + soc { 12 + interrupt-controller@c8003000 { 13 + compatible = "intel,ixp43x-interrupt"; 14 + }; 15 + 16 + /* 17 + * This is the USB Device Mode (UDC) controller, which is used 18 + * to present the IXP4xx as a device on a USB bus. 19 + */ 20 + usb@c800b000 { 21 + compatible = "intel,ixp4xx-udc"; 22 + reg = <0xc800b000 0x1000>; 23 + interrupts = <12 IRQ_TYPE_LEVEL_HIGH>; 24 + status = "disabled"; 25 + }; 26 + 27 + i2c@c8011000 { 28 + compatible = "intel,ixp4xx-i2c"; 29 + reg = <0xc8011000 0x18>; 30 + interrupts = <33 IRQ_TYPE_LEVEL_HIGH>; 31 + status = "disabled"; 32 + }; 33 + }; 34 + };
+69
arch/arm/boot/dts/intel-ixp4xx.dtsi
··· 1 + // SPDX-License-Identifier: ISC 2 + /* 3 + * Device Tree file for Intel XScale Network Processors 4 + * in the IXP 4xx series. 5 + */ 6 + #include <dt-bindings/interrupt-controller/irq.h> 7 + #include <dt-bindings/gpio/gpio.h> 8 + 9 + / { 10 + soc { 11 + #address-cells = <1>; 12 + #size-cells = <1>; 13 + ranges; 14 + compatible = "simple-bus"; 15 + interrupt-parent = <&intcon>; 16 + 17 + qmgr: queue-manager@60000000 { 18 + compatible = "intel,ixp4xx-ahb-queue-manager"; 19 + reg = <0x60000000 0x4000>; 20 + interrupts = <3 IRQ_TYPE_LEVEL_HIGH>, <4 IRQ_TYPE_LEVEL_HIGH>; 21 + }; 22 + 23 + uart0: serial@c8000000 { 24 + compatible = "intel,xscale-uart"; 25 + reg = <0xc8000000 0x1000>; 26 + /* 27 + * The reg-offset and reg-shift is a side effect 28 + * of running the platform in big endian mode. 29 + */ 30 + reg-offset = <3>; 31 + reg-shift = <2>; 32 + interrupts = <15 IRQ_TYPE_LEVEL_HIGH>; 33 + clock-frequency = <14745600>; 34 + no-loopback-test; 35 + }; 36 + 37 + gpio0: gpio@c8004000 { 38 + compatible = "intel,ixp4xx-gpio"; 39 + reg = <0xc8004000 0x1000>; 40 + gpio-controller; 41 + #gpio-cells = <2>; 42 + interrupt-controller; 43 + #interrupt-cells = <2>; 44 + }; 45 + 46 + intcon: interrupt-controller@c8003000 { 47 + /* 48 + * Note: no compatible string. The subvariant of the 49 + * chip needs to define what version it is. The 50 + * location of the interrupt controller is fixed in 51 + * memory across all variants. 52 + */ 53 + reg = <0xc8003000 0x100>; 54 + interrupt-controller; 55 + #interrupt-cells = <2>; 56 + }; 57 + 58 + timer@c8005000 { 59 + compatible = "intel,ixp4xx-timer"; 60 + reg = <0xc8005000 0x100>; 61 + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; 62 + }; 63 + 64 + npe@c8006000 { 65 + compatible = "intel,ixp4xx-network-processing-engine"; 66 + reg = <0xc8006000 0x1000>, <0xc8007000 0x1000>, <0xc8008000 0x1000>; 67 + }; 68 + }; 69 + };
+14 -13
arch/arm/mach-ixp4xx/Kconfig
··· 4 4 5 5 comment "IXP4xx Platforms" 6 6 7 + config MACH_IXP4XX_OF 8 + bool 9 + prompt "Devce Tree IXP4xx boards" 10 + default y 11 + select ARM_APPENDED_DTB # Old Redboot bootloaders deployed 12 + select I2C 13 + select I2C_IOP3XX 14 + select PCI 15 + select SERIAL_OF_PLATFORM 16 + select TIMER_OF 17 + select USE_OF 18 + help 19 + Say 'Y' here to support Device Tree-based IXP4xx platforms. 20 + 7 21 config MACH_NSLU2 8 22 bool 9 23 prompt "Linksys NSLU2" ··· 235 221 By default, the direct method is used. Choose this option if you 236 222 need to use the indirect method instead. If you don't know 237 223 what you need, leave this option unselected. 238 - 239 - config IXP4XX_QMGR 240 - tristate "IXP4xx Queue Manager support" 241 - help 242 - This driver supports IXP4xx built-in hardware queue manager 243 - and is automatically selected by Ethernet and HSS drivers. 244 - 245 - config IXP4XX_NPE 246 - tristate "IXP4xx Network Processor Engine support" 247 - select FW_LOADER 248 - help 249 - This driver supports IXP4xx built-in network coprocessors 250 - and is automatically selected by Ethernet and HSS drivers. 251 224 252 225 endmenu 253 226
+3 -2
arch/arm/mach-ixp4xx/Makefile
··· 6 6 obj-pci-y := 7 7 obj-pci-n := 8 8 9 + # Device tree platform 10 + obj-pci-$(CONFIG_MACH_IXP4XX_OF) += ixp4xx-of.o 11 + 9 12 obj-pci-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o 10 13 obj-pci-$(CONFIG_MACH_AVILA) += avila-pci.o 11 14 obj-pci-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o ··· 43 40 obj-$(CONFIG_MACH_ARCOM_VULCAN) += vulcan-setup.o 44 41 45 42 obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o 46 - obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx_qmgr.o 47 - obj-$(CONFIG_IXP4XX_NPE) += ixp4xx_npe.o
+2
arch/arm/mach-ixp4xx/avila-pci.c
··· 27 27 #include <mach/hardware.h> 28 28 #include <asm/mach-types.h> 29 29 30 + #include "irqs.h" 31 + 30 32 #define AVILA_MAX_DEV 4 31 33 #define LOFT_MAX_DEV 6 32 34 #define IRQ_LINES 4
+2
arch/arm/mach-ixp4xx/avila-setup.c
··· 28 28 #include <asm/mach/arch.h> 29 29 #include <asm/mach/flash.h> 30 30 31 + #include "irqs.h" 32 + 31 33 #define AVILA_SDA_PIN 7 32 34 #define AVILA_SCL_PIN 6 33 35
+83 -401
arch/arm/mach-ixp4xx/common.c
··· 22 22 #include <linux/serial_core.h> 23 23 #include <linux/interrupt.h> 24 24 #include <linux/bitops.h> 25 - #include <linux/time.h> 26 - #include <linux/clocksource.h> 27 - #include <linux/clockchips.h> 28 25 #include <linux/io.h> 29 26 #include <linux/export.h> 30 - #include <linux/gpio/driver.h> 31 27 #include <linux/cpu.h> 32 28 #include <linux/pci.h> 33 29 #include <linux/sched_clock.h> 30 + #include <linux/bitops.h> 31 + #include <linux/irqchip/irq-ixp4xx.h> 32 + #include <linux/platform_data/timer-ixp4xx.h> 34 33 #include <mach/udc.h> 35 34 #include <mach/hardware.h> 36 35 #include <mach/io.h> 37 36 #include <linux/uaccess.h> 38 37 #include <asm/pgtable.h> 39 38 #include <asm/page.h> 39 + #include <asm/exception.h> 40 40 #include <asm/irq.h> 41 41 #include <asm/system_misc.h> 42 42 #include <asm/mach/map.h> 43 43 #include <asm/mach/irq.h> 44 44 #include <asm/mach/time.h> 45 45 46 + #include "irqs.h" 47 + 46 48 #define IXP4XX_TIMER_FREQ 66666000 47 - 48 - /* 49 - * The timer register doesn't allow to specify the two least significant bits of 50 - * the timeout value and assumes them being zero. So make sure IXP4XX_LATCH is 51 - * the best value with the two least significant bits unset. 52 - */ 53 - #define IXP4XX_LATCH DIV_ROUND_CLOSEST(IXP4XX_TIMER_FREQ, \ 54 - (IXP4XX_OST_RELOAD_MASK + 1) * HZ) * \ 55 - (IXP4XX_OST_RELOAD_MASK + 1) 56 - 57 - static void __init ixp4xx_clocksource_init(void); 58 - static void __init ixp4xx_clockevent_init(void); 59 - static struct clock_event_device clockevent_ixp4xx; 60 49 61 50 /************************************************************************* 62 51 * IXP4xx chipset I/O mapping ··· 66 77 .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS), 67 78 .length = IXP4XX_PCI_CFG_REGION_SIZE, 68 79 .type = MT_DEVICE 69 - }, { /* Queue Manager */ 70 - .virtual = (unsigned long)IXP4XX_QMGR_BASE_VIRT, 71 - .pfn = __phys_to_pfn(IXP4XX_QMGR_BASE_PHYS), 72 - .length = IXP4XX_QMGR_REGION_SIZE, 73 - .type = MT_DEVICE 74 80 }, 75 81 }; 76 82 ··· 74 90 iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc)); 75 91 } 76 92 77 - /* 78 - * GPIO-functions 79 - */ 80 - /* 81 - * The following converted to the real HW bits the gpio_line_config 82 - */ 83 - /* GPIO pin types */ 84 - #define IXP4XX_GPIO_OUT 0x1 85 - #define IXP4XX_GPIO_IN 0x2 86 - 87 - /* GPIO signal types */ 88 - #define IXP4XX_GPIO_LOW 0 89 - #define IXP4XX_GPIO_HIGH 1 90 - 91 - /* GPIO Clocks */ 92 - #define IXP4XX_GPIO_CLK_0 14 93 - #define IXP4XX_GPIO_CLK_1 15 94 - 95 - static void gpio_line_config(u8 line, u32 direction) 96 - { 97 - if (direction == IXP4XX_GPIO_IN) 98 - *IXP4XX_GPIO_GPOER |= (1 << line); 99 - else 100 - *IXP4XX_GPIO_GPOER &= ~(1 << line); 101 - } 102 - 103 - static void gpio_line_get(u8 line, int *value) 104 - { 105 - *value = (*IXP4XX_GPIO_GPINR >> line) & 0x1; 106 - } 107 - 108 - static void gpio_line_set(u8 line, int value) 109 - { 110 - if (value == IXP4XX_GPIO_HIGH) 111 - *IXP4XX_GPIO_GPOUTR |= (1 << line); 112 - else if (value == IXP4XX_GPIO_LOW) 113 - *IXP4XX_GPIO_GPOUTR &= ~(1 << line); 114 - } 115 - 116 - /************************************************************************* 117 - * IXP4xx chipset IRQ handling 118 - * 119 - * TODO: GPIO IRQs should be marked invalid until the user of the IRQ 120 - * (be it PCI or something else) configures that GPIO line 121 - * as an IRQ. 122 - **************************************************************************/ 123 - enum ixp4xx_irq_type { 124 - IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE 125 - }; 126 - 127 - /* Each bit represents an IRQ: 1: edge-triggered, 0: level triggered */ 128 - static unsigned long long ixp4xx_irq_edge = 0; 129 - 130 - /* 131 - * IRQ -> GPIO mapping table 132 - */ 133 - static signed char irq2gpio[32] = { 134 - -1, -1, -1, -1, -1, -1, 0, 1, 135 - -1, -1, -1, -1, -1, -1, -1, -1, 136 - -1, -1, -1, 2, 3, 4, 5, 6, 137 - 7, 8, 9, 10, 11, 12, -1, -1, 138 - }; 139 - 140 - static int ixp4xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) 141 - { 142 - int irq; 143 - 144 - for (irq = 0; irq < 32; irq++) { 145 - if (irq2gpio[irq] == gpio) 146 - return irq; 147 - } 148 - return -EINVAL; 149 - } 150 - 151 - static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type) 152 - { 153 - int line = irq2gpio[d->irq]; 154 - u32 int_style; 155 - enum ixp4xx_irq_type irq_type; 156 - volatile u32 *int_reg; 157 - 158 - /* 159 - * Only for GPIO IRQs 160 - */ 161 - if (line < 0) 162 - return -EINVAL; 163 - 164 - switch (type){ 165 - case IRQ_TYPE_EDGE_BOTH: 166 - int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL; 167 - irq_type = IXP4XX_IRQ_EDGE; 168 - break; 169 - case IRQ_TYPE_EDGE_RISING: 170 - int_style = IXP4XX_GPIO_STYLE_RISING_EDGE; 171 - irq_type = IXP4XX_IRQ_EDGE; 172 - break; 173 - case IRQ_TYPE_EDGE_FALLING: 174 - int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE; 175 - irq_type = IXP4XX_IRQ_EDGE; 176 - break; 177 - case IRQ_TYPE_LEVEL_HIGH: 178 - int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH; 179 - irq_type = IXP4XX_IRQ_LEVEL; 180 - break; 181 - case IRQ_TYPE_LEVEL_LOW: 182 - int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW; 183 - irq_type = IXP4XX_IRQ_LEVEL; 184 - break; 185 - default: 186 - return -EINVAL; 187 - } 188 - 189 - if (irq_type == IXP4XX_IRQ_EDGE) 190 - ixp4xx_irq_edge |= (1 << d->irq); 191 - else 192 - ixp4xx_irq_edge &= ~(1 << d->irq); 193 - 194 - if (line >= 8) { /* pins 8-15 */ 195 - line -= 8; 196 - int_reg = IXP4XX_GPIO_GPIT2R; 197 - } else { /* pins 0-7 */ 198 - int_reg = IXP4XX_GPIO_GPIT1R; 199 - } 200 - 201 - /* Clear the style for the appropriate pin */ 202 - *int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR << 203 - (line * IXP4XX_GPIO_STYLE_SIZE)); 204 - 205 - *IXP4XX_GPIO_GPISR = (1 << line); 206 - 207 - /* Set the new style */ 208 - *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE)); 209 - 210 - /* Configure the line as an input */ 211 - gpio_line_config(irq2gpio[d->irq], IXP4XX_GPIO_IN); 212 - 213 - return 0; 214 - } 215 - 216 - static void ixp4xx_irq_mask(struct irq_data *d) 217 - { 218 - if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->irq >= 32) 219 - *IXP4XX_ICMR2 &= ~(1 << (d->irq - 32)); 220 - else 221 - *IXP4XX_ICMR &= ~(1 << d->irq); 222 - } 223 - 224 - static void ixp4xx_irq_ack(struct irq_data *d) 225 - { 226 - int line = (d->irq < 32) ? irq2gpio[d->irq] : -1; 227 - 228 - if (line >= 0) 229 - *IXP4XX_GPIO_GPISR = (1 << line); 230 - } 231 - 232 - /* 233 - * Level triggered interrupts on GPIO lines can only be cleared when the 234 - * interrupt condition disappears. 235 - */ 236 - static void ixp4xx_irq_unmask(struct irq_data *d) 237 - { 238 - if (!(ixp4xx_irq_edge & (1 << d->irq))) 239 - ixp4xx_irq_ack(d); 240 - 241 - if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->irq >= 32) 242 - *IXP4XX_ICMR2 |= (1 << (d->irq - 32)); 243 - else 244 - *IXP4XX_ICMR |= (1 << d->irq); 245 - } 246 - 247 - static struct irq_chip ixp4xx_irq_chip = { 248 - .name = "IXP4xx", 249 - .irq_ack = ixp4xx_irq_ack, 250 - .irq_mask = ixp4xx_irq_mask, 251 - .irq_unmask = ixp4xx_irq_unmask, 252 - .irq_set_type = ixp4xx_set_irq_type, 253 - }; 254 - 255 93 void __init ixp4xx_init_irq(void) 256 94 { 257 - int i = 0; 258 - 259 95 /* 260 96 * ixp4xx does not implement the XScale PWRMODE register 261 97 * so it must not call cpu_do_idle(). 262 98 */ 263 99 cpu_idle_poll_ctrl(true); 264 100 265 - /* Route all sources to IRQ instead of FIQ */ 266 - *IXP4XX_ICLR = 0x0; 267 - 268 - /* Disable all interrupt */ 269 - *IXP4XX_ICMR = 0x0; 270 - 271 - if (cpu_is_ixp46x() || cpu_is_ixp43x()) { 272 - /* Route upper 32 sources to IRQ instead of FIQ */ 273 - *IXP4XX_ICLR2 = 0x00; 274 - 275 - /* Disable upper 32 interrupts */ 276 - *IXP4XX_ICMR2 = 0x00; 277 - } 278 - 279 - /* Default to all level triggered */ 280 - for(i = 0; i < NR_IRQS; i++) { 281 - irq_set_chip_and_handler(i, &ixp4xx_irq_chip, 282 - handle_level_irq); 283 - irq_clear_status_flags(i, IRQ_NOREQUEST); 284 - } 101 + ixp4xx_irq_init(IXP4XX_INTC_BASE_PHYS, 102 + (cpu_is_ixp46x() || cpu_is_ixp43x())); 285 103 } 286 - 287 - 288 - /************************************************************************* 289 - * IXP4xx timer tick 290 - * We use OS timer1 on the CPU for the timer tick and the timestamp 291 - * counter as a source of real clock ticks to account for missed jiffies. 292 - *************************************************************************/ 293 - 294 - static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id) 295 - { 296 - struct clock_event_device *evt = dev_id; 297 - 298 - /* Clear Pending Interrupt by writing '1' to it */ 299 - *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; 300 - 301 - evt->event_handler(evt); 302 - 303 - return IRQ_HANDLED; 304 - } 305 - 306 - static struct irqaction ixp4xx_timer_irq = { 307 - .name = "timer1", 308 - .flags = IRQF_TIMER | IRQF_IRQPOLL, 309 - .handler = ixp4xx_timer_interrupt, 310 - .dev_id = &clockevent_ixp4xx, 311 - }; 312 104 313 105 void __init ixp4xx_timer_init(void) 314 106 { 315 - /* Reset/disable counter */ 316 - *IXP4XX_OSRT1 = 0; 317 - 318 - /* Clear Pending Interrupt by writing '1' to it */ 319 - *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; 320 - 321 - /* Reset time-stamp counter */ 322 - *IXP4XX_OSTS = 0; 323 - 324 - /* Connect the interrupt handler and enable the interrupt */ 325 - setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq); 326 - 327 - ixp4xx_clocksource_init(); 328 - ixp4xx_clockevent_init(); 107 + return ixp4xx_timer_setup(IXP4XX_TIMER_BASE_PHYS, 108 + IRQ_IXP4XX_TIMER1, 109 + IXP4XX_TIMER_FREQ); 329 110 } 330 111 331 112 static struct pxa2xx_udc_mach_info ixp4xx_udc_info; ··· 113 364 }, 114 365 }; 115 366 367 + static struct resource ixp4xx_gpio_resource[] = { 368 + { 369 + .start = IXP4XX_GPIO_BASE_PHYS, 370 + .end = IXP4XX_GPIO_BASE_PHYS + 0xfff, 371 + .flags = IORESOURCE_MEM, 372 + }, 373 + }; 374 + 375 + static struct platform_device ixp4xx_gpio_device = { 376 + .name = "ixp4xx-gpio", 377 + .id = -1, 378 + .dev = { 379 + .coherent_dma_mask = DMA_BIT_MASK(32), 380 + }, 381 + .resource = ixp4xx_gpio_resource, 382 + .num_resources = ARRAY_SIZE(ixp4xx_gpio_resource), 383 + }; 384 + 116 385 /* 117 386 * USB device controller. The IXP4xx uses the same controller as PXA25X, 118 387 * so we just use the same device. ··· 145 378 }, 146 379 }; 147 380 381 + static struct resource ixp4xx_npe_resources[] = { 382 + { 383 + .start = IXP4XX_NPEA_BASE_PHYS, 384 + .end = IXP4XX_NPEA_BASE_PHYS + 0xfff, 385 + .flags = IORESOURCE_MEM, 386 + }, 387 + { 388 + .start = IXP4XX_NPEB_BASE_PHYS, 389 + .end = IXP4XX_NPEB_BASE_PHYS + 0xfff, 390 + .flags = IORESOURCE_MEM, 391 + }, 392 + { 393 + .start = IXP4XX_NPEC_BASE_PHYS, 394 + .end = IXP4XX_NPEC_BASE_PHYS + 0xfff, 395 + .flags = IORESOURCE_MEM, 396 + }, 397 + 398 + }; 399 + 400 + static struct platform_device ixp4xx_npe_device = { 401 + .name = "ixp4xx-npe", 402 + .id = -1, 403 + .num_resources = ARRAY_SIZE(ixp4xx_npe_resources), 404 + .resource = ixp4xx_npe_resources, 405 + }; 406 + 407 + static struct resource ixp4xx_qmgr_resources[] = { 408 + { 409 + .start = IXP4XX_QMGR_BASE_PHYS, 410 + .end = IXP4XX_QMGR_BASE_PHYS + 0x3fff, 411 + .flags = IORESOURCE_MEM, 412 + }, 413 + { 414 + .start = IRQ_IXP4XX_QM1, 415 + .end = IRQ_IXP4XX_QM1, 416 + .flags = IORESOURCE_IRQ, 417 + }, 418 + { 419 + .start = IRQ_IXP4XX_QM2, 420 + .end = IRQ_IXP4XX_QM2, 421 + .flags = IORESOURCE_IRQ, 422 + }, 423 + }; 424 + 425 + static struct platform_device ixp4xx_qmgr_device = { 426 + .name = "ixp4xx-qmgr", 427 + .id = -1, 428 + .num_resources = ARRAY_SIZE(ixp4xx_qmgr_resources), 429 + .resource = ixp4xx_qmgr_resources, 430 + }; 431 + 148 432 static struct platform_device *ixp4xx_devices[] __initdata = { 433 + &ixp4xx_npe_device, 434 + &ixp4xx_qmgr_device, 435 + &ixp4xx_gpio_device, 149 436 &ixp4xx_udc_device, 150 437 }; 151 438 ··· 234 413 unsigned long ixp4xx_exp_bus_size; 235 414 EXPORT_SYMBOL(ixp4xx_exp_bus_size); 236 415 237 - static int ixp4xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) 238 - { 239 - gpio_line_config(gpio, IXP4XX_GPIO_IN); 240 - 241 - return 0; 242 - } 243 - 244 - static int ixp4xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, 245 - int level) 246 - { 247 - gpio_line_set(gpio, level); 248 - gpio_line_config(gpio, IXP4XX_GPIO_OUT); 249 - 250 - return 0; 251 - } 252 - 253 - static int ixp4xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio) 254 - { 255 - int value; 256 - 257 - gpio_line_get(gpio, &value); 258 - 259 - return value; 260 - } 261 - 262 - static void ixp4xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, 263 - int value) 264 - { 265 - gpio_line_set(gpio, value); 266 - } 267 - 268 - static struct gpio_chip ixp4xx_gpio_chip = { 269 - .label = "IXP4XX_GPIO_CHIP", 270 - .direction_input = ixp4xx_gpio_direction_input, 271 - .direction_output = ixp4xx_gpio_direction_output, 272 - .get = ixp4xx_gpio_get_value, 273 - .set = ixp4xx_gpio_set_value, 274 - .to_irq = ixp4xx_gpio_to_irq, 275 - .base = 0, 276 - .ngpio = 16, 277 - }; 278 - 279 416 void __init ixp4xx_sys_init(void) 280 417 { 281 418 ixp4xx_exp_bus_size = SZ_16M; 282 419 283 420 platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices)); 284 - 285 - gpiochip_add_data(&ixp4xx_gpio_chip, NULL); 286 421 287 422 if (cpu_is_ixp46x()) { 288 423 int region; ··· 258 481 ixp4xx_exp_bus_size >> 20); 259 482 } 260 483 261 - /* 262 - * sched_clock() 263 - */ 264 - static u64 notrace ixp4xx_read_sched_clock(void) 265 - { 266 - return *IXP4XX_OSTS; 267 - } 268 - 269 - /* 270 - * clocksource 271 - */ 272 - 273 - static u64 ixp4xx_clocksource_read(struct clocksource *c) 274 - { 275 - return *IXP4XX_OSTS; 276 - } 277 - 278 484 unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ; 279 485 EXPORT_SYMBOL(ixp4xx_timer_freq); 280 - static void __init ixp4xx_clocksource_init(void) 281 - { 282 - sched_clock_register(ixp4xx_read_sched_clock, 32, ixp4xx_timer_freq); 283 - 284 - clocksource_mmio_init(NULL, "OSTS", ixp4xx_timer_freq, 200, 32, 285 - ixp4xx_clocksource_read); 286 - } 287 - 288 - /* 289 - * clockevents 290 - */ 291 - static int ixp4xx_set_next_event(unsigned long evt, 292 - struct clock_event_device *unused) 293 - { 294 - unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK; 295 - 296 - *IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK) | opts; 297 - 298 - return 0; 299 - } 300 - 301 - static int ixp4xx_shutdown(struct clock_event_device *evt) 302 - { 303 - unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK; 304 - unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK; 305 - 306 - opts &= ~IXP4XX_OST_ENABLE; 307 - *IXP4XX_OSRT1 = osrt | opts; 308 - return 0; 309 - } 310 - 311 - static int ixp4xx_set_oneshot(struct clock_event_device *evt) 312 - { 313 - unsigned long opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT; 314 - unsigned long osrt = 0; 315 - 316 - /* period set by 'set next_event' */ 317 - *IXP4XX_OSRT1 = osrt | opts; 318 - return 0; 319 - } 320 - 321 - static int ixp4xx_set_periodic(struct clock_event_device *evt) 322 - { 323 - unsigned long opts = IXP4XX_OST_ENABLE; 324 - unsigned long osrt = IXP4XX_LATCH & ~IXP4XX_OST_RELOAD_MASK; 325 - 326 - *IXP4XX_OSRT1 = osrt | opts; 327 - return 0; 328 - } 329 - 330 - static int ixp4xx_resume(struct clock_event_device *evt) 331 - { 332 - unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK; 333 - unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK; 334 - 335 - opts |= IXP4XX_OST_ENABLE; 336 - *IXP4XX_OSRT1 = osrt | opts; 337 - return 0; 338 - } 339 - 340 - static struct clock_event_device clockevent_ixp4xx = { 341 - .name = "ixp4xx timer1", 342 - .features = CLOCK_EVT_FEAT_PERIODIC | 343 - CLOCK_EVT_FEAT_ONESHOT, 344 - .rating = 200, 345 - .set_state_shutdown = ixp4xx_shutdown, 346 - .set_state_periodic = ixp4xx_set_periodic, 347 - .set_state_oneshot = ixp4xx_set_oneshot, 348 - .tick_resume = ixp4xx_resume, 349 - .set_next_event = ixp4xx_set_next_event, 350 - }; 351 - 352 - static void __init ixp4xx_clockevent_init(void) 353 - { 354 - clockevent_ixp4xx.cpumask = cpumask_of(0); 355 - clockevents_config_and_register(&clockevent_ixp4xx, IXP4XX_TIMER_FREQ, 356 - 0xf, 0xfffffffe); 357 - } 358 486 359 487 void ixp4xx_restart(enum reboot_mode mode, const char *cmd) 360 488 {
+2
arch/arm/mach-ixp4xx/coyote-pci.c
··· 23 23 #include <asm/irq.h> 24 24 #include <asm/mach/pci.h> 25 25 26 + #include "irqs.h" 27 + 26 28 #define SLOT0_DEVID 14 27 29 #define SLOT1_DEVID 15 28 30
+2
arch/arm/mach-ixp4xx/coyote-setup.c
··· 25 25 #include <asm/mach/arch.h> 26 26 #include <asm/mach/flash.h> 27 27 28 + #include "irqs.h" 29 + 28 30 #define COYOTE_IDE_BASE_PHYS IXP4XX_EXP_BUS_BASE(3) 29 31 #define COYOTE_IDE_BASE_VIRT 0xFFFE1000 30 32 #define COYOTE_IDE_REGION_SIZE 0x1000
+2
arch/arm/mach-ixp4xx/dsmg600-pci.c
··· 22 22 #include <asm/mach/pci.h> 23 23 #include <asm/mach-types.h> 24 24 25 + #include "irqs.h" 26 + 25 27 #define MAX_DEV 4 26 28 #define IRQ_LINES 3 27 29
+2 -3
arch/arm/mach-ixp4xx/dsmg600-setup.c
··· 35 35 #include <asm/mach/flash.h> 36 36 #include <asm/mach/time.h> 37 37 38 + #include "irqs.h" 39 + 38 40 #define DSMG600_SDA_PIN 5 39 41 #define DSMG600_SCL_PIN 4 40 42 ··· 269 267 static void __init dsmg600_init(void) 270 268 { 271 269 ixp4xx_sys_init(); 272 - 273 - /* Make sure that GPIO14 and GPIO15 are not used as clocks */ 274 - *IXP4XX_GPIO_GPCLKR = 0; 275 270 276 271 dsmg600_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); 277 272 dsmg600_flash_resource.end =
+2
arch/arm/mach-ixp4xx/fsg-pci.c
··· 22 22 #include <asm/mach/pci.h> 23 23 #include <asm/mach-types.h> 24 24 25 + #include "irqs.h" 26 + 25 27 #define MAX_DEV 3 26 28 #define IRQ_LINES 3 27 29
+2
arch/arm/mach-ixp4xx/fsg-setup.c
··· 29 29 #include <asm/mach/arch.h> 30 30 #include <asm/mach/flash.h> 31 31 32 + #include "irqs.h" 33 + 32 34 #define FSG_SDA_PIN 12 33 35 #define FSG_SCL_PIN 13 34 36
+2
arch/arm/mach-ixp4xx/gateway7001-pci.c
··· 27 27 28 28 #include <asm/mach/pci.h> 29 29 30 + #include "irqs.h" 31 + 30 32 void __init gateway7001_pci_preinit(void) 31 33 { 32 34 irq_set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW);
+2
arch/arm/mach-ixp4xx/gateway7001-setup.c
··· 28 28 #include <asm/mach/arch.h> 29 29 #include <asm/mach/flash.h> 30 30 31 + #include "irqs.h" 32 + 31 33 static struct flash_platform_data gateway7001_flash_data = { 32 34 .map_name = "cfi_probe", 33 35 .width = 2,
+2
arch/arm/mach-ixp4xx/gtwx5715-pci.c
··· 30 30 #include <mach/hardware.h> 31 31 #include <asm/mach/pci.h> 32 32 33 + #include "irqs.h" 34 + 33 35 #define SLOT0_DEVID 0 34 36 #define SLOT1_DEVID 1 35 37 #define INTA 10 /* slot 1 has INTA and INTB crossed */
+2
arch/arm/mach-ixp4xx/gtwx5715-setup.c
··· 36 36 #include <asm/mach/arch.h> 37 37 #include <asm/mach/flash.h> 38 38 39 + #include "irqs.h" 40 + 39 41 /* GPIO 5,6,7 and 12 are hard wired to the Kendin KS8995M Switch 40 42 and operate as an SPI type interface. The details of the interface 41 43 are available on Kendin/Micrel's web site. */
-41
arch/arm/mach-ixp4xx/include/mach/entry-macro.S
··· 1 - /* 2 - * arch/arm/mach-ixp4xx/include/mach/entry-macro.S 3 - * 4 - * Low-level IRQ helper macros for IXP4xx-based platforms 5 - * 6 - * This file is licensed under the terms of the GNU General Public 7 - * License version 2. This program is licensed "as is" without any 8 - * warranty of any kind, whether express or implied. 9 - */ 10 - #include <mach/hardware.h> 11 - 12 - .macro get_irqnr_preamble, base, tmp 13 - .endm 14 - 15 - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp 16 - ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET) 17 - ldr \irqstat, [\irqstat] @ get interrupts 18 - cmp \irqstat, #0 19 - beq 1001f @ upper IRQ? 20 - clz \irqnr, \irqstat 21 - mov \base, #31 22 - sub \irqnr, \base, \irqnr 23 - b 1002f @ lower IRQ being 24 - @ handled 25 - 26 - 1001: 27 - /* 28 - * IXP465/IXP435 has an upper IRQ status register 29 - */ 30 - #if defined(CONFIG_CPU_IXP46X) || defined(CONFIG_CPU_IXP43X) 31 - ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP2_OFFSET) 32 - ldr \irqstat, [\irqstat] @ get upper interrupts 33 - mov \irqnr, #63 34 - clz \irqstat, \irqstat 35 - cmp \irqstat, #32 36 - subne \irqnr, \irqnr, \irqstat 37 - #endif 38 - 1002: 39 - .endm 40 - 41 -
-75
arch/arm/mach-ixp4xx/include/mach/irqs.h
··· 1 - /* 2 - * arch/arm/mach-ixp4xx/include/mach/irqs.h 3 - * 4 - * IRQ definitions for IXP4XX based systems 5 - * 6 - * Copyright (C) 2002 Intel Corporation. 7 - * Copyright (C) 2003 MontaVista Software, Inc. 8 - * 9 - * This program is free software; you can redistribute it and/or modify 10 - * it under the terms of the GNU General Public License version 2 as 11 - * published by the Free Software Foundation. 12 - * 13 - */ 14 - 15 - #ifndef _ARCH_IXP4XX_IRQS_H_ 16 - #define _ARCH_IXP4XX_IRQS_H_ 17 - 18 - #define IRQ_IXP4XX_NPEA 0 19 - #define IRQ_IXP4XX_NPEB 1 20 - #define IRQ_IXP4XX_NPEC 2 21 - #define IRQ_IXP4XX_QM1 3 22 - #define IRQ_IXP4XX_QM2 4 23 - #define IRQ_IXP4XX_TIMER1 5 24 - #define IRQ_IXP4XX_GPIO0 6 25 - #define IRQ_IXP4XX_GPIO1 7 26 - #define IRQ_IXP4XX_PCI_INT 8 27 - #define IRQ_IXP4XX_PCI_DMA1 9 28 - #define IRQ_IXP4XX_PCI_DMA2 10 29 - #define IRQ_IXP4XX_TIMER2 11 30 - #define IRQ_IXP4XX_USB 12 31 - #define IRQ_IXP4XX_UART2 13 32 - #define IRQ_IXP4XX_TIMESTAMP 14 33 - #define IRQ_IXP4XX_UART1 15 34 - #define IRQ_IXP4XX_WDOG 16 35 - #define IRQ_IXP4XX_AHB_PMU 17 36 - #define IRQ_IXP4XX_XSCALE_PMU 18 37 - #define IRQ_IXP4XX_GPIO2 19 38 - #define IRQ_IXP4XX_GPIO3 20 39 - #define IRQ_IXP4XX_GPIO4 21 40 - #define IRQ_IXP4XX_GPIO5 22 41 - #define IRQ_IXP4XX_GPIO6 23 42 - #define IRQ_IXP4XX_GPIO7 24 43 - #define IRQ_IXP4XX_GPIO8 25 44 - #define IRQ_IXP4XX_GPIO9 26 45 - #define IRQ_IXP4XX_GPIO10 27 46 - #define IRQ_IXP4XX_GPIO11 28 47 - #define IRQ_IXP4XX_GPIO12 29 48 - #define IRQ_IXP4XX_SW_INT1 30 49 - #define IRQ_IXP4XX_SW_INT2 31 50 - #define IRQ_IXP4XX_USB_HOST 32 51 - #define IRQ_IXP4XX_I2C 33 52 - #define IRQ_IXP4XX_SSP 34 53 - #define IRQ_IXP4XX_TSYNC 35 54 - #define IRQ_IXP4XX_EAU_DONE 36 55 - #define IRQ_IXP4XX_SHA_DONE 37 56 - #define IRQ_IXP4XX_SWCP_PE 58 57 - #define IRQ_IXP4XX_QM_PE 60 58 - #define IRQ_IXP4XX_MCU_ECC 61 59 - #define IRQ_IXP4XX_EXP_PE 62 60 - 61 - #define _IXP4XX_GPIO_IRQ(n) (IRQ_IXP4XX_GPIO ## n) 62 - #define IXP4XX_GPIO_IRQ(n) _IXP4XX_GPIO_IRQ(n) 63 - 64 - /* 65 - * Only first 32 sources are valid if running on IXP42x systems 66 - */ 67 - #if defined(CONFIG_CPU_IXP46X) || defined(CONFIG_CPU_IXP43X) 68 - #define NR_IRQS 64 69 - #else 70 - #define NR_IRQS 32 71 - #endif 72 - 73 - #define XSCALE_PMU_IRQ (IRQ_IXP4XX_XSCALE_PMU) 74 - 75 - #endif
-94
arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
··· 43 43 * Queue Manager 44 44 */ 45 45 #define IXP4XX_QMGR_BASE_PHYS 0x60000000 46 - #define IXP4XX_QMGR_BASE_VIRT IOMEM(0xFEF15000) 47 - #define IXP4XX_QMGR_REGION_SIZE 0x00004000 48 46 49 47 /* 50 48 * Peripheral space, including debug UART. Must be section-aligned so that ··· 130 132 #define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000) 131 133 #define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000) 132 134 #define IXP4XX_TIMER_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000) 133 - #define IXP4XX_NPEA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x6000) 134 - #define IXP4XX_NPEB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x7000) 135 - #define IXP4XX_NPEC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x8000) 136 135 #define IXP4XX_EthB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000) 137 136 #define IXP4XX_EthC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000) 138 137 #define IXP4XX_USB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000) ··· 141 146 #define IXP4XX_TIMESYNC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x10000) 142 147 #define IXP4XX_I2C_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x11000) 143 148 #define IXP4XX_SSP_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x12000) 144 - 145 - /* 146 - * Constants to make it easy to access Interrupt Controller registers 147 - */ 148 - #define IXP4XX_ICPR_OFFSET 0x00 /* Interrupt Status */ 149 - #define IXP4XX_ICMR_OFFSET 0x04 /* Interrupt Enable */ 150 - #define IXP4XX_ICLR_OFFSET 0x08 /* Interrupt IRQ/FIQ Select */ 151 - #define IXP4XX_ICIP_OFFSET 0x0C /* IRQ Status */ 152 - #define IXP4XX_ICFP_OFFSET 0x10 /* FIQ Status */ 153 - #define IXP4XX_ICHR_OFFSET 0x14 /* Interrupt Priority */ 154 - #define IXP4XX_ICIH_OFFSET 0x18 /* IRQ Highest Pri Int */ 155 - #define IXP4XX_ICFH_OFFSET 0x1C /* FIQ Highest Pri Int */ 156 - 157 - /* 158 - * IXP465-only 159 - */ 160 - #define IXP4XX_ICPR2_OFFSET 0x20 /* Interrupt Status 2 */ 161 - #define IXP4XX_ICMR2_OFFSET 0x24 /* Interrupt Enable 2 */ 162 - #define IXP4XX_ICLR2_OFFSET 0x28 /* Interrupt IRQ/FIQ Select 2 */ 163 - #define IXP4XX_ICIP2_OFFSET 0x2C /* IRQ Status */ 164 - #define IXP4XX_ICFP2_OFFSET 0x30 /* FIQ Status */ 165 - #define IXP4XX_ICEEN_OFFSET 0x34 /* Error High Pri Enable */ 166 - 167 - 168 - /* 169 - * Interrupt Controller Register Definitions. 170 - */ 171 - 172 - #define IXP4XX_INTC_REG(x) ((volatile u32 *)(IXP4XX_INTC_BASE_VIRT+(x))) 173 - 174 - #define IXP4XX_ICPR IXP4XX_INTC_REG(IXP4XX_ICPR_OFFSET) 175 - #define IXP4XX_ICMR IXP4XX_INTC_REG(IXP4XX_ICMR_OFFSET) 176 - #define IXP4XX_ICLR IXP4XX_INTC_REG(IXP4XX_ICLR_OFFSET) 177 - #define IXP4XX_ICIP IXP4XX_INTC_REG(IXP4XX_ICIP_OFFSET) 178 - #define IXP4XX_ICFP IXP4XX_INTC_REG(IXP4XX_ICFP_OFFSET) 179 - #define IXP4XX_ICHR IXP4XX_INTC_REG(IXP4XX_ICHR_OFFSET) 180 - #define IXP4XX_ICIH IXP4XX_INTC_REG(IXP4XX_ICIH_OFFSET) 181 - #define IXP4XX_ICFH IXP4XX_INTC_REG(IXP4XX_ICFH_OFFSET) 182 - #define IXP4XX_ICPR2 IXP4XX_INTC_REG(IXP4XX_ICPR2_OFFSET) 183 - #define IXP4XX_ICMR2 IXP4XX_INTC_REG(IXP4XX_ICMR2_OFFSET) 184 - #define IXP4XX_ICLR2 IXP4XX_INTC_REG(IXP4XX_ICLR2_OFFSET) 185 - #define IXP4XX_ICIP2 IXP4XX_INTC_REG(IXP4XX_ICIP2_OFFSET) 186 - #define IXP4XX_ICFP2 IXP4XX_INTC_REG(IXP4XX_ICFP2_OFFSET) 187 - #define IXP4XX_ICEEN IXP4XX_INTC_REG(IXP4XX_ICEEN_OFFSET) 188 - 189 - /* 190 - * Constants to make it easy to access GPIO registers 191 - */ 192 - #define IXP4XX_GPIO_GPOUTR_OFFSET 0x00 193 - #define IXP4XX_GPIO_GPOER_OFFSET 0x04 194 - #define IXP4XX_GPIO_GPINR_OFFSET 0x08 195 - #define IXP4XX_GPIO_GPISR_OFFSET 0x0C 196 - #define IXP4XX_GPIO_GPIT1R_OFFSET 0x10 197 - #define IXP4XX_GPIO_GPIT2R_OFFSET 0x14 198 - #define IXP4XX_GPIO_GPCLKR_OFFSET 0x18 199 - #define IXP4XX_GPIO_GPDBSELR_OFFSET 0x1C 200 - 201 - /* 202 - * GPIO Register Definitions. 203 - * [Only perform 32bit reads/writes] 204 - */ 205 - #define IXP4XX_GPIO_REG(x) ((volatile u32 *)(IXP4XX_GPIO_BASE_VIRT+(x))) 206 - 207 - #define IXP4XX_GPIO_GPOUTR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOUTR_OFFSET) 208 - #define IXP4XX_GPIO_GPOER IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOER_OFFSET) 209 - #define IXP4XX_GPIO_GPINR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPINR_OFFSET) 210 - #define IXP4XX_GPIO_GPISR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPISR_OFFSET) 211 - #define IXP4XX_GPIO_GPIT1R IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT1R_OFFSET) 212 - #define IXP4XX_GPIO_GPIT2R IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT2R_OFFSET) 213 - #define IXP4XX_GPIO_GPCLKR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPCLKR_OFFSET) 214 - #define IXP4XX_GPIO_GPDBSELR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPDBSELR_OFFSET) 215 - 216 - /* 217 - * GPIO register bit definitions 218 - */ 219 - 220 - /* Interrupt styles 221 - */ 222 - #define IXP4XX_GPIO_STYLE_ACTIVE_HIGH 0x0 223 - #define IXP4XX_GPIO_STYLE_ACTIVE_LOW 0x1 224 - #define IXP4XX_GPIO_STYLE_RISING_EDGE 0x2 225 - #define IXP4XX_GPIO_STYLE_FALLING_EDGE 0x3 226 - #define IXP4XX_GPIO_STYLE_TRANSITIONAL 0x4 227 - 228 - /* 229 - * Mask used to clear interrupt styles 230 - */ 231 - #define IXP4XX_GPIO_STYLE_CLEAR 0x7 232 - #define IXP4XX_GPIO_STYLE_SIZE 3 233 149 234 150 /* 235 151 * Constants to make it easy to access Timer Control/Status registers
-2
arch/arm/mach-ixp4xx/include/mach/npe.h include/linux/soc/ixp4xx/npe.h
··· 16 16 }; 17 17 18 18 struct npe { 19 - struct resource *mem_res; 20 19 struct npe_regs __iomem *regs; 21 - u32 regs_phys; 22 20 int id; 23 21 int valid; 24 22 };
-204
arch/arm/mach-ixp4xx/include/mach/qmgr.h
··· 1 - /* 2 - * Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl> 3 - * 4 - * This program is free software; you can redistribute it and/or modify it 5 - * under the terms of version 2 of the GNU General Public License 6 - * as published by the Free Software Foundation. 7 - */ 8 - 9 - #ifndef IXP4XX_QMGR_H 10 - #define IXP4XX_QMGR_H 11 - 12 - #include <linux/io.h> 13 - #include <linux/kernel.h> 14 - 15 - #define DEBUG_QMGR 0 16 - 17 - #define HALF_QUEUES 32 18 - #define QUEUES 64 19 - #define MAX_QUEUE_LENGTH 4 /* in dwords */ 20 - 21 - #define QUEUE_STAT1_EMPTY 1 /* queue status bits */ 22 - #define QUEUE_STAT1_NEARLY_EMPTY 2 23 - #define QUEUE_STAT1_NEARLY_FULL 4 24 - #define QUEUE_STAT1_FULL 8 25 - #define QUEUE_STAT2_UNDERFLOW 1 26 - #define QUEUE_STAT2_OVERFLOW 2 27 - 28 - #define QUEUE_WATERMARK_0_ENTRIES 0 29 - #define QUEUE_WATERMARK_1_ENTRY 1 30 - #define QUEUE_WATERMARK_2_ENTRIES 2 31 - #define QUEUE_WATERMARK_4_ENTRIES 3 32 - #define QUEUE_WATERMARK_8_ENTRIES 4 33 - #define QUEUE_WATERMARK_16_ENTRIES 5 34 - #define QUEUE_WATERMARK_32_ENTRIES 6 35 - #define QUEUE_WATERMARK_64_ENTRIES 7 36 - 37 - /* queue interrupt request conditions */ 38 - #define QUEUE_IRQ_SRC_EMPTY 0 39 - #define QUEUE_IRQ_SRC_NEARLY_EMPTY 1 40 - #define QUEUE_IRQ_SRC_NEARLY_FULL 2 41 - #define QUEUE_IRQ_SRC_FULL 3 42 - #define QUEUE_IRQ_SRC_NOT_EMPTY 4 43 - #define QUEUE_IRQ_SRC_NOT_NEARLY_EMPTY 5 44 - #define QUEUE_IRQ_SRC_NOT_NEARLY_FULL 6 45 - #define QUEUE_IRQ_SRC_NOT_FULL 7 46 - 47 - struct qmgr_regs { 48 - u32 acc[QUEUES][MAX_QUEUE_LENGTH]; /* 0x000 - 0x3FF */ 49 - u32 stat1[4]; /* 0x400 - 0x40F */ 50 - u32 stat2[2]; /* 0x410 - 0x417 */ 51 - u32 statne_h; /* 0x418 - queue nearly empty */ 52 - u32 statf_h; /* 0x41C - queue full */ 53 - u32 irqsrc[4]; /* 0x420 - 0x42F IRC source */ 54 - u32 irqen[2]; /* 0x430 - 0x437 IRQ enabled */ 55 - u32 irqstat[2]; /* 0x438 - 0x43F - IRQ access only */ 56 - u32 reserved[1776]; 57 - u32 sram[2048]; /* 0x2000 - 0x3FFF - config and buffer */ 58 - }; 59 - 60 - void qmgr_set_irq(unsigned int queue, int src, 61 - void (*handler)(void *pdev), void *pdev); 62 - void qmgr_enable_irq(unsigned int queue); 63 - void qmgr_disable_irq(unsigned int queue); 64 - 65 - /* request_ and release_queue() must be called from non-IRQ context */ 66 - 67 - #if DEBUG_QMGR 68 - extern char qmgr_queue_descs[QUEUES][32]; 69 - 70 - int qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */, 71 - unsigned int nearly_empty_watermark, 72 - unsigned int nearly_full_watermark, 73 - const char *desc_format, const char* name); 74 - #else 75 - int __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */, 76 - unsigned int nearly_empty_watermark, 77 - unsigned int nearly_full_watermark); 78 - #define qmgr_request_queue(queue, len, nearly_empty_watermark, \ 79 - nearly_full_watermark, desc_format, name) \ 80 - __qmgr_request_queue(queue, len, nearly_empty_watermark, \ 81 - nearly_full_watermark) 82 - #endif 83 - 84 - void qmgr_release_queue(unsigned int queue); 85 - 86 - 87 - static inline void qmgr_put_entry(unsigned int queue, u32 val) 88 - { 89 - struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; 90 - #if DEBUG_QMGR 91 - BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ 92 - 93 - printk(KERN_DEBUG "Queue %s(%i) put %X\n", 94 - qmgr_queue_descs[queue], queue, val); 95 - #endif 96 - __raw_writel(val, &qmgr_regs->acc[queue][0]); 97 - } 98 - 99 - static inline u32 qmgr_get_entry(unsigned int queue) 100 - { 101 - u32 val; 102 - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; 103 - val = __raw_readl(&qmgr_regs->acc[queue][0]); 104 - #if DEBUG_QMGR 105 - BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ 106 - 107 - printk(KERN_DEBUG "Queue %s(%i) get %X\n", 108 - qmgr_queue_descs[queue], queue, val); 109 - #endif 110 - return val; 111 - } 112 - 113 - static inline int __qmgr_get_stat1(unsigned int queue) 114 - { 115 - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; 116 - return (__raw_readl(&qmgr_regs->stat1[queue >> 3]) 117 - >> ((queue & 7) << 2)) & 0xF; 118 - } 119 - 120 - static inline int __qmgr_get_stat2(unsigned int queue) 121 - { 122 - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; 123 - BUG_ON(queue >= HALF_QUEUES); 124 - return (__raw_readl(&qmgr_regs->stat2[queue >> 4]) 125 - >> ((queue & 0xF) << 1)) & 0x3; 126 - } 127 - 128 - /** 129 - * qmgr_stat_empty() - checks if a hardware queue is empty 130 - * @queue: queue number 131 - * 132 - * Returns non-zero value if the queue is empty. 133 - */ 134 - static inline int qmgr_stat_empty(unsigned int queue) 135 - { 136 - BUG_ON(queue >= HALF_QUEUES); 137 - return __qmgr_get_stat1(queue) & QUEUE_STAT1_EMPTY; 138 - } 139 - 140 - /** 141 - * qmgr_stat_below_low_watermark() - checks if a queue is below low watermark 142 - * @queue: queue number 143 - * 144 - * Returns non-zero value if the queue is below low watermark. 145 - */ 146 - static inline int qmgr_stat_below_low_watermark(unsigned int queue) 147 - { 148 - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; 149 - if (queue >= HALF_QUEUES) 150 - return (__raw_readl(&qmgr_regs->statne_h) >> 151 - (queue - HALF_QUEUES)) & 0x01; 152 - return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_EMPTY; 153 - } 154 - 155 - /** 156 - * qmgr_stat_above_high_watermark() - checks if a queue is above high watermark 157 - * @queue: queue number 158 - * 159 - * Returns non-zero value if the queue is above high watermark 160 - */ 161 - static inline int qmgr_stat_above_high_watermark(unsigned int queue) 162 - { 163 - BUG_ON(queue >= HALF_QUEUES); 164 - return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_FULL; 165 - } 166 - 167 - /** 168 - * qmgr_stat_full() - checks if a hardware queue is full 169 - * @queue: queue number 170 - * 171 - * Returns non-zero value if the queue is full. 172 - */ 173 - static inline int qmgr_stat_full(unsigned int queue) 174 - { 175 - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; 176 - if (queue >= HALF_QUEUES) 177 - return (__raw_readl(&qmgr_regs->statf_h) >> 178 - (queue - HALF_QUEUES)) & 0x01; 179 - return __qmgr_get_stat1(queue) & QUEUE_STAT1_FULL; 180 - } 181 - 182 - /** 183 - * qmgr_stat_underflow() - checks if a hardware queue experienced underflow 184 - * @queue: queue number 185 - * 186 - * Returns non-zero value if the queue experienced underflow. 187 - */ 188 - static inline int qmgr_stat_underflow(unsigned int queue) 189 - { 190 - return __qmgr_get_stat2(queue) & QUEUE_STAT2_UNDERFLOW; 191 - } 192 - 193 - /** 194 - * qmgr_stat_overflow() - checks if a hardware queue experienced overflow 195 - * @queue: queue number 196 - * 197 - * Returns non-zero value if the queue experienced overflow. 198 - */ 199 - static inline int qmgr_stat_overflow(unsigned int queue) 200 - { 201 - return __qmgr_get_stat2(queue) & QUEUE_STAT2_OVERFLOW; 202 - } 203 - 204 - #endif
+68
arch/arm/mach-ixp4xx/irqs.h
··· 1 + /* 2 + * arch/arm/mach-ixp4xx/include/mach/irqs.h 3 + * 4 + * IRQ definitions for IXP4XX based systems 5 + * 6 + * Copyright (C) 2002 Intel Corporation. 7 + * Copyright (C) 2003 MontaVista Software, Inc. 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License version 2 as 11 + * published by the Free Software Foundation. 12 + * 13 + */ 14 + 15 + #ifndef _ARCH_IXP4XX_IRQS_H_ 16 + #define _ARCH_IXP4XX_IRQS_H_ 17 + 18 + #define IRQ_IXP4XX_BASE 16 19 + 20 + #define IRQ_IXP4XX_NPEA (IRQ_IXP4XX_BASE + 0) 21 + #define IRQ_IXP4XX_NPEB (IRQ_IXP4XX_BASE + 1) 22 + #define IRQ_IXP4XX_NPEC (IRQ_IXP4XX_BASE + 2) 23 + #define IRQ_IXP4XX_QM1 (IRQ_IXP4XX_BASE + 3) 24 + #define IRQ_IXP4XX_QM2 (IRQ_IXP4XX_BASE + 4) 25 + #define IRQ_IXP4XX_TIMER1 (IRQ_IXP4XX_BASE + 5) 26 + #define IRQ_IXP4XX_GPIO0 (IRQ_IXP4XX_BASE + 6) 27 + #define IRQ_IXP4XX_GPIO1 (IRQ_IXP4XX_BASE + 7) 28 + #define IRQ_IXP4XX_PCI_INT (IRQ_IXP4XX_BASE + 8) 29 + #define IRQ_IXP4XX_PCI_DMA1 (IRQ_IXP4XX_BASE + 9) 30 + #define IRQ_IXP4XX_PCI_DMA2 (IRQ_IXP4XX_BASE + 10) 31 + #define IRQ_IXP4XX_TIMER2 (IRQ_IXP4XX_BASE + 11) 32 + #define IRQ_IXP4XX_USB (IRQ_IXP4XX_BASE + 12) 33 + #define IRQ_IXP4XX_UART2 (IRQ_IXP4XX_BASE + 13) 34 + #define IRQ_IXP4XX_TIMESTAMP (IRQ_IXP4XX_BASE + 14) 35 + #define IRQ_IXP4XX_UART1 (IRQ_IXP4XX_BASE + 15) 36 + #define IRQ_IXP4XX_WDOG (IRQ_IXP4XX_BASE + 16) 37 + #define IRQ_IXP4XX_AHB_PMU (IRQ_IXP4XX_BASE + 17) 38 + #define IRQ_IXP4XX_XSCALE_PMU (IRQ_IXP4XX_BASE + 18) 39 + #define IRQ_IXP4XX_GPIO2 (IRQ_IXP4XX_BASE + 19) 40 + #define IRQ_IXP4XX_GPIO3 (IRQ_IXP4XX_BASE + 20) 41 + #define IRQ_IXP4XX_GPIO4 (IRQ_IXP4XX_BASE + 21) 42 + #define IRQ_IXP4XX_GPIO5 (IRQ_IXP4XX_BASE + 22) 43 + #define IRQ_IXP4XX_GPIO6 (IRQ_IXP4XX_BASE + 23) 44 + #define IRQ_IXP4XX_GPIO7 (IRQ_IXP4XX_BASE + 24) 45 + #define IRQ_IXP4XX_GPIO8 (IRQ_IXP4XX_BASE + 25) 46 + #define IRQ_IXP4XX_GPIO9 (IRQ_IXP4XX_BASE + 26) 47 + #define IRQ_IXP4XX_GPIO10 (IRQ_IXP4XX_BASE + 27) 48 + #define IRQ_IXP4XX_GPIO11 (IRQ_IXP4XX_BASE + 28) 49 + #define IRQ_IXP4XX_GPIO12 (IRQ_IXP4XX_BASE + 29) 50 + #define IRQ_IXP4XX_SW_INT1 (IRQ_IXP4XX_BASE + 30) 51 + #define IRQ_IXP4XX_SW_INT2 (IRQ_IXP4XX_BASE + 31) 52 + #define IRQ_IXP4XX_USB_HOST (IRQ_IXP4XX_BASE + 32) 53 + #define IRQ_IXP4XX_I2C (IRQ_IXP4XX_BASE + 33) 54 + #define IRQ_IXP4XX_SSP (IRQ_IXP4XX_BASE + 34) 55 + #define IRQ_IXP4XX_TSYNC (IRQ_IXP4XX_BASE + 35) 56 + #define IRQ_IXP4XX_EAU_DONE (IRQ_IXP4XX_BASE + 36) 57 + #define IRQ_IXP4XX_SHA_DONE (IRQ_IXP4XX_BASE + 37) 58 + #define IRQ_IXP4XX_SWCP_PE (IRQ_IXP4XX_BASE + 58) 59 + #define IRQ_IXP4XX_QM_PE (IRQ_IXP4XX_BASE + 60) 60 + #define IRQ_IXP4XX_MCU_ECC (IRQ_IXP4XX_BASE + 61) 61 + #define IRQ_IXP4XX_EXP_PE (IRQ_IXP4XX_BASE + 62) 62 + 63 + #define _IXP4XX_GPIO_IRQ(n) (IRQ_IXP4XX_GPIO ## n) 64 + #define IXP4XX_GPIO_IRQ(n) _IXP4XX_GPIO_IRQ(n) 65 + 66 + #define XSCALE_PMU_IRQ (IRQ_IXP4XX_XSCALE_PMU) 67 + 68 + #endif
+2
arch/arm/mach-ixp4xx/ixdp425-pci.c
··· 24 24 #include <mach/hardware.h> 25 25 #include <asm/mach-types.h> 26 26 27 + #include "irqs.h" 28 + 27 29 #define MAX_DEV 4 28 30 #define IRQ_LINES 4 29 31
+2
arch/arm/mach-ixp4xx/ixdp425-setup.c
··· 32 32 #include <asm/mach/arch.h> 33 33 #include <asm/mach/flash.h> 34 34 35 + #include "irqs.h" 36 + 35 37 #define IXDP425_SDA_PIN 7 36 38 #define IXDP425_SCL_PIN 6 37 39
+2
arch/arm/mach-ixp4xx/ixdpg425-pci.c
··· 23 23 24 24 #include <asm/mach/pci.h> 25 25 26 + #include "irqs.h" 27 + 26 28 void __init ixdpg425_pci_preinit(void) 27 29 { 28 30 irq_set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW);
+60
arch/arm/mach-ixp4xx/ixp4xx-of.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * IXP4xx Device Tree boot support 4 + */ 5 + #include <linux/kernel.h> 6 + #include <linux/init.h> 7 + #include <linux/io.h> 8 + 9 + #include <asm/mach/arch.h> 10 + #include <asm/mach/map.h> 11 + 12 + #include <mach/hardware.h> 13 + #include <mach/ixp4xx-regs.h> 14 + 15 + static struct map_desc ixp4xx_of_io_desc[] __initdata = { 16 + /* 17 + * This is needed for runtime system configuration checks, 18 + * such as reading if hardware so-and-so is present. This 19 + * could eventually be converted into a syscon once all boards 20 + * are converted to device tree. 21 + */ 22 + { 23 + .virtual = IXP4XX_EXP_CFG_BASE_VIRT, 24 + .pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS), 25 + .length = SZ_4K, 26 + .type = MT_DEVICE, 27 + }, 28 + #ifdef CONFIG_DEBUG_UART_8250 29 + /* This is needed for LL-debug/earlyprintk/debug-macro.S */ 30 + { 31 + .virtual = CONFIG_DEBUG_UART_VIRT, 32 + .pfn = __phys_to_pfn(CONFIG_DEBUG_UART_PHYS), 33 + .length = SZ_4K, 34 + .type = MT_DEVICE, 35 + }, 36 + #endif 37 + }; 38 + 39 + static void __init ixp4xx_of_map_io(void) 40 + { 41 + iotable_init(ixp4xx_of_io_desc, ARRAY_SIZE(ixp4xx_of_io_desc)); 42 + } 43 + 44 + /* 45 + * We handle 4 differen SoC families. These compatible strings are enough 46 + * to provide the core so that different boards can add their more detailed 47 + * specifics. 48 + */ 49 + static const char *ixp4xx_of_board_compat[] = { 50 + "intel,ixp42x", 51 + "intel,ixp43x", 52 + "intel,ixp45x", 53 + "intel,ixp46x", 54 + NULL, 55 + }; 56 + 57 + DT_MACHINE_START(IXP4XX_DT, "IXP4xx (Device Tree)") 58 + .map_io = ixp4xx_of_map_io, 59 + .dt_compat = ixp4xx_of_board_compat, 60 + MACHINE_END
+44 -24
arch/arm/mach-ixp4xx/ixp4xx_npe.c drivers/soc/ixp4xx/ixp4xx-npe.c
··· 20 20 #include <linux/io.h> 21 21 #include <linux/kernel.h> 22 22 #include <linux/module.h> 23 - #include <mach/npe.h> 23 + #include <linux/of.h> 24 + #include <linux/platform_device.h> 25 + #include <linux/soc/ixp4xx/npe.h> 24 26 25 27 #define DEBUG_MSG 0 26 28 #define DEBUG_FW 0 ··· 155 153 static struct npe npe_tab[NPE_COUNT] = { 156 154 { 157 155 .id = 0, 158 - .regs = (struct npe_regs __iomem *)IXP4XX_NPEA_BASE_VIRT, 159 - .regs_phys = IXP4XX_NPEA_BASE_PHYS, 160 156 }, { 161 157 .id = 1, 162 - .regs = (struct npe_regs __iomem *)IXP4XX_NPEB_BASE_VIRT, 163 - .regs_phys = IXP4XX_NPEB_BASE_PHYS, 164 158 }, { 165 159 .id = 2, 166 - .regs = (struct npe_regs __iomem *)IXP4XX_NPEC_BASE_VIRT, 167 - .regs_phys = IXP4XX_NPEC_BASE_PHYS, 168 160 } 169 161 }; 170 162 ··· 678 682 module_put(THIS_MODULE); 679 683 } 680 684 681 - 682 - static int __init npe_init_module(void) 685 + static int ixp4xx_npe_probe(struct platform_device *pdev) 683 686 { 684 - 685 687 int i, found = 0; 688 + struct device *dev = &pdev->dev; 689 + struct resource *res; 686 690 687 691 for (i = 0; i < NPE_COUNT; i++) { 688 692 struct npe *npe = &npe_tab[i]; 693 + 694 + res = platform_get_resource(pdev, IORESOURCE_MEM, i); 695 + if (!res) 696 + return -ENODEV; 697 + 689 698 if (!(ixp4xx_read_feature_bits() & 690 - (IXP4XX_FEATURE_RESET_NPEA << i))) 699 + (IXP4XX_FEATURE_RESET_NPEA << i))) { 700 + dev_info(dev, "NPE%d at 0x%08x-0x%08x not available\n", 701 + i, res->start, res->end); 691 702 continue; /* NPE already disabled or not present */ 692 - if (!(npe->mem_res = request_mem_region(npe->regs_phys, 693 - REGS_SIZE, 694 - npe_name(npe)))) { 695 - print_npe(KERN_ERR, npe, 696 - "failed to request memory region\n"); 703 + } 704 + npe->regs = devm_ioremap_resource(dev, res); 705 + if (!npe->regs) 706 + return -ENOMEM; 707 + 708 + if (npe_reset(npe)) { 709 + dev_info(dev, "NPE%d at 0x%08x-0x%08x does not reset\n", 710 + i, res->start, res->end); 697 711 continue; 698 712 } 699 - 700 - if (npe_reset(npe)) 701 - continue; 702 713 npe->valid = 1; 714 + dev_info(dev, "NPE%d at 0x%08x-0x%08x registered\n", 715 + i, res->start, res->end); 703 716 found++; 704 717 } 705 718 ··· 717 712 return 0; 718 713 } 719 714 720 - static void __exit npe_cleanup_module(void) 715 + static int ixp4xx_npe_remove(struct platform_device *pdev) 721 716 { 722 717 int i; 723 718 724 719 for (i = 0; i < NPE_COUNT; i++) 725 - if (npe_tab[i].mem_res) { 720 + if (npe_tab[i].regs) { 726 721 npe_reset(&npe_tab[i]); 727 - release_resource(npe_tab[i].mem_res); 728 722 } 723 + 724 + return 0; 729 725 } 730 726 731 - module_init(npe_init_module); 732 - module_exit(npe_cleanup_module); 727 + static const struct of_device_id ixp4xx_npe_of_match[] = { 728 + { 729 + .compatible = "intel,ixp4xx-network-processing-engine", 730 + }, 731 + {}, 732 + }; 733 + 734 + static struct platform_driver ixp4xx_npe_driver = { 735 + .driver = { 736 + .name = "ixp4xx-npe", 737 + .of_match_table = of_match_ptr(ixp4xx_npe_of_match), 738 + }, 739 + .probe = ixp4xx_npe_probe, 740 + .remove = ixp4xx_npe_remove, 741 + }; 742 + module_platform_driver(ixp4xx_npe_driver); 733 743 734 744 MODULE_AUTHOR("Krzysztof Halasa"); 735 745 MODULE_LICENSE("GPL v2");
+151 -35
arch/arm/mach-ixp4xx/ixp4xx_qmgr.c drivers/soc/ixp4xx/ixp4xx-qmgr.c
··· 12 12 #include <linux/interrupt.h> 13 13 #include <linux/kernel.h> 14 14 #include <linux/module.h> 15 - #include <mach/qmgr.h> 15 + #include <linux/of.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/soc/ixp4xx/qmgr.h> 16 18 17 - static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; 18 - static struct resource *mem_res; 19 + static struct qmgr_regs __iomem *qmgr_regs; 20 + static int qmgr_irq_1; 21 + static int qmgr_irq_2; 19 22 static spinlock_t qmgr_lock; 20 23 static u32 used_sram_bitmap[4]; /* 128 16-dword pages */ 21 24 static void (*irq_handlers[QUEUES])(void *pdev); ··· 27 24 #if DEBUG_QMGR 28 25 char qmgr_queue_descs[QUEUES][32]; 29 26 #endif 27 + 28 + void qmgr_put_entry(unsigned int queue, u32 val) 29 + { 30 + #if DEBUG_QMGR 31 + BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ 32 + 33 + printk(KERN_DEBUG "Queue %s(%i) put %X\n", 34 + qmgr_queue_descs[queue], queue, val); 35 + #endif 36 + __raw_writel(val, &qmgr_regs->acc[queue][0]); 37 + } 38 + 39 + u32 qmgr_get_entry(unsigned int queue) 40 + { 41 + u32 val; 42 + val = __raw_readl(&qmgr_regs->acc[queue][0]); 43 + #if DEBUG_QMGR 44 + BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ 45 + 46 + printk(KERN_DEBUG "Queue %s(%i) get %X\n", 47 + qmgr_queue_descs[queue], queue, val); 48 + #endif 49 + return val; 50 + } 51 + 52 + static int __qmgr_get_stat1(unsigned int queue) 53 + { 54 + return (__raw_readl(&qmgr_regs->stat1[queue >> 3]) 55 + >> ((queue & 7) << 2)) & 0xF; 56 + } 57 + 58 + static int __qmgr_get_stat2(unsigned int queue) 59 + { 60 + BUG_ON(queue >= HALF_QUEUES); 61 + return (__raw_readl(&qmgr_regs->stat2[queue >> 4]) 62 + >> ((queue & 0xF) << 1)) & 0x3; 63 + } 64 + 65 + /** 66 + * qmgr_stat_empty() - checks if a hardware queue is empty 67 + * @queue: queue number 68 + * 69 + * Returns non-zero value if the queue is empty. 70 + */ 71 + int qmgr_stat_empty(unsigned int queue) 72 + { 73 + BUG_ON(queue >= HALF_QUEUES); 74 + return __qmgr_get_stat1(queue) & QUEUE_STAT1_EMPTY; 75 + } 76 + 77 + /** 78 + * qmgr_stat_below_low_watermark() - checks if a queue is below low watermark 79 + * @queue: queue number 80 + * 81 + * Returns non-zero value if the queue is below low watermark. 82 + */ 83 + int qmgr_stat_below_low_watermark(unsigned int queue) 84 + { 85 + if (queue >= HALF_QUEUES) 86 + return (__raw_readl(&qmgr_regs->statne_h) >> 87 + (queue - HALF_QUEUES)) & 0x01; 88 + return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_EMPTY; 89 + } 90 + 91 + /** 92 + * qmgr_stat_full() - checks if a hardware queue is full 93 + * @queue: queue number 94 + * 95 + * Returns non-zero value if the queue is full. 96 + */ 97 + int qmgr_stat_full(unsigned int queue) 98 + { 99 + if (queue >= HALF_QUEUES) 100 + return (__raw_readl(&qmgr_regs->statf_h) >> 101 + (queue - HALF_QUEUES)) & 0x01; 102 + return __qmgr_get_stat1(queue) & QUEUE_STAT1_FULL; 103 + } 104 + 105 + /** 106 + * qmgr_stat_overflow() - checks if a hardware queue experienced overflow 107 + * @queue: queue number 108 + * 109 + * Returns non-zero value if the queue experienced overflow. 110 + */ 111 + int qmgr_stat_overflow(unsigned int queue) 112 + { 113 + return __qmgr_get_stat2(queue) & QUEUE_STAT2_OVERFLOW; 114 + } 30 115 31 116 void qmgr_set_irq(unsigned int queue, int src, 32 117 void (*handler)(void *pdev), void *pdev) ··· 186 95 187 96 static irqreturn_t qmgr_irq(int irq, void *pdev) 188 97 { 189 - int i, half = (irq == IRQ_IXP4XX_QM1 ? 0 : 1); 98 + int i, half = (irq == qmgr_irq_1 ? 0 : 1); 190 99 u32 req_bitmap = __raw_readl(&qmgr_regs->irqstat[half]); 191 100 192 101 if (!req_bitmap) ··· 373 282 module_put(THIS_MODULE); 374 283 } 375 284 376 - static int qmgr_init(void) 285 + static int ixp4xx_qmgr_probe(struct platform_device *pdev) 377 286 { 378 287 int i, err; 379 288 irq_handler_t handler1, handler2; 289 + struct device *dev = &pdev->dev; 290 + struct resource *res; 291 + int irq1, irq2; 380 292 381 - mem_res = request_mem_region(IXP4XX_QMGR_BASE_PHYS, 382 - IXP4XX_QMGR_REGION_SIZE, 383 - "IXP4xx Queue Manager"); 384 - if (mem_res == NULL) 385 - return -EBUSY; 293 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 294 + if (!res) 295 + return -ENODEV; 296 + qmgr_regs = devm_ioremap_resource(dev, res); 297 + if (!qmgr_regs) 298 + return -ENOMEM; 299 + 300 + irq1 = platform_get_irq(pdev, 0); 301 + if (irq1 <= 0) 302 + return irq1 ? irq1 : -EINVAL; 303 + qmgr_irq_1 = irq1; 304 + irq2 = platform_get_irq(pdev, 1); 305 + if (irq2 <= 0) 306 + return irq2 ? irq2 : -EINVAL; 307 + qmgr_irq_2 = irq2; 386 308 387 309 /* reset qmgr registers */ 388 310 for (i = 0; i < 4; i++) { ··· 420 316 } else 421 317 handler1 = handler2 = qmgr_irq; 422 318 423 - err = request_irq(IRQ_IXP4XX_QM1, handler1, 0, "IXP4xx Queue Manager", 424 - NULL); 319 + err = devm_request_irq(dev, irq1, handler1, 0, "IXP4xx Queue Manager", 320 + NULL); 425 321 if (err) { 426 - printk(KERN_ERR "qmgr: failed to request IRQ%i (%i)\n", 427 - IRQ_IXP4XX_QM1, err); 428 - goto error_irq; 322 + dev_err(dev, "failed to request IRQ%i (%i)\n", 323 + irq1, err); 324 + return err; 429 325 } 430 326 431 - err = request_irq(IRQ_IXP4XX_QM2, handler2, 0, "IXP4xx Queue Manager", 432 - NULL); 327 + err = devm_request_irq(dev, irq2, handler2, 0, "IXP4xx Queue Manager", 328 + NULL); 433 329 if (err) { 434 - printk(KERN_ERR "qmgr: failed to request IRQ%i (%i)\n", 435 - IRQ_IXP4XX_QM2, err); 436 - goto error_irq2; 330 + dev_err(dev, "failed to request IRQ%i (%i)\n", 331 + irq2, err); 332 + return err; 437 333 } 438 334 439 335 used_sram_bitmap[0] = 0xF; /* 4 first pages reserved for config */ 440 336 spin_lock_init(&qmgr_lock); 441 337 442 - printk(KERN_INFO "IXP4xx Queue Manager initialized.\n"); 338 + dev_info(dev, "IXP4xx Queue Manager initialized.\n"); 443 339 return 0; 444 - 445 - error_irq2: 446 - free_irq(IRQ_IXP4XX_QM1, NULL); 447 - error_irq: 448 - release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); 449 - return err; 450 340 } 451 341 452 - static void qmgr_remove(void) 342 + static int ixp4xx_qmgr_remove(struct platform_device *pdev) 453 343 { 454 - free_irq(IRQ_IXP4XX_QM1, NULL); 455 - free_irq(IRQ_IXP4XX_QM2, NULL); 456 - synchronize_irq(IRQ_IXP4XX_QM1); 457 - synchronize_irq(IRQ_IXP4XX_QM2); 458 - release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); 344 + synchronize_irq(qmgr_irq_1); 345 + synchronize_irq(qmgr_irq_2); 346 + return 0; 459 347 } 460 348 461 - module_init(qmgr_init); 462 - module_exit(qmgr_remove); 349 + static const struct of_device_id ixp4xx_qmgr_of_match[] = { 350 + { 351 + .compatible = "intel,ixp4xx-ahb-queue-manager", 352 + }, 353 + {}, 354 + }; 355 + 356 + static struct platform_driver ixp4xx_qmgr_driver = { 357 + .driver = { 358 + .name = "ixp4xx-qmgr", 359 + .of_match_table = of_match_ptr(ixp4xx_qmgr_of_match), 360 + }, 361 + .probe = ixp4xx_qmgr_probe, 362 + .remove = ixp4xx_qmgr_remove, 363 + }; 364 + module_platform_driver(ixp4xx_qmgr_driver); 463 365 464 366 MODULE_LICENSE("GPL v2"); 465 367 MODULE_AUTHOR("Krzysztof Halasa"); 466 368 369 + EXPORT_SYMBOL(qmgr_put_entry); 370 + EXPORT_SYMBOL(qmgr_get_entry); 371 + EXPORT_SYMBOL(qmgr_stat_empty); 372 + EXPORT_SYMBOL(qmgr_stat_below_low_watermark); 373 + EXPORT_SYMBOL(qmgr_stat_full); 374 + EXPORT_SYMBOL(qmgr_stat_overflow); 467 375 EXPORT_SYMBOL(qmgr_set_irq); 468 376 EXPORT_SYMBOL(qmgr_enable_irq); 469 377 EXPORT_SYMBOL(qmgr_disable_irq);
+2
arch/arm/mach-ixp4xx/nas100d-pci.c
··· 21 21 #include <asm/mach/pci.h> 22 22 #include <asm/mach-types.h> 23 23 24 + #include "irqs.h" 25 + 24 26 #define MAX_DEV 3 25 27 #define IRQ_LINES 3 26 28
+2 -3
arch/arm/mach-ixp4xx/nas100d-setup.c
··· 34 34 #include <asm/mach/arch.h> 35 35 #include <asm/mach/flash.h> 36 36 37 + #include "irqs.h" 38 + 37 39 #define NAS100D_SDA_PIN 5 38 40 #define NAS100D_SCL_PIN 6 39 41 ··· 280 278 int i; 281 279 282 280 ixp4xx_sys_init(); 283 - 284 - /* gpio 14 and 15 are _not_ clocks */ 285 - *IXP4XX_GPIO_GPCLKR = 0; 286 281 287 282 nas100d_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); 288 283 nas100d_flash_resource.end =
+2
arch/arm/mach-ixp4xx/nslu2-pci.c
··· 21 21 #include <asm/mach/pci.h> 22 22 #include <asm/mach-types.h> 23 23 24 + #include "irqs.h" 25 + 24 26 #define MAX_DEV 3 25 27 #define IRQ_LINES 3 26 28
+11 -1
arch/arm/mach-ixp4xx/nslu2-setup.c
··· 32 32 #include <asm/mach/flash.h> 33 33 #include <asm/mach/time.h> 34 34 35 + #include "irqs.h" 36 + 35 37 #define NSLU2_SDA_PIN 7 36 38 #define NSLU2_SCL_PIN 6 37 39 ··· 127 125 }, 128 126 }; 129 127 128 + static struct resource nslu2_beeper_resources[] = { 129 + { 130 + .start = IRQ_IXP4XX_TIMER2, 131 + .flags = IORESOURCE_IRQ, 132 + }, 133 + }; 134 + 130 135 static struct platform_device nslu2_beeper = { 131 136 .name = "ixp4xx-beeper", 132 137 .id = NSLU2_GPIO_BUZZ, 133 - .num_resources = 0, 138 + .resource = nslu2_beeper_resources, 139 + .num_resources = ARRAY_SIZE(nslu2_beeper_resources), 134 140 }; 135 141 136 142 static struct resource nslu2_uart_resources[] = {
+2
arch/arm/mach-ixp4xx/wg302v2-pci.c
··· 27 27 28 28 #include <asm/mach/pci.h> 29 29 30 + #include "irqs.h" 31 + 30 32 void __init wg302v2_pci_preinit(void) 31 33 { 32 34 irq_set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW);
+2
arch/arm/mach-ixp4xx/wg302v2-setup.c
··· 29 29 #include <asm/mach/arch.h> 30 30 #include <asm/mach/flash.h> 31 31 32 + #include "irqs.h" 33 + 32 34 static struct flash_platform_data wg302v2_flash_data = { 33 35 .map_name = "cfi_probe", 34 36 .width = 2,
+7
drivers/clocksource/Kconfig
··· 69 69 Enables support for the Faraday Technology timer block 70 70 FTTMR010. 71 71 72 + config IXP4XX_TIMER 73 + bool "Intel XScale IXP4xx timer driver" if COMPILE_TEST 74 + depends on HAS_IOMEM 75 + select CLKSRC_MMIO 76 + help 77 + Enables support for the Intel XScale IXP4xx SoC timer. 78 + 72 79 config ROCKCHIP_TIMER 73 80 bool "Rockchip timer driver" if COMPILE_TEST 74 81 depends on ARM || ARM64
+1
drivers/clocksource/Makefile
··· 20 20 obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o 21 21 obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o 22 22 obj-$(CONFIG_FTTMR010_TIMER) += timer-fttmr010.o 23 + obj-$(CONFIG_IXP4XX_TIMER) += timer-ixp4xx.o 23 24 obj-$(CONFIG_ROCKCHIP_TIMER) += timer-rockchip.o 24 25 obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o 25 26 obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o
+284
drivers/clocksource/timer-ixp4xx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * IXP4 timer driver 4 + * Copyright (C) 2019 Linus Walleij <linus.walleij@linaro.org> 5 + * 6 + * Based on arch/arm/mach-ixp4xx/common.c 7 + * Copyright 2002 (C) Intel Corporation 8 + * Copyright 2003-2004 (C) MontaVista, Software, Inc. 9 + * Copyright (C) Deepak Saxena <dsaxena@plexity.net> 10 + */ 11 + #include <linux/interrupt.h> 12 + #include <linux/io.h> 13 + #include <linux/clockchips.h> 14 + #include <linux/clocksource.h> 15 + #include <linux/sched_clock.h> 16 + #include <linux/slab.h> 17 + #include <linux/bitops.h> 18 + #include <linux/delay.h> 19 + #include <linux/of_address.h> 20 + #include <linux/of_irq.h> 21 + /* Goes away with OF conversion */ 22 + #include <linux/platform_data/timer-ixp4xx.h> 23 + 24 + /* 25 + * Constants to make it easy to access Timer Control/Status registers 26 + */ 27 + #define IXP4XX_OSTS_OFFSET 0x00 /* Continuous Timestamp */ 28 + #define IXP4XX_OST1_OFFSET 0x04 /* Timer 1 Timestamp */ 29 + #define IXP4XX_OSRT1_OFFSET 0x08 /* Timer 1 Reload */ 30 + #define IXP4XX_OST2_OFFSET 0x0C /* Timer 2 Timestamp */ 31 + #define IXP4XX_OSRT2_OFFSET 0x10 /* Timer 2 Reload */ 32 + #define IXP4XX_OSWT_OFFSET 0x14 /* Watchdog Timer */ 33 + #define IXP4XX_OSWE_OFFSET 0x18 /* Watchdog Enable */ 34 + #define IXP4XX_OSWK_OFFSET 0x1C /* Watchdog Key */ 35 + #define IXP4XX_OSST_OFFSET 0x20 /* Timer Status */ 36 + 37 + /* 38 + * Timer register values and bit definitions 39 + */ 40 + #define IXP4XX_OST_ENABLE 0x00000001 41 + #define IXP4XX_OST_ONE_SHOT 0x00000002 42 + /* Low order bits of reload value ignored */ 43 + #define IXP4XX_OST_RELOAD_MASK 0x00000003 44 + #define IXP4XX_OST_DISABLED 0x00000000 45 + #define IXP4XX_OSST_TIMER_1_PEND 0x00000001 46 + #define IXP4XX_OSST_TIMER_2_PEND 0x00000002 47 + #define IXP4XX_OSST_TIMER_TS_PEND 0x00000004 48 + #define IXP4XX_OSST_TIMER_WDOG_PEND 0x00000008 49 + #define IXP4XX_OSST_TIMER_WARM_RESET 0x00000010 50 + 51 + #define IXP4XX_WDT_KEY 0x0000482E 52 + #define IXP4XX_WDT_RESET_ENABLE 0x00000001 53 + #define IXP4XX_WDT_IRQ_ENABLE 0x00000002 54 + #define IXP4XX_WDT_COUNT_ENABLE 0x00000004 55 + 56 + struct ixp4xx_timer { 57 + void __iomem *base; 58 + unsigned int tick_rate; 59 + u32 latch; 60 + struct clock_event_device clkevt; 61 + #ifdef CONFIG_ARM 62 + struct delay_timer delay_timer; 63 + #endif 64 + }; 65 + 66 + /* 67 + * A local singleton used by sched_clock and delay timer reads, which are 68 + * fast and stateless 69 + */ 70 + static struct ixp4xx_timer *local_ixp4xx_timer; 71 + 72 + static inline struct ixp4xx_timer * 73 + to_ixp4xx_timer(struct clock_event_device *evt) 74 + { 75 + return container_of(evt, struct ixp4xx_timer, clkevt); 76 + } 77 + 78 + static u64 notrace ixp4xx_read_sched_clock(void) 79 + { 80 + return __raw_readl(local_ixp4xx_timer->base + IXP4XX_OSTS_OFFSET); 81 + } 82 + 83 + static u64 ixp4xx_clocksource_read(struct clocksource *c) 84 + { 85 + return __raw_readl(local_ixp4xx_timer->base + IXP4XX_OSTS_OFFSET); 86 + } 87 + 88 + static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id) 89 + { 90 + struct ixp4xx_timer *tmr = dev_id; 91 + struct clock_event_device *evt = &tmr->clkevt; 92 + 93 + /* Clear Pending Interrupt */ 94 + __raw_writel(IXP4XX_OSST_TIMER_1_PEND, 95 + tmr->base + IXP4XX_OSST_OFFSET); 96 + 97 + evt->event_handler(evt); 98 + 99 + return IRQ_HANDLED; 100 + } 101 + 102 + static int ixp4xx_set_next_event(unsigned long cycles, 103 + struct clock_event_device *evt) 104 + { 105 + struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt); 106 + u32 val; 107 + 108 + val = __raw_readl(tmr->base + IXP4XX_OSRT1_OFFSET); 109 + /* Keep enable/oneshot bits */ 110 + val &= IXP4XX_OST_RELOAD_MASK; 111 + __raw_writel((cycles & ~IXP4XX_OST_RELOAD_MASK) | val, 112 + tmr->base + IXP4XX_OSRT1_OFFSET); 113 + 114 + return 0; 115 + } 116 + 117 + static int ixp4xx_shutdown(struct clock_event_device *evt) 118 + { 119 + struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt); 120 + u32 val; 121 + 122 + val = __raw_readl(tmr->base + IXP4XX_OSRT1_OFFSET); 123 + val &= ~IXP4XX_OST_ENABLE; 124 + __raw_writel(val, tmr->base + IXP4XX_OSRT1_OFFSET); 125 + 126 + return 0; 127 + } 128 + 129 + static int ixp4xx_set_oneshot(struct clock_event_device *evt) 130 + { 131 + struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt); 132 + 133 + __raw_writel(IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT, 134 + tmr->base + IXP4XX_OSRT1_OFFSET); 135 + 136 + return 0; 137 + } 138 + 139 + static int ixp4xx_set_periodic(struct clock_event_device *evt) 140 + { 141 + struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt); 142 + u32 val; 143 + 144 + val = tmr->latch & ~IXP4XX_OST_RELOAD_MASK; 145 + val |= IXP4XX_OST_ENABLE; 146 + __raw_writel(val, tmr->base + IXP4XX_OSRT1_OFFSET); 147 + 148 + return 0; 149 + } 150 + 151 + static int ixp4xx_resume(struct clock_event_device *evt) 152 + { 153 + struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt); 154 + u32 val; 155 + 156 + val = __raw_readl(tmr->base + IXP4XX_OSRT1_OFFSET); 157 + val |= IXP4XX_OST_ENABLE; 158 + __raw_writel(val, tmr->base + IXP4XX_OSRT1_OFFSET); 159 + 160 + return 0; 161 + } 162 + 163 + /* 164 + * IXP4xx timer tick 165 + * We use OS timer1 on the CPU for the timer tick and the timestamp 166 + * counter as a source of real clock ticks to account for missed jiffies. 167 + */ 168 + static __init int ixp4xx_timer_register(void __iomem *base, 169 + int timer_irq, 170 + unsigned int timer_freq) 171 + { 172 + struct ixp4xx_timer *tmr; 173 + int ret; 174 + 175 + tmr = kzalloc(sizeof(*tmr), GFP_KERNEL); 176 + if (!tmr) 177 + return -ENOMEM; 178 + tmr->base = base; 179 + tmr->tick_rate = timer_freq; 180 + 181 + /* 182 + * The timer register doesn't allow to specify the two least 183 + * significant bits of the timeout value and assumes them being zero. 184 + * So make sure the latch is the best value with the two least 185 + * significant bits unset. 186 + */ 187 + tmr->latch = DIV_ROUND_CLOSEST(timer_freq, 188 + (IXP4XX_OST_RELOAD_MASK + 1) * HZ) 189 + * (IXP4XX_OST_RELOAD_MASK + 1); 190 + 191 + local_ixp4xx_timer = tmr; 192 + 193 + /* Reset/disable counter */ 194 + __raw_writel(0, tmr->base + IXP4XX_OSRT1_OFFSET); 195 + 196 + /* Clear any pending interrupt on timer 1 */ 197 + __raw_writel(IXP4XX_OSST_TIMER_1_PEND, 198 + tmr->base + IXP4XX_OSST_OFFSET); 199 + 200 + /* Reset time-stamp counter */ 201 + __raw_writel(0, tmr->base + IXP4XX_OSTS_OFFSET); 202 + 203 + clocksource_mmio_init(NULL, "OSTS", timer_freq, 200, 32, 204 + ixp4xx_clocksource_read); 205 + 206 + tmr->clkevt.name = "ixp4xx timer1"; 207 + tmr->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 208 + tmr->clkevt.rating = 200; 209 + tmr->clkevt.set_state_shutdown = ixp4xx_shutdown; 210 + tmr->clkevt.set_state_periodic = ixp4xx_set_periodic; 211 + tmr->clkevt.set_state_oneshot = ixp4xx_set_oneshot; 212 + tmr->clkevt.tick_resume = ixp4xx_resume; 213 + tmr->clkevt.set_next_event = ixp4xx_set_next_event; 214 + tmr->clkevt.cpumask = cpumask_of(0); 215 + tmr->clkevt.irq = timer_irq; 216 + ret = request_irq(timer_irq, ixp4xx_timer_interrupt, 217 + IRQF_TIMER, "IXP4XX-TIMER1", tmr); 218 + if (ret) { 219 + pr_crit("no timer IRQ\n"); 220 + return -ENODEV; 221 + } 222 + clockevents_config_and_register(&tmr->clkevt, timer_freq, 223 + 0xf, 0xfffffffe); 224 + 225 + #ifdef CONFIG_ARM 226 + sched_clock_register(ixp4xx_read_sched_clock, 32, timer_freq); 227 + #endif 228 + 229 + return 0; 230 + } 231 + 232 + /** 233 + * ixp4xx_timer_setup() - Timer setup function to be called from boardfiles 234 + * @timerbase: physical base of timer block 235 + * @timer_irq: Linux IRQ number for the timer 236 + * @timer_freq: Fixed frequency of the timer 237 + */ 238 + void __init ixp4xx_timer_setup(resource_size_t timerbase, 239 + int timer_irq, 240 + unsigned int timer_freq) 241 + { 242 + void __iomem *base; 243 + 244 + base = ioremap(timerbase, 0x100); 245 + if (!base) { 246 + pr_crit("IXP4xx: can't remap timer\n"); 247 + return; 248 + } 249 + ixp4xx_timer_register(base, timer_irq, timer_freq); 250 + } 251 + EXPORT_SYMBOL_GPL(ixp4xx_timer_setup); 252 + 253 + #ifdef CONFIG_OF 254 + static __init int ixp4xx_of_timer_init(struct device_node *np) 255 + { 256 + void __iomem *base; 257 + int irq; 258 + int ret; 259 + 260 + base = of_iomap(np, 0); 261 + if (!base) { 262 + pr_crit("IXP4xx: can't remap timer\n"); 263 + return -ENODEV; 264 + } 265 + 266 + irq = irq_of_parse_and_map(np, 0); 267 + if (irq <= 0) { 268 + pr_err("Can't parse IRQ\n"); 269 + ret = -EINVAL; 270 + goto out_unmap; 271 + } 272 + 273 + /* TODO: get some fixed clocks into the device tree */ 274 + ret = ixp4xx_timer_register(base, irq, 66666000); 275 + if (ret) 276 + goto out_unmap; 277 + return 0; 278 + 279 + out_unmap: 280 + iounmap(base); 281 + return ret; 282 + } 283 + TIMER_OF_DECLARE(ixp4xx, "intel,ixp4xx-timer", ixp4xx_of_timer_init); 284 + #endif
+2 -2
drivers/crypto/ixp4xx_crypto.c
··· 30 30 #include <crypto/authenc.h> 31 31 #include <crypto/scatterwalk.h> 32 32 33 - #include <mach/npe.h> 34 - #include <mach/qmgr.h> 33 + #include <linux/soc/ixp4xx/npe.h> 34 + #include <linux/soc/ixp4xx/qmgr.h> 35 35 36 36 #define MAX_KEYLEN 32 37 37
+13
drivers/gpio/Kconfig
··· 287 287 288 288 If unsure, say N. 289 289 290 + config GPIO_IXP4XX 291 + bool "Intel IXP4xx GPIO" 292 + depends on ARM # For <asm/mach-types.h> 293 + depends on ARCH_IXP4XX 294 + select GPIO_GENERIC 295 + select IRQ_DOMAIN 296 + select IRQ_DOMAIN_HIERARCHY 297 + help 298 + Say yes here to support the GPIO functionality of a number of Intel 299 + IXP4xx series of chips. 300 + 301 + If unsure, say N. 302 + 290 303 config GPIO_LOONGSON 291 304 bool "Loongson-2/3 GPIO support" 292 305 depends on CPU_LOONGSON2 || CPU_LOONGSON3
+1
drivers/gpio/Makefile
··· 61 61 obj-$(CONFIG_HTC_EGPIO) += gpio-htc-egpio.o 62 62 obj-$(CONFIG_GPIO_ICH) += gpio-ich.o 63 63 obj-$(CONFIG_GPIO_IOP) += gpio-iop.o 64 + obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o 64 65 obj-$(CONFIG_GPIO_IT87) += gpio-it87.o 65 66 obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o 66 67 obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o
+474
drivers/gpio/gpio-ixp4xx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // IXP4 GPIO driver 4 + // Copyright (C) 2019 Linus Walleij <linus.walleij@linaro.org> 5 + // 6 + // based on previous work and know-how from: 7 + // Deepak Saxena <dsaxena@plexity.net> 8 + 9 + #include <linux/gpio/driver.h> 10 + #include <linux/io.h> 11 + #include <linux/irq.h> 12 + #include <linux/irqdomain.h> 13 + #include <linux/irqchip.h> 14 + #include <linux/of_irq.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/bitops.h> 17 + /* Include that go away with DT transition */ 18 + #include <linux/irqchip/irq-ixp4xx.h> 19 + 20 + #include <asm/mach-types.h> 21 + 22 + #define IXP4XX_REG_GPOUT 0x00 23 + #define IXP4XX_REG_GPOE 0x04 24 + #define IXP4XX_REG_GPIN 0x08 25 + #define IXP4XX_REG_GPIS 0x0C 26 + #define IXP4XX_REG_GPIT1 0x10 27 + #define IXP4XX_REG_GPIT2 0x14 28 + #define IXP4XX_REG_GPCLK 0x18 29 + #define IXP4XX_REG_GPDBSEL 0x1C 30 + 31 + /* 32 + * The hardware uses 3 bits to indicate interrupt "style". 33 + * we clear and set these three bits accordingly. The lower 24 34 + * bits in two registers (GPIT1 and GPIT2) are used to set up 35 + * the style for 8 lines each for a total of 16 GPIO lines. 36 + */ 37 + #define IXP4XX_GPIO_STYLE_ACTIVE_HIGH 0x0 38 + #define IXP4XX_GPIO_STYLE_ACTIVE_LOW 0x1 39 + #define IXP4XX_GPIO_STYLE_RISING_EDGE 0x2 40 + #define IXP4XX_GPIO_STYLE_FALLING_EDGE 0x3 41 + #define IXP4XX_GPIO_STYLE_TRANSITIONAL 0x4 42 + #define IXP4XX_GPIO_STYLE_MASK GENMASK(2, 0) 43 + #define IXP4XX_GPIO_STYLE_SIZE 3 44 + 45 + /** 46 + * struct ixp4xx_gpio - IXP4 GPIO state container 47 + * @dev: containing device for this instance 48 + * @fwnode: the fwnode for this GPIO chip 49 + * @gc: gpiochip for this instance 50 + * @domain: irqdomain for this chip instance 51 + * @base: remapped I/O-memory base 52 + * @irq_edge: Each bit represents an IRQ: 1: edge-triggered, 53 + * 0: level triggered 54 + */ 55 + struct ixp4xx_gpio { 56 + struct device *dev; 57 + struct fwnode_handle *fwnode; 58 + struct gpio_chip gc; 59 + struct irq_domain *domain; 60 + void __iomem *base; 61 + unsigned long long irq_edge; 62 + }; 63 + 64 + /** 65 + * struct ixp4xx_gpio_map - IXP4 GPIO to parent IRQ map 66 + * @gpio_offset: offset of the IXP4 GPIO line 67 + * @parent_hwirq: hwirq on the parent IRQ controller 68 + */ 69 + struct ixp4xx_gpio_map { 70 + int gpio_offset; 71 + int parent_hwirq; 72 + }; 73 + 74 + /* GPIO lines 0..12 have corresponding IRQs, GPIOs 13..15 have no IRQs */ 75 + const struct ixp4xx_gpio_map ixp4xx_gpiomap[] = { 76 + { .gpio_offset = 0, .parent_hwirq = 6 }, 77 + { .gpio_offset = 1, .parent_hwirq = 7 }, 78 + { .gpio_offset = 2, .parent_hwirq = 19 }, 79 + { .gpio_offset = 3, .parent_hwirq = 20 }, 80 + { .gpio_offset = 4, .parent_hwirq = 21 }, 81 + { .gpio_offset = 5, .parent_hwirq = 22 }, 82 + { .gpio_offset = 6, .parent_hwirq = 23 }, 83 + { .gpio_offset = 7, .parent_hwirq = 24 }, 84 + { .gpio_offset = 8, .parent_hwirq = 25 }, 85 + { .gpio_offset = 9, .parent_hwirq = 26 }, 86 + { .gpio_offset = 10, .parent_hwirq = 27 }, 87 + { .gpio_offset = 11, .parent_hwirq = 28 }, 88 + { .gpio_offset = 12, .parent_hwirq = 29 }, 89 + }; 90 + 91 + static void ixp4xx_gpio_irq_ack(struct irq_data *d) 92 + { 93 + struct ixp4xx_gpio *g = irq_data_get_irq_chip_data(d); 94 + 95 + __raw_writel(BIT(d->hwirq), g->base + IXP4XX_REG_GPIS); 96 + } 97 + 98 + static void ixp4xx_gpio_irq_unmask(struct irq_data *d) 99 + { 100 + struct ixp4xx_gpio *g = irq_data_get_irq_chip_data(d); 101 + 102 + /* ACK when unmasking if not edge-triggered */ 103 + if (!(g->irq_edge & BIT(d->hwirq))) 104 + ixp4xx_gpio_irq_ack(d); 105 + 106 + irq_chip_unmask_parent(d); 107 + } 108 + 109 + static int ixp4xx_gpio_irq_set_type(struct irq_data *d, unsigned int type) 110 + { 111 + struct ixp4xx_gpio *g = irq_data_get_irq_chip_data(d); 112 + int line = d->hwirq; 113 + unsigned long flags; 114 + u32 int_style; 115 + u32 int_reg; 116 + u32 val; 117 + 118 + switch (type) { 119 + case IRQ_TYPE_EDGE_BOTH: 120 + irq_set_handler_locked(d, handle_edge_irq); 121 + int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL; 122 + g->irq_edge |= BIT(d->hwirq); 123 + break; 124 + case IRQ_TYPE_EDGE_RISING: 125 + irq_set_handler_locked(d, handle_edge_irq); 126 + int_style = IXP4XX_GPIO_STYLE_RISING_EDGE; 127 + g->irq_edge |= BIT(d->hwirq); 128 + break; 129 + case IRQ_TYPE_EDGE_FALLING: 130 + irq_set_handler_locked(d, handle_edge_irq); 131 + int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE; 132 + g->irq_edge |= BIT(d->hwirq); 133 + break; 134 + case IRQ_TYPE_LEVEL_HIGH: 135 + irq_set_handler_locked(d, handle_level_irq); 136 + int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH; 137 + g->irq_edge &= ~BIT(d->hwirq); 138 + break; 139 + case IRQ_TYPE_LEVEL_LOW: 140 + irq_set_handler_locked(d, handle_level_irq); 141 + int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW; 142 + g->irq_edge &= ~BIT(d->hwirq); 143 + break; 144 + default: 145 + return -EINVAL; 146 + } 147 + 148 + if (line >= 8) { 149 + /* pins 8-15 */ 150 + line -= 8; 151 + int_reg = IXP4XX_REG_GPIT2; 152 + } else { 153 + /* pins 0-7 */ 154 + int_reg = IXP4XX_REG_GPIT1; 155 + } 156 + 157 + spin_lock_irqsave(&g->gc.bgpio_lock, flags); 158 + 159 + /* Clear the style for the appropriate pin */ 160 + val = __raw_readl(g->base + int_reg); 161 + val &= ~(IXP4XX_GPIO_STYLE_MASK << (line * IXP4XX_GPIO_STYLE_SIZE)); 162 + __raw_writel(val, g->base + int_reg); 163 + 164 + __raw_writel(BIT(line), g->base + IXP4XX_REG_GPIS); 165 + 166 + /* Set the new style */ 167 + val = __raw_readl(g->base + int_reg); 168 + val |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE)); 169 + __raw_writel(val, g->base + int_reg); 170 + 171 + /* Force-configure this line as an input */ 172 + val = __raw_readl(g->base + IXP4XX_REG_GPOE); 173 + val |= BIT(d->hwirq); 174 + __raw_writel(val, g->base + IXP4XX_REG_GPOE); 175 + 176 + spin_unlock_irqrestore(&g->gc.bgpio_lock, flags); 177 + 178 + /* This parent only accept level high (asserted) */ 179 + return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH); 180 + } 181 + 182 + static struct irq_chip ixp4xx_gpio_irqchip = { 183 + .name = "IXP4GPIO", 184 + .irq_ack = ixp4xx_gpio_irq_ack, 185 + .irq_mask = irq_chip_mask_parent, 186 + .irq_unmask = ixp4xx_gpio_irq_unmask, 187 + .irq_set_type = ixp4xx_gpio_irq_set_type, 188 + }; 189 + 190 + static int ixp4xx_gpio_to_irq(struct gpio_chip *gc, unsigned int offset) 191 + { 192 + struct ixp4xx_gpio *g = gpiochip_get_data(gc); 193 + struct irq_fwspec fwspec; 194 + 195 + fwspec.fwnode = g->fwnode; 196 + fwspec.param_count = 2; 197 + fwspec.param[0] = offset; 198 + fwspec.param[1] = IRQ_TYPE_NONE; 199 + 200 + return irq_create_fwspec_mapping(&fwspec); 201 + } 202 + 203 + static int ixp4xx_gpio_irq_domain_translate(struct irq_domain *domain, 204 + struct irq_fwspec *fwspec, 205 + unsigned long *hwirq, 206 + unsigned int *type) 207 + { 208 + 209 + /* We support standard DT translation */ 210 + if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) { 211 + *hwirq = fwspec->param[0]; 212 + *type = fwspec->param[1]; 213 + return 0; 214 + } 215 + 216 + /* This goes away when we transition to DT */ 217 + if (is_fwnode_irqchip(fwspec->fwnode)) { 218 + if (fwspec->param_count != 2) 219 + return -EINVAL; 220 + *hwirq = fwspec->param[0]; 221 + *type = fwspec->param[1]; 222 + WARN_ON(*type == IRQ_TYPE_NONE); 223 + return 0; 224 + } 225 + return -EINVAL; 226 + } 227 + 228 + static int ixp4xx_gpio_irq_domain_alloc(struct irq_domain *d, 229 + unsigned int irq, unsigned int nr_irqs, 230 + void *data) 231 + { 232 + struct ixp4xx_gpio *g = d->host_data; 233 + irq_hw_number_t hwirq; 234 + unsigned int type = IRQ_TYPE_NONE; 235 + struct irq_fwspec *fwspec = data; 236 + int ret; 237 + int i; 238 + 239 + ret = ixp4xx_gpio_irq_domain_translate(d, fwspec, &hwirq, &type); 240 + if (ret) 241 + return ret; 242 + 243 + dev_dbg(g->dev, "allocate IRQ %d..%d, hwirq %lu..%lu\n", 244 + irq, irq + nr_irqs - 1, 245 + hwirq, hwirq + nr_irqs - 1); 246 + 247 + for (i = 0; i < nr_irqs; i++) { 248 + struct irq_fwspec parent_fwspec; 249 + const struct ixp4xx_gpio_map *map; 250 + int j; 251 + 252 + /* Not all lines support IRQs */ 253 + for (j = 0; j < ARRAY_SIZE(ixp4xx_gpiomap); j++) { 254 + map = &ixp4xx_gpiomap[j]; 255 + if (map->gpio_offset == hwirq) 256 + break; 257 + } 258 + if (j == ARRAY_SIZE(ixp4xx_gpiomap)) { 259 + dev_err(g->dev, "can't look up hwirq %lu\n", hwirq); 260 + return -EINVAL; 261 + } 262 + dev_dbg(g->dev, "found parent hwirq %u\n", map->parent_hwirq); 263 + 264 + /* 265 + * We set handle_bad_irq because the .set_type() should 266 + * always be invoked and set the right type of handler. 267 + */ 268 + irq_domain_set_info(d, 269 + irq + i, 270 + hwirq + i, 271 + &ixp4xx_gpio_irqchip, 272 + g, 273 + handle_bad_irq, 274 + NULL, NULL); 275 + irq_set_probe(irq + i); 276 + 277 + /* 278 + * Create a IRQ fwspec to send up to the parent irqdomain: 279 + * specify the hwirq we address on the parent and tie it 280 + * all together up the chain. 281 + */ 282 + parent_fwspec.fwnode = d->parent->fwnode; 283 + parent_fwspec.param_count = 2; 284 + parent_fwspec.param[0] = map->parent_hwirq; 285 + /* This parent only handles asserted level IRQs */ 286 + parent_fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH; 287 + dev_dbg(g->dev, "alloc_irqs_parent for %d parent hwirq %d\n", 288 + irq + i, map->parent_hwirq); 289 + ret = irq_domain_alloc_irqs_parent(d, irq + i, 1, 290 + &parent_fwspec); 291 + if (ret) 292 + dev_err(g->dev, 293 + "failed to allocate parent hwirq %d for hwirq %lu\n", 294 + map->parent_hwirq, hwirq); 295 + } 296 + 297 + return 0; 298 + } 299 + 300 + static const struct irq_domain_ops ixp4xx_gpio_irqdomain_ops = { 301 + .translate = ixp4xx_gpio_irq_domain_translate, 302 + .alloc = ixp4xx_gpio_irq_domain_alloc, 303 + .free = irq_domain_free_irqs_common, 304 + }; 305 + 306 + static int ixp4xx_gpio_probe(struct platform_device *pdev) 307 + { 308 + unsigned long flags; 309 + struct device *dev = &pdev->dev; 310 + struct device_node *np = dev->of_node; 311 + struct irq_domain *parent; 312 + struct resource *res; 313 + struct ixp4xx_gpio *g; 314 + int ret; 315 + int i; 316 + 317 + g = devm_kzalloc(dev, sizeof(*g), GFP_KERNEL); 318 + if (!g) 319 + return -ENOMEM; 320 + g->dev = dev; 321 + 322 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 323 + g->base = devm_ioremap_resource(dev, res); 324 + if (IS_ERR(g->base)) { 325 + dev_err(dev, "ioremap error\n"); 326 + return PTR_ERR(g->base); 327 + } 328 + 329 + /* 330 + * Make sure GPIO 14 and 15 are NOT used as clocks but GPIO on 331 + * specific machines. 332 + */ 333 + if (machine_is_dsmg600() || machine_is_nas100d()) 334 + __raw_writel(0x0, g->base + IXP4XX_REG_GPCLK); 335 + 336 + /* 337 + * This is a very special big-endian ARM issue: when the IXP4xx is 338 + * run in big endian mode, all registers in the machine are switched 339 + * around to the CPU-native endianness. As you see mostly in the 340 + * driver we use __raw_readl()/__raw_writel() to access the registers 341 + * in the appropriate order. With the GPIO library we need to specify 342 + * byte order explicitly, so this flag needs to be set when compiling 343 + * for big endian. 344 + */ 345 + #if defined(CONFIG_CPU_BIG_ENDIAN) 346 + flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER; 347 + #else 348 + flags = 0; 349 + #endif 350 + 351 + /* Populate and register gpio chip */ 352 + ret = bgpio_init(&g->gc, dev, 4, 353 + g->base + IXP4XX_REG_GPIN, 354 + g->base + IXP4XX_REG_GPOUT, 355 + NULL, 356 + NULL, 357 + g->base + IXP4XX_REG_GPOE, 358 + flags); 359 + if (ret) { 360 + dev_err(dev, "unable to init generic GPIO\n"); 361 + return ret; 362 + } 363 + g->gc.to_irq = ixp4xx_gpio_to_irq; 364 + g->gc.ngpio = 16; 365 + g->gc.label = "IXP4XX_GPIO_CHIP"; 366 + /* 367 + * TODO: when we have migrated to device tree and all GPIOs 368 + * are fetched using phandles, set this to -1 to get rid of 369 + * the fixed gpiochip base. 370 + */ 371 + g->gc.base = 0; 372 + g->gc.parent = &pdev->dev; 373 + g->gc.owner = THIS_MODULE; 374 + 375 + ret = devm_gpiochip_add_data(dev, &g->gc, g); 376 + if (ret) { 377 + dev_err(dev, "failed to add SoC gpiochip\n"); 378 + return ret; 379 + } 380 + 381 + /* 382 + * When we convert to device tree we will simply look up the 383 + * parent irqdomain using irq_find_host(parent) as parent comes 384 + * from IRQCHIP_DECLARE(), then use of_node_to_fwnode() to get 385 + * the fwnode. For now we need this boardfile style code. 386 + */ 387 + if (np) { 388 + struct device_node *irq_parent; 389 + 390 + irq_parent = of_irq_find_parent(np); 391 + if (!irq_parent) { 392 + dev_err(dev, "no IRQ parent node\n"); 393 + return -ENODEV; 394 + } 395 + parent = irq_find_host(irq_parent); 396 + if (!parent) { 397 + dev_err(dev, "no IRQ parent domain\n"); 398 + return -ENODEV; 399 + } 400 + g->fwnode = of_node_to_fwnode(np); 401 + } else { 402 + parent = ixp4xx_get_irq_domain(); 403 + g->fwnode = irq_domain_alloc_fwnode(g->base); 404 + if (!g->fwnode) { 405 + dev_err(dev, "no domain base\n"); 406 + return -ENODEV; 407 + } 408 + } 409 + g->domain = irq_domain_create_hierarchy(parent, 410 + IRQ_DOMAIN_FLAG_HIERARCHY, 411 + ARRAY_SIZE(ixp4xx_gpiomap), 412 + g->fwnode, 413 + &ixp4xx_gpio_irqdomain_ops, 414 + g); 415 + if (!g->domain) { 416 + irq_domain_free_fwnode(g->fwnode); 417 + dev_err(dev, "no hierarchical irq domain\n"); 418 + return ret; 419 + } 420 + 421 + /* 422 + * After adding OF support, this is no longer needed: irqs 423 + * will be allocated for the respective fwnodes. 424 + */ 425 + if (!np) { 426 + for (i = 0; i < ARRAY_SIZE(ixp4xx_gpiomap); i++) { 427 + const struct ixp4xx_gpio_map *map = &ixp4xx_gpiomap[i]; 428 + struct irq_fwspec fwspec; 429 + 430 + fwspec.fwnode = g->fwnode; 431 + /* This is the hwirq for the GPIO line side of things */ 432 + fwspec.param[0] = map->gpio_offset; 433 + fwspec.param[1] = IRQ_TYPE_EDGE_RISING; 434 + fwspec.param_count = 2; 435 + ret = __irq_domain_alloc_irqs(g->domain, 436 + -1, /* just pick something */ 437 + 1, 438 + NUMA_NO_NODE, 439 + &fwspec, 440 + false, 441 + NULL); 442 + if (ret < 0) { 443 + irq_domain_free_fwnode(g->fwnode); 444 + dev_err(dev, 445 + "can not allocate irq for GPIO line %d parent hwirq %d in hierarchy domain: %d\n", 446 + map->gpio_offset, map->parent_hwirq, 447 + ret); 448 + return ret; 449 + } 450 + } 451 + } 452 + 453 + platform_set_drvdata(pdev, g); 454 + dev_info(dev, "IXP4 GPIO @%p registered\n", g->base); 455 + 456 + return 0; 457 + } 458 + 459 + static const struct of_device_id ixp4xx_gpio_of_match[] = { 460 + { 461 + .compatible = "intel,ixp4xx-gpio", 462 + }, 463 + {}, 464 + }; 465 + 466 + 467 + static struct platform_driver ixp4xx_gpio_driver = { 468 + .driver = { 469 + .name = "ixp4xx-gpio", 470 + .of_match_table = of_match_ptr(ixp4xx_gpio_of_match), 471 + }, 472 + .probe = ixp4xx_gpio_probe, 473 + }; 474 + builtin_platform_driver(ixp4xx_gpio_driver);
+15 -5
drivers/input/misc/ixp4xx-beeper.c
··· 30 30 31 31 static DEFINE_SPINLOCK(beep_lock); 32 32 33 + static int ixp4xx_timer2_irq; 34 + 33 35 static void ixp4xx_spkr_control(unsigned int pin, unsigned int count) 34 36 { 35 37 unsigned long flags; ··· 92 90 static int ixp4xx_spkr_probe(struct platform_device *dev) 93 91 { 94 92 struct input_dev *input_dev; 93 + int irq; 95 94 int err; 96 95 97 96 input_dev = input_allocate_device(); ··· 113 110 input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); 114 111 input_dev->event = ixp4xx_spkr_event; 115 112 113 + irq = platform_get_irq(dev, 0); 114 + if (irq < 0) { 115 + err = irq; 116 + goto err_free_device; 117 + } 118 + 116 119 err = gpio_request(dev->id, "ixp4-beeper"); 117 120 if (err) 118 121 goto err_free_device; 119 122 120 - err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt, 123 + err = request_irq(irq, &ixp4xx_spkr_interrupt, 121 124 IRQF_NO_SUSPEND, "ixp4xx-beeper", 122 125 (void *) dev->id); 123 126 if (err) 124 127 goto err_free_gpio; 128 + ixp4xx_timer2_irq = irq; 125 129 126 130 err = input_register_device(input_dev); 127 131 if (err) ··· 139 129 return 0; 140 130 141 131 err_free_irq: 142 - free_irq(IRQ_IXP4XX_TIMER2, (void *)dev->id); 132 + free_irq(irq, (void *)dev->id); 143 133 err_free_gpio: 144 134 gpio_free(dev->id); 145 135 err_free_device: ··· 156 146 input_unregister_device(input_dev); 157 147 158 148 /* turn the speaker off */ 159 - disable_irq(IRQ_IXP4XX_TIMER2); 149 + disable_irq(ixp4xx_timer2_irq); 160 150 ixp4xx_spkr_control(pin, 0); 161 151 162 - free_irq(IRQ_IXP4XX_TIMER2, (void *)dev->id); 152 + free_irq(ixp4xx_timer2_irq, (void *)dev->id); 163 153 gpio_free(dev->id); 164 154 165 155 return 0; ··· 171 161 unsigned int pin = (unsigned int) input_get_drvdata(input_dev); 172 162 173 163 /* turn off the speaker */ 174 - disable_irq(IRQ_IXP4XX_TIMER2); 164 + disable_irq(ixp4xx_timer2_irq); 175 165 ixp4xx_spkr_control(pin, 0); 176 166 } 177 167
+6
drivers/irqchip/Kconfig
··· 160 160 select GENERIC_IRQ_CHIP 161 161 select IRQ_DOMAIN 162 162 163 + config IXP4XX_IRQ 164 + bool 165 + select IRQ_DOMAIN 166 + select GENERIC_IRQ_MULTI_HANDLER 167 + select SPARSE_IRQ 168 + 163 169 config MADERA_IRQ 164 170 tristate 165 171
+1
drivers/irqchip/Makefile
··· 43 43 obj-$(CONFIG_I8259) += irq-i8259.o 44 44 obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o 45 45 obj-$(CONFIG_IRQ_MIPS_CPU) += irq-mips-cpu.o 46 + obj-$(CONFIG_IXP4XX_IRQ) += irq-ixp4xx.o 46 47 obj-$(CONFIG_SIRF_IRQ) += irq-sirfsoc.o 47 48 obj-$(CONFIG_JCORE_AIC) += irq-jcore-aic.o 48 49 obj-$(CONFIG_RDA_INTC) += irq-rda-intc.o
+403
drivers/irqchip/irq-ixp4xx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * irqchip for the IXP4xx interrupt controller 4 + * Copyright (C) 2019 Linus Walleij <linus.walleij@linaro.org> 5 + * 6 + * Based on arch/arm/mach-ixp4xx/common.c 7 + * Copyright 2002 (C) Intel Corporation 8 + * Copyright 2003-2004 (C) MontaVista, Software, Inc. 9 + * Copyright (C) Deepak Saxena <dsaxena@plexity.net> 10 + */ 11 + #include <linux/bitops.h> 12 + #include <linux/gpio/driver.h> 13 + #include <linux/irq.h> 14 + #include <linux/io.h> 15 + #include <linux/irqchip.h> 16 + #include <linux/irqchip/irq-ixp4xx.h> 17 + #include <linux/irqdomain.h> 18 + #include <linux/of.h> 19 + #include <linux/of_address.h> 20 + #include <linux/of_irq.h> 21 + #include <linux/platform_device.h> 22 + #include <linux/cpu.h> 23 + 24 + #include <asm/exception.h> 25 + #include <asm/mach/irq.h> 26 + 27 + #define IXP4XX_ICPR 0x00 /* Interrupt Status */ 28 + #define IXP4XX_ICMR 0x04 /* Interrupt Enable */ 29 + #define IXP4XX_ICLR 0x08 /* Interrupt IRQ/FIQ Select */ 30 + #define IXP4XX_ICIP 0x0C /* IRQ Status */ 31 + #define IXP4XX_ICFP 0x10 /* FIQ Status */ 32 + #define IXP4XX_ICHR 0x14 /* Interrupt Priority */ 33 + #define IXP4XX_ICIH 0x18 /* IRQ Highest Pri Int */ 34 + #define IXP4XX_ICFH 0x1C /* FIQ Highest Pri Int */ 35 + 36 + /* IXP43x and IXP46x-only */ 37 + #define IXP4XX_ICPR2 0x20 /* Interrupt Status 2 */ 38 + #define IXP4XX_ICMR2 0x24 /* Interrupt Enable 2 */ 39 + #define IXP4XX_ICLR2 0x28 /* Interrupt IRQ/FIQ Select 2 */ 40 + #define IXP4XX_ICIP2 0x2C /* IRQ Status */ 41 + #define IXP4XX_ICFP2 0x30 /* FIQ Status */ 42 + #define IXP4XX_ICEEN 0x34 /* Error High Pri Enable */ 43 + 44 + /** 45 + * struct ixp4xx_irq - state container for the Faraday IRQ controller 46 + * @irqbase: IRQ controller memory base in virtual memory 47 + * @is_356: if this is an IXP43x, IXP45x or IX46x SoC (with 64 IRQs) 48 + * @irqchip: irqchip for this instance 49 + * @domain: IRQ domain for this instance 50 + */ 51 + struct ixp4xx_irq { 52 + void __iomem *irqbase; 53 + bool is_356; 54 + struct irq_chip irqchip; 55 + struct irq_domain *domain; 56 + }; 57 + 58 + /* Local static state container */ 59 + static struct ixp4xx_irq ixirq; 60 + 61 + /* GPIO Clocks */ 62 + #define IXP4XX_GPIO_CLK_0 14 63 + #define IXP4XX_GPIO_CLK_1 15 64 + 65 + static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type) 66 + { 67 + /* All are level active high (asserted) here */ 68 + if (type != IRQ_TYPE_LEVEL_HIGH) 69 + return -EINVAL; 70 + return 0; 71 + } 72 + 73 + static void ixp4xx_irq_mask(struct irq_data *d) 74 + { 75 + struct ixp4xx_irq *ixi = irq_data_get_irq_chip_data(d); 76 + u32 val; 77 + 78 + if (ixi->is_356 && d->hwirq >= 32) { 79 + val = __raw_readl(ixi->irqbase + IXP4XX_ICMR2); 80 + val &= ~BIT(d->hwirq - 32); 81 + __raw_writel(val, ixi->irqbase + IXP4XX_ICMR2); 82 + } else { 83 + val = __raw_readl(ixi->irqbase + IXP4XX_ICMR); 84 + val &= ~BIT(d->hwirq); 85 + __raw_writel(val, ixi->irqbase + IXP4XX_ICMR); 86 + } 87 + } 88 + 89 + /* 90 + * Level triggered interrupts on GPIO lines can only be cleared when the 91 + * interrupt condition disappears. 92 + */ 93 + static void ixp4xx_irq_unmask(struct irq_data *d) 94 + { 95 + struct ixp4xx_irq *ixi = irq_data_get_irq_chip_data(d); 96 + u32 val; 97 + 98 + if (ixi->is_356 && d->hwirq >= 32) { 99 + val = __raw_readl(ixi->irqbase + IXP4XX_ICMR2); 100 + val |= BIT(d->hwirq - 32); 101 + __raw_writel(val, ixi->irqbase + IXP4XX_ICMR2); 102 + } else { 103 + val = __raw_readl(ixi->irqbase + IXP4XX_ICMR); 104 + val |= BIT(d->hwirq); 105 + __raw_writel(val, ixi->irqbase + IXP4XX_ICMR); 106 + } 107 + } 108 + 109 + asmlinkage void __exception_irq_entry ixp4xx_handle_irq(struct pt_regs *regs) 110 + { 111 + struct ixp4xx_irq *ixi = &ixirq; 112 + unsigned long status; 113 + int i; 114 + 115 + status = __raw_readl(ixi->irqbase + IXP4XX_ICIP); 116 + for_each_set_bit(i, &status, 32) 117 + handle_domain_irq(ixi->domain, i, regs); 118 + 119 + /* 120 + * IXP465/IXP435 has an upper IRQ status register 121 + */ 122 + if (ixi->is_356) { 123 + status = __raw_readl(ixi->irqbase + IXP4XX_ICIP2); 124 + for_each_set_bit(i, &status, 32) 125 + handle_domain_irq(ixi->domain, i + 32, regs); 126 + } 127 + } 128 + 129 + static int ixp4xx_irq_domain_translate(struct irq_domain *domain, 130 + struct irq_fwspec *fwspec, 131 + unsigned long *hwirq, 132 + unsigned int *type) 133 + { 134 + /* We support standard DT translation */ 135 + if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) { 136 + *hwirq = fwspec->param[0]; 137 + *type = fwspec->param[1]; 138 + return 0; 139 + } 140 + 141 + if (is_fwnode_irqchip(fwspec->fwnode)) { 142 + if (fwspec->param_count != 2) 143 + return -EINVAL; 144 + *hwirq = fwspec->param[0]; 145 + *type = fwspec->param[1]; 146 + WARN_ON(*type == IRQ_TYPE_NONE); 147 + return 0; 148 + } 149 + 150 + return -EINVAL; 151 + } 152 + 153 + static int ixp4xx_irq_domain_alloc(struct irq_domain *d, 154 + unsigned int irq, unsigned int nr_irqs, 155 + void *data) 156 + { 157 + struct ixp4xx_irq *ixi = d->host_data; 158 + irq_hw_number_t hwirq; 159 + unsigned int type = IRQ_TYPE_NONE; 160 + struct irq_fwspec *fwspec = data; 161 + int ret; 162 + int i; 163 + 164 + ret = ixp4xx_irq_domain_translate(d, fwspec, &hwirq, &type); 165 + if (ret) 166 + return ret; 167 + 168 + for (i = 0; i < nr_irqs; i++) { 169 + /* 170 + * TODO: after converting IXP4xx to only device tree, set 171 + * handle_bad_irq as default handler and assume all consumers 172 + * call .set_type() as this is provided in the second cell in 173 + * the device tree phandle. 174 + */ 175 + irq_domain_set_info(d, 176 + irq + i, 177 + hwirq + i, 178 + &ixi->irqchip, 179 + ixi, 180 + handle_level_irq, 181 + NULL, NULL); 182 + irq_set_probe(irq + i); 183 + } 184 + 185 + return 0; 186 + } 187 + 188 + /* 189 + * This needs to be a hierarchical irqdomain to work well with the 190 + * GPIO irqchip (which is lower in the hierarchy) 191 + */ 192 + static const struct irq_domain_ops ixp4xx_irqdomain_ops = { 193 + .translate = ixp4xx_irq_domain_translate, 194 + .alloc = ixp4xx_irq_domain_alloc, 195 + .free = irq_domain_free_irqs_common, 196 + }; 197 + 198 + /** 199 + * ixp4xx_get_irq_domain() - retrieve the ixp4xx irq domain 200 + * 201 + * This function will go away when we transition to DT probing. 202 + */ 203 + struct irq_domain *ixp4xx_get_irq_domain(void) 204 + { 205 + struct ixp4xx_irq *ixi = &ixirq; 206 + 207 + return ixi->domain; 208 + } 209 + EXPORT_SYMBOL_GPL(ixp4xx_get_irq_domain); 210 + 211 + /* 212 + * This is the Linux IRQ to hwirq mapping table. This goes away when 213 + * we have DT support as all IRQ resources are defined in the device 214 + * tree. It will register all the IRQs that are not used by the hierarchical 215 + * GPIO IRQ chip. The "holes" inbetween these IRQs will be requested by 216 + * the GPIO driver using . This is a step-gap solution. 217 + */ 218 + struct ixp4xx_irq_chunk { 219 + int irq; 220 + int hwirq; 221 + int nr_irqs; 222 + }; 223 + 224 + static const struct ixp4xx_irq_chunk ixp4xx_irq_chunks[] = { 225 + { 226 + .irq = 16, 227 + .hwirq = 0, 228 + .nr_irqs = 6, 229 + }, 230 + { 231 + .irq = 24, 232 + .hwirq = 8, 233 + .nr_irqs = 11, 234 + }, 235 + { 236 + .irq = 46, 237 + .hwirq = 30, 238 + .nr_irqs = 2, 239 + }, 240 + /* Only on the 436 variants */ 241 + { 242 + .irq = 48, 243 + .hwirq = 32, 244 + .nr_irqs = 10, 245 + }, 246 + }; 247 + 248 + /** 249 + * ixp4x_irq_setup() - Common setup code for the IXP4xx interrupt controller 250 + * @ixi: State container 251 + * @irqbase: Virtual memory base for the interrupt controller 252 + * @fwnode: Corresponding fwnode abstraction for this controller 253 + * @is_356: if this is an IXP43x, IXP45x or IXP46x SoC variant 254 + */ 255 + static int ixp4xx_irq_setup(struct ixp4xx_irq *ixi, 256 + void __iomem *irqbase, 257 + struct fwnode_handle *fwnode, 258 + bool is_356) 259 + { 260 + int nr_irqs; 261 + 262 + ixi->irqbase = irqbase; 263 + ixi->is_356 = is_356; 264 + 265 + /* Route all sources to IRQ instead of FIQ */ 266 + __raw_writel(0x0, ixi->irqbase + IXP4XX_ICLR); 267 + 268 + /* Disable all interrupts */ 269 + __raw_writel(0x0, ixi->irqbase + IXP4XX_ICMR); 270 + 271 + if (is_356) { 272 + /* Route upper 32 sources to IRQ instead of FIQ */ 273 + __raw_writel(0x0, ixi->irqbase + IXP4XX_ICLR2); 274 + 275 + /* Disable upper 32 interrupts */ 276 + __raw_writel(0x0, ixi->irqbase + IXP4XX_ICMR2); 277 + 278 + nr_irqs = 64; 279 + } else { 280 + nr_irqs = 32; 281 + } 282 + 283 + ixi->irqchip.name = "IXP4xx"; 284 + ixi->irqchip.irq_mask = ixp4xx_irq_mask; 285 + ixi->irqchip.irq_unmask = ixp4xx_irq_unmask; 286 + ixi->irqchip.irq_set_type = ixp4xx_set_irq_type; 287 + 288 + ixi->domain = irq_domain_create_linear(fwnode, nr_irqs, 289 + &ixp4xx_irqdomain_ops, 290 + ixi); 291 + if (!ixi->domain) { 292 + pr_crit("IXP4XX: can not add primary irqdomain\n"); 293 + return -ENODEV; 294 + } 295 + 296 + set_handle_irq(ixp4xx_handle_irq); 297 + 298 + return 0; 299 + } 300 + 301 + /** 302 + * ixp4xx_irq_init() - Function to initialize the irqchip from boardfiles 303 + * @irqbase: physical base for the irq controller 304 + * @is_356: if this is an IXP43x, IXP45x or IXP46x SoC variant 305 + */ 306 + void __init ixp4xx_irq_init(resource_size_t irqbase, 307 + bool is_356) 308 + { 309 + struct ixp4xx_irq *ixi = &ixirq; 310 + void __iomem *base; 311 + struct fwnode_handle *fwnode; 312 + struct irq_fwspec fwspec; 313 + int nr_chunks; 314 + int ret; 315 + int i; 316 + 317 + base = ioremap(irqbase, 0x100); 318 + if (!base) { 319 + pr_crit("IXP4XX: could not ioremap interrupt controller\n"); 320 + return; 321 + } 322 + fwnode = irq_domain_alloc_fwnode(base); 323 + if (!fwnode) { 324 + pr_crit("IXP4XX: no domain handle\n"); 325 + return; 326 + } 327 + ret = ixp4xx_irq_setup(ixi, base, fwnode, is_356); 328 + if (ret) { 329 + pr_crit("IXP4XX: failed to set up irqchip\n"); 330 + irq_domain_free_fwnode(fwnode); 331 + } 332 + 333 + nr_chunks = ARRAY_SIZE(ixp4xx_irq_chunks); 334 + if (!is_356) 335 + nr_chunks--; 336 + 337 + /* 338 + * After adding OF support, this is no longer needed: irqs 339 + * will be allocated for the respective fwnodes. 340 + */ 341 + for (i = 0; i < nr_chunks; i++) { 342 + const struct ixp4xx_irq_chunk *chunk = &ixp4xx_irq_chunks[i]; 343 + 344 + pr_info("Allocate Linux IRQs %d..%d HW IRQs %d..%d\n", 345 + chunk->irq, chunk->irq + chunk->nr_irqs - 1, 346 + chunk->hwirq, chunk->hwirq + chunk->nr_irqs - 1); 347 + fwspec.fwnode = fwnode; 348 + fwspec.param[0] = chunk->hwirq; 349 + fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH; 350 + fwspec.param_count = 2; 351 + ret = __irq_domain_alloc_irqs(ixi->domain, 352 + chunk->irq, 353 + chunk->nr_irqs, 354 + NUMA_NO_NODE, 355 + &fwspec, 356 + false, 357 + NULL); 358 + if (ret < 0) { 359 + pr_crit("IXP4XX: can not allocate irqs in hierarchy %d\n", 360 + ret); 361 + return; 362 + } 363 + } 364 + } 365 + EXPORT_SYMBOL_GPL(ixp4xx_irq_init); 366 + 367 + #ifdef CONFIG_OF 368 + int __init ixp4xx_of_init_irq(struct device_node *np, 369 + struct device_node *parent) 370 + { 371 + struct ixp4xx_irq *ixi = &ixirq; 372 + void __iomem *base; 373 + struct fwnode_handle *fwnode; 374 + bool is_356; 375 + int ret; 376 + 377 + base = of_iomap(np, 0); 378 + if (!base) { 379 + pr_crit("IXP4XX: could not ioremap interrupt controller\n"); 380 + return -ENODEV; 381 + } 382 + fwnode = of_node_to_fwnode(np); 383 + 384 + /* These chip variants have 64 interrupts */ 385 + is_356 = of_device_is_compatible(np, "intel,ixp43x-interrupt") || 386 + of_device_is_compatible(np, "intel,ixp45x-interrupt") || 387 + of_device_is_compatible(np, "intel,ixp46x-interrupt"); 388 + 389 + ret = ixp4xx_irq_setup(ixi, base, fwnode, is_356); 390 + if (ret) 391 + pr_crit("IXP4XX: failed to set up irqchip\n"); 392 + 393 + return ret; 394 + } 395 + IRQCHIP_DECLARE(ixp42x, "intel,ixp42x-interrupt", 396 + ixp4xx_of_init_irq); 397 + IRQCHIP_DECLARE(ixp43x, "intel,ixp43x-interrupt", 398 + ixp4xx_of_init_irq); 399 + IRQCHIP_DECLARE(ixp45x, "intel,ixp45x-interrupt", 400 + ixp4xx_of_init_irq); 401 + IRQCHIP_DECLARE(ixp46x, "intel,ixp46x-interrupt", 402 + ixp4xx_of_init_irq); 403 + #endif
+12 -2
drivers/net/ethernet/xscale/ixp4xx_eth.c
··· 31 31 #include <linux/io.h> 32 32 #include <linux/kernel.h> 33 33 #include <linux/net_tstamp.h> 34 + #include <linux/of.h> 34 35 #include <linux/phy.h> 35 36 #include <linux/platform_device.h> 36 37 #include <linux/ptp_classify.h> 37 38 #include <linux/slab.h> 38 39 #include <linux/module.h> 39 40 #include <mach/ixp46x_ts.h> 40 - #include <mach/npe.h> 41 - #include <mach/qmgr.h> 41 + #include <linux/soc/ixp4xx/npe.h> 42 + #include <linux/soc/ixp4xx/qmgr.h> 42 43 43 44 #define DEBUG_DESC 0 44 45 #define DEBUG_RX 0 ··· 1498 1497 static int __init eth_init_module(void) 1499 1498 { 1500 1499 int err; 1500 + 1501 + /* 1502 + * FIXME: we bail out on device tree boot but this really needs 1503 + * to be fixed in a nicer way: this registers the MDIO bus before 1504 + * even matching the driver infrastructure, we should only probe 1505 + * detected hardware. 1506 + */ 1507 + if (of_have_populated_dt()) 1508 + return -ENODEV; 1501 1509 if ((err = ixp4xx_mdio_register())) 1502 1510 return err; 1503 1511 return platform_driver_register(&ixp4xx_eth_driver);
+2 -2
drivers/net/wan/ixp4xx_hss.c
··· 22 22 #include <linux/platform_device.h> 23 23 #include <linux/poll.h> 24 24 #include <linux/slab.h> 25 - #include <mach/npe.h> 26 - #include <mach/qmgr.h> 25 + #include <linux/soc/ixp4xx/npe.h> 26 + #include <linux/soc/ixp4xx/qmgr.h> 27 27 28 28 #define DEBUG_DESC 0 29 29 #define DEBUG_RX 0
+1
drivers/soc/Kconfig
··· 6 6 source "drivers/soc/bcm/Kconfig" 7 7 source "drivers/soc/fsl/Kconfig" 8 8 source "drivers/soc/imx/Kconfig" 9 + source "drivers/soc/ixp4xx/Kconfig" 9 10 source "drivers/soc/mediatek/Kconfig" 10 11 source "drivers/soc/qcom/Kconfig" 11 12 source "drivers/soc/renesas/Kconfig"
+1
drivers/soc/Makefile
··· 11 11 obj-y += fsl/ 12 12 obj-$(CONFIG_ARCH_GEMINI) += gemini/ 13 13 obj-$(CONFIG_ARCH_MXC) += imx/ 14 + obj-$(CONFIG_ARCH_IXP4XX) += ixp4xx/ 14 15 obj-$(CONFIG_SOC_XWAY) += lantiq/ 15 16 obj-y += mediatek/ 16 17 obj-y += amlogic/
+16
drivers/soc/ixp4xx/Kconfig
··· 1 + menu "IXP4xx SoC drivers" 2 + 3 + config IXP4XX_QMGR 4 + tristate "IXP4xx Queue Manager support" 5 + help 6 + This driver supports IXP4xx built-in hardware queue manager 7 + and is automatically selected by Ethernet and HSS drivers. 8 + 9 + config IXP4XX_NPE 10 + tristate "IXP4xx Network Processor Engine support" 11 + select FW_LOADER 12 + help 13 + This driver supports IXP4xx built-in network coprocessors 14 + and is automatically selected by Ethernet and HSS drivers. 15 + 16 + endmenu
+2
drivers/soc/ixp4xx/Makefile
··· 1 + obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx-qmgr.o 2 + obj-$(CONFIG_IXP4XX_NPE) += ixp4xx-npe.o
+9
drivers/watchdog/ixp4xx_wdt.c
··· 21 21 #include <linux/kernel.h> 22 22 #include <linux/fs.h> 23 23 #include <linux/miscdevice.h> 24 + #include <linux/of.h> 24 25 #include <linux/watchdog.h> 25 26 #include <linux/init.h> 26 27 #include <linux/bitops.h> ··· 177 176 { 178 177 int ret; 179 178 179 + /* 180 + * FIXME: we bail out on device tree boot but this really needs 181 + * to be fixed in a nicer way: this registers the MDIO bus before 182 + * even matching the driver infrastructure, we should only probe 183 + * detected hardware. 184 + */ 185 + if (of_have_populated_dt()) 186 + return -ENODEV; 180 187 if (!(read_cpuid_id() & 0xf) && !cpu_is_ixp46x()) { 181 188 pr_err("Rev. A0 IXP42x CPU detected - watchdog disabled\n"); 182 189
+12
include/linux/irqchip/irq-ixp4xx.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __IRQ_IXP4XX_H 3 + #define __IRQ_IXP4XX_H 4 + 5 + #include <linux/ioport.h> 6 + struct irq_domain; 7 + 8 + void ixp4xx_irq_init(resource_size_t irqbase, 9 + bool is_356); 10 + struct irq_domain *ixp4xx_get_irq_domain(void); 11 + 12 + #endif /* __IRQ_IXP4XX_H */
+11
include/linux/platform_data/timer-ixp4xx.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __TIMER_IXP4XX_H 3 + #define __TIMER_IXP4XX_H 4 + 5 + #include <linux/ioport.h> 6 + 7 + void __init ixp4xx_timer_setup(resource_size_t timerbase, 8 + int timer_irq, 9 + unsigned int timer_freq); 10 + 11 + #endif
+91
include/linux/soc/ixp4xx/qmgr.h
··· 1 + /* 2 + * Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl> 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms of version 2 of the GNU General Public License 6 + * as published by the Free Software Foundation. 7 + */ 8 + 9 + #ifndef IXP4XX_QMGR_H 10 + #define IXP4XX_QMGR_H 11 + 12 + #include <linux/io.h> 13 + #include <linux/kernel.h> 14 + 15 + #define DEBUG_QMGR 0 16 + 17 + #define HALF_QUEUES 32 18 + #define QUEUES 64 19 + #define MAX_QUEUE_LENGTH 4 /* in dwords */ 20 + 21 + #define QUEUE_STAT1_EMPTY 1 /* queue status bits */ 22 + #define QUEUE_STAT1_NEARLY_EMPTY 2 23 + #define QUEUE_STAT1_NEARLY_FULL 4 24 + #define QUEUE_STAT1_FULL 8 25 + #define QUEUE_STAT2_UNDERFLOW 1 26 + #define QUEUE_STAT2_OVERFLOW 2 27 + 28 + #define QUEUE_WATERMARK_0_ENTRIES 0 29 + #define QUEUE_WATERMARK_1_ENTRY 1 30 + #define QUEUE_WATERMARK_2_ENTRIES 2 31 + #define QUEUE_WATERMARK_4_ENTRIES 3 32 + #define QUEUE_WATERMARK_8_ENTRIES 4 33 + #define QUEUE_WATERMARK_16_ENTRIES 5 34 + #define QUEUE_WATERMARK_32_ENTRIES 6 35 + #define QUEUE_WATERMARK_64_ENTRIES 7 36 + 37 + /* queue interrupt request conditions */ 38 + #define QUEUE_IRQ_SRC_EMPTY 0 39 + #define QUEUE_IRQ_SRC_NEARLY_EMPTY 1 40 + #define QUEUE_IRQ_SRC_NEARLY_FULL 2 41 + #define QUEUE_IRQ_SRC_FULL 3 42 + #define QUEUE_IRQ_SRC_NOT_EMPTY 4 43 + #define QUEUE_IRQ_SRC_NOT_NEARLY_EMPTY 5 44 + #define QUEUE_IRQ_SRC_NOT_NEARLY_FULL 6 45 + #define QUEUE_IRQ_SRC_NOT_FULL 7 46 + 47 + struct qmgr_regs { 48 + u32 acc[QUEUES][MAX_QUEUE_LENGTH]; /* 0x000 - 0x3FF */ 49 + u32 stat1[4]; /* 0x400 - 0x40F */ 50 + u32 stat2[2]; /* 0x410 - 0x417 */ 51 + u32 statne_h; /* 0x418 - queue nearly empty */ 52 + u32 statf_h; /* 0x41C - queue full */ 53 + u32 irqsrc[4]; /* 0x420 - 0x42F IRC source */ 54 + u32 irqen[2]; /* 0x430 - 0x437 IRQ enabled */ 55 + u32 irqstat[2]; /* 0x438 - 0x43F - IRQ access only */ 56 + u32 reserved[1776]; 57 + u32 sram[2048]; /* 0x2000 - 0x3FFF - config and buffer */ 58 + }; 59 + 60 + void qmgr_put_entry(unsigned int queue, u32 val); 61 + u32 qmgr_get_entry(unsigned int queue); 62 + int qmgr_stat_empty(unsigned int queue); 63 + int qmgr_stat_below_low_watermark(unsigned int queue); 64 + int qmgr_stat_full(unsigned int queue); 65 + int qmgr_stat_overflow(unsigned int queue); 66 + void qmgr_release_queue(unsigned int queue); 67 + void qmgr_set_irq(unsigned int queue, int src, 68 + void (*handler)(void *pdev), void *pdev); 69 + void qmgr_enable_irq(unsigned int queue); 70 + void qmgr_disable_irq(unsigned int queue); 71 + 72 + /* request_ and release_queue() must be called from non-IRQ context */ 73 + 74 + #if DEBUG_QMGR 75 + extern char qmgr_queue_descs[QUEUES][32]; 76 + 77 + int qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */, 78 + unsigned int nearly_empty_watermark, 79 + unsigned int nearly_full_watermark, 80 + const char *desc_format, const char* name); 81 + #else 82 + int __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */, 83 + unsigned int nearly_empty_watermark, 84 + unsigned int nearly_full_watermark); 85 + #define qmgr_request_queue(queue, len, nearly_empty_watermark, \ 86 + nearly_full_watermark, desc_format, name) \ 87 + __qmgr_request_queue(queue, len, nearly_empty_watermark, \ 88 + nearly_full_watermark) 89 + #endif 90 + 91 + #endif