diff options
Diffstat (limited to 'arch/arm/mach-ixp4xx')
-rw-r--r-- | arch/arm/mach-ixp4xx/Kconfig | 8 | ||||
-rw-r--r-- | arch/arm/mach-ixp4xx/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-ixp4xx/include/mach/debug-macro.S | 2 | ||||
-rw-r--r-- | arch/arm/mach-ixp4xx/include/mach/io.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-ixp4xx/vulcan-pci.c | 73 | ||||
-rw-r--r-- | arch/arm/mach-ixp4xx/vulcan-setup.c | 246 |
6 files changed, 334 insertions, 3 deletions
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 9e5070da17ae..6f991c5ae863 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig | |||
@@ -140,6 +140,14 @@ config MACH_FSG | |||
140 | FSG-3 device. For more information on this platform, | 140 | FSG-3 device. For more information on this platform, |
141 | see http://www.nslu2-linux.org/wiki/FSG3/HomePage | 141 | see http://www.nslu2-linux.org/wiki/FSG3/HomePage |
142 | 142 | ||
143 | config MACH_ARCOM_VULCAN | ||
144 | bool | ||
145 | prompt "Arcom/Eurotech Vulcan" | ||
146 | select PCI | ||
147 | help | ||
148 | Say 'Y' here if you want your kernel to support Arcom's | ||
149 | Vulcan board. | ||
150 | |||
143 | # | 151 | # |
144 | # Certain registers and IRQs are only enabled if supporting IXP465 CPUs | 152 | # Certain registers and IRQs are only enabled if supporting IXP465 CPUs |
145 | # | 153 | # |
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile index 47d1f60d23fa..d807fc367dd3 100644 --- a/arch/arm/mach-ixp4xx/Makefile +++ b/arch/arm/mach-ixp4xx/Makefile | |||
@@ -16,6 +16,7 @@ obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o | |||
16 | obj-pci-$(CONFIG_MACH_GATEWAY7001) += gateway7001-pci.o | 16 | obj-pci-$(CONFIG_MACH_GATEWAY7001) += gateway7001-pci.o |
17 | obj-pci-$(CONFIG_MACH_WG302V2) += wg302v2-pci.o | 17 | obj-pci-$(CONFIG_MACH_WG302V2) += wg302v2-pci.o |
18 | obj-pci-$(CONFIG_MACH_FSG) += fsg-pci.o | 18 | obj-pci-$(CONFIG_MACH_FSG) += fsg-pci.o |
19 | obj-pci-$(CONFIG_MACH_ARCOM_VULCAN) += vulcan-pci.o | ||
19 | 20 | ||
20 | obj-y += common.o | 21 | obj-y += common.o |
21 | 22 | ||
@@ -31,6 +32,7 @@ obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o | |||
31 | obj-$(CONFIG_MACH_WG302V2) += wg302v2-setup.o | 32 | obj-$(CONFIG_MACH_WG302V2) += wg302v2-setup.o |
32 | obj-$(CONFIG_MACH_FSG) += fsg-setup.o | 33 | obj-$(CONFIG_MACH_FSG) += fsg-setup.o |
33 | obj-$(CONFIG_MACH_GORAMO_MLR) += goramo_mlr.o | 34 | obj-$(CONFIG_MACH_GORAMO_MLR) += goramo_mlr.o |
35 | obj-$(CONFIG_MACH_ARCOM_VULCAN) += vulcan-setup.o | ||
34 | 36 | ||
35 | obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o | 37 | obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o |
36 | obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx_qmgr.o | 38 | obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx_qmgr.o |
diff --git a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S index 893873eb2a0d..3fc66d6d00a0 100644 --- a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S +++ b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S | |||
@@ -16,8 +16,10 @@ | |||
16 | moveq \rx, #0xc8000000 | 16 | moveq \rx, #0xc8000000 |
17 | movne \rx, #0xff000000 | 17 | movne \rx, #0xff000000 |
18 | orrne \rx, \rx, #0x00b00000 | 18 | orrne \rx, \rx, #0x00b00000 |
19 | #ifdef __ARMEB__ | ||
19 | add \rx,\rx,#3 @ Uart regs are at off set of 3 if | 20 | add \rx,\rx,#3 @ Uart regs are at off set of 3 if |
20 | @ byte writes used - Big Endian. | 21 | @ byte writes used - Big Endian. |
22 | #endif | ||
21 | .endm | 23 | .endm |
22 | 24 | ||
23 | #define UART_SHIFT 2 | 25 | #define UART_SHIFT 2 |
diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h index 6ea7e2fb2701..de274a1f19d7 100644 --- a/arch/arm/mach-ixp4xx/include/mach/io.h +++ b/arch/arm/mach-ixp4xx/include/mach/io.h | |||
@@ -353,7 +353,7 @@ static inline unsigned int ioread8(const void __iomem *addr) | |||
353 | return (unsigned int)inb(port & PIO_MASK); | 353 | return (unsigned int)inb(port & PIO_MASK); |
354 | else | 354 | else |
355 | #ifndef CONFIG_IXP4XX_INDIRECT_PCI | 355 | #ifndef CONFIG_IXP4XX_INDIRECT_PCI |
356 | return (unsigned int)__raw_readb(port); | 356 | return (unsigned int)__raw_readb(addr); |
357 | #else | 357 | #else |
358 | return (unsigned int)__indirect_readb(addr); | 358 | return (unsigned int)__indirect_readb(addr); |
359 | #endif | 359 | #endif |
@@ -381,7 +381,7 @@ static inline unsigned int ioread16(const void __iomem *addr) | |||
381 | return (unsigned int)inw(port & PIO_MASK); | 381 | return (unsigned int)inw(port & PIO_MASK); |
382 | else | 382 | else |
383 | #ifndef CONFIG_IXP4XX_INDIRECT_PCI | 383 | #ifndef CONFIG_IXP4XX_INDIRECT_PCI |
384 | return le16_to_cpu(__raw_readw((u32)port)); | 384 | return le16_to_cpu((__force __le16)__raw_readw(addr)); |
385 | #else | 385 | #else |
386 | return (unsigned int)__indirect_readw(addr); | 386 | return (unsigned int)__indirect_readw(addr); |
387 | #endif | 387 | #endif |
@@ -440,7 +440,7 @@ static inline void iowrite8(u8 value, void __iomem *addr) | |||
440 | outb(value, port & PIO_MASK); | 440 | outb(value, port & PIO_MASK); |
441 | else | 441 | else |
442 | #ifndef CONFIG_IXP4XX_INDIRECT_PCI | 442 | #ifndef CONFIG_IXP4XX_INDIRECT_PCI |
443 | __raw_writeb(value, port); | 443 | __raw_writeb(value, addr); |
444 | #else | 444 | #else |
445 | __indirect_writeb(value, addr); | 445 | __indirect_writeb(value, addr); |
446 | #endif | 446 | #endif |
diff --git a/arch/arm/mach-ixp4xx/vulcan-pci.c b/arch/arm/mach-ixp4xx/vulcan-pci.c new file mode 100644 index 000000000000..f3111c6840ef --- /dev/null +++ b/arch/arm/mach-ixp4xx/vulcan-pci.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * arch/arch/mach-ixp4xx/vulcan-pci.c | ||
3 | * | ||
4 | * Vulcan board-level PCI initialization | ||
5 | * | ||
6 | * Copyright (C) 2010 Marc Zyngier <maz@misterjones.org> | ||
7 | * | ||
8 | * based on ixdp425-pci.c: | ||
9 | * Copyright (C) 2002 Intel Corporation. | ||
10 | * Copyright (C) 2003-2004 MontaVista Software, Inc. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/pci.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/irq.h> | ||
21 | #include <asm/mach/pci.h> | ||
22 | #include <asm/mach-types.h> | ||
23 | |||
24 | /* PCI controller GPIO to IRQ pin mappings */ | ||
25 | #define INTA 2 | ||
26 | #define INTB 3 | ||
27 | |||
28 | void __init vulcan_pci_preinit(void) | ||
29 | { | ||
30 | #ifndef CONFIG_IXP4XX_INDIRECT_PCI | ||
31 | /* | ||
32 | * Cardbus bridge wants way more than the SoC can actually offer, | ||
33 | * and leaves the whole PCI bus in a mess. Artificially limit it | ||
34 | * to 8MB per region. Of course indirect mode doesn't have this | ||
35 | * limitation... | ||
36 | */ | ||
37 | pci_cardbus_mem_size = SZ_8M; | ||
38 | pr_info("Vulcan PCI: limiting CardBus memory size to %dMB\n", | ||
39 | (int)(pci_cardbus_mem_size >> 20)); | ||
40 | #endif | ||
41 | set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); | ||
42 | set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); | ||
43 | ixp4xx_pci_preinit(); | ||
44 | } | ||
45 | |||
46 | static int __init vulcan_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
47 | { | ||
48 | if (slot == 1) | ||
49 | return IXP4XX_GPIO_IRQ(INTA); | ||
50 | |||
51 | if (slot == 2) | ||
52 | return IXP4XX_GPIO_IRQ(INTB); | ||
53 | |||
54 | return -1; | ||
55 | } | ||
56 | |||
57 | struct hw_pci vulcan_pci __initdata = { | ||
58 | .nr_controllers = 1, | ||
59 | .preinit = vulcan_pci_preinit, | ||
60 | .swizzle = pci_std_swizzle, | ||
61 | .setup = ixp4xx_setup, | ||
62 | .scan = ixp4xx_scan_bus, | ||
63 | .map_irq = vulcan_map_irq, | ||
64 | }; | ||
65 | |||
66 | int __init vulcan_pci_init(void) | ||
67 | { | ||
68 | if (machine_is_arcom_vulcan()) | ||
69 | pci_common_init(&vulcan_pci); | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | subsys_initcall(vulcan_pci_init); | ||
diff --git a/arch/arm/mach-ixp4xx/vulcan-setup.c b/arch/arm/mach-ixp4xx/vulcan-setup.c new file mode 100644 index 000000000000..465cc5cce687 --- /dev/null +++ b/arch/arm/mach-ixp4xx/vulcan-setup.c | |||
@@ -0,0 +1,246 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-ixp4xx/vulcan-setup.c | ||
3 | * | ||
4 | * Arcom/Eurotech Vulcan board-setup | ||
5 | * | ||
6 | * Copyright (C) 2010 Marc Zyngier <maz@misterjones.org> | ||
7 | * | ||
8 | * based on fsg-setup.c: | ||
9 | * Copyright (C) 2008 Rod Whitby <rod@whitby.id.au> | ||
10 | */ | ||
11 | |||
12 | #include <linux/if_ether.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/serial.h> | ||
15 | #include <linux/serial_8250.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/w1-gpio.h> | ||
18 | #include <linux/mtd/plat-ram.h> | ||
19 | #include <asm/mach-types.h> | ||
20 | #include <asm/mach/arch.h> | ||
21 | #include <asm/mach/flash.h> | ||
22 | |||
23 | static struct flash_platform_data vulcan_flash_data = { | ||
24 | .map_name = "cfi_probe", | ||
25 | .width = 2, | ||
26 | }; | ||
27 | |||
28 | static struct resource vulcan_flash_resource = { | ||
29 | .flags = IORESOURCE_MEM, | ||
30 | }; | ||
31 | |||
32 | static struct platform_device vulcan_flash = { | ||
33 | .name = "IXP4XX-Flash", | ||
34 | .id = 0, | ||
35 | .dev = { | ||
36 | .platform_data = &vulcan_flash_data, | ||
37 | }, | ||
38 | .resource = &vulcan_flash_resource, | ||
39 | .num_resources = 1, | ||
40 | }; | ||
41 | |||
42 | static struct platdata_mtd_ram vulcan_sram_data = { | ||
43 | .mapname = "Vulcan SRAM", | ||
44 | .bankwidth = 1, | ||
45 | }; | ||
46 | |||
47 | static struct resource vulcan_sram_resource = { | ||
48 | .flags = IORESOURCE_MEM, | ||
49 | }; | ||
50 | |||
51 | static struct platform_device vulcan_sram = { | ||
52 | .name = "mtd-ram", | ||
53 | .id = 0, | ||
54 | .dev = { | ||
55 | .platform_data = &vulcan_sram_data, | ||
56 | }, | ||
57 | .resource = &vulcan_sram_resource, | ||
58 | .num_resources = 1, | ||
59 | }; | ||
60 | |||
61 | static struct resource vulcan_uart_resources[] = { | ||
62 | [0] = { | ||
63 | .start = IXP4XX_UART1_BASE_PHYS, | ||
64 | .end = IXP4XX_UART1_BASE_PHYS + 0x0fff, | ||
65 | .flags = IORESOURCE_MEM, | ||
66 | }, | ||
67 | [1] = { | ||
68 | .start = IXP4XX_UART2_BASE_PHYS, | ||
69 | .end = IXP4XX_UART2_BASE_PHYS + 0x0fff, | ||
70 | .flags = IORESOURCE_MEM, | ||
71 | }, | ||
72 | [2] = { | ||
73 | .flags = IORESOURCE_MEM, | ||
74 | }, | ||
75 | }; | ||
76 | |||
77 | static struct plat_serial8250_port vulcan_uart_data[] = { | ||
78 | [0] = { | ||
79 | .mapbase = IXP4XX_UART1_BASE_PHYS, | ||
80 | .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, | ||
81 | .irq = IRQ_IXP4XX_UART1, | ||
82 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | ||
83 | .iotype = UPIO_MEM, | ||
84 | .regshift = 2, | ||
85 | .uartclk = IXP4XX_UART_XTAL, | ||
86 | }, | ||
87 | [1] = { | ||
88 | .mapbase = IXP4XX_UART2_BASE_PHYS, | ||
89 | .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, | ||
90 | .irq = IRQ_IXP4XX_UART2, | ||
91 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | ||
92 | .iotype = UPIO_MEM, | ||
93 | .regshift = 2, | ||
94 | .uartclk = IXP4XX_UART_XTAL, | ||
95 | }, | ||
96 | [2] = { | ||
97 | .irq = IXP4XX_GPIO_IRQ(4), | ||
98 | .irqflags = IRQF_TRIGGER_LOW, | ||
99 | .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | ||
100 | .iotype = UPIO_MEM, | ||
101 | .uartclk = 1843200, | ||
102 | }, | ||
103 | [3] = { | ||
104 | .irq = IXP4XX_GPIO_IRQ(4), | ||
105 | .irqflags = IRQF_TRIGGER_LOW, | ||
106 | .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | ||
107 | .iotype = UPIO_MEM, | ||
108 | .uartclk = 1843200, | ||
109 | }, | ||
110 | { } | ||
111 | }; | ||
112 | |||
113 | static struct platform_device vulcan_uart = { | ||
114 | .name = "serial8250", | ||
115 | .id = PLAT8250_DEV_PLATFORM, | ||
116 | .dev = { | ||
117 | .platform_data = vulcan_uart_data, | ||
118 | }, | ||
119 | .resource = vulcan_uart_resources, | ||
120 | .num_resources = ARRAY_SIZE(vulcan_uart_resources), | ||
121 | }; | ||
122 | |||
123 | static struct eth_plat_info vulcan_plat_eth[] = { | ||
124 | [0] = { | ||
125 | .phy = 0, | ||
126 | .rxq = 3, | ||
127 | .txreadyq = 20, | ||
128 | }, | ||
129 | [1] = { | ||
130 | .phy = 1, | ||
131 | .rxq = 4, | ||
132 | .txreadyq = 21, | ||
133 | }, | ||
134 | }; | ||
135 | |||
136 | static struct platform_device vulcan_eth[] = { | ||
137 | [0] = { | ||
138 | .name = "ixp4xx_eth", | ||
139 | .id = IXP4XX_ETH_NPEB, | ||
140 | .dev = { | ||
141 | .platform_data = &vulcan_plat_eth[0], | ||
142 | }, | ||
143 | }, | ||
144 | [1] = { | ||
145 | .name = "ixp4xx_eth", | ||
146 | .id = IXP4XX_ETH_NPEC, | ||
147 | .dev = { | ||
148 | .platform_data = &vulcan_plat_eth[1], | ||
149 | }, | ||
150 | }, | ||
151 | }; | ||
152 | |||
153 | static struct resource vulcan_max6369_resource = { | ||
154 | .flags = IORESOURCE_MEM, | ||
155 | }; | ||
156 | |||
157 | static struct platform_device vulcan_max6369 = { | ||
158 | .name = "max6369_wdt", | ||
159 | .id = -1, | ||
160 | .resource = &vulcan_max6369_resource, | ||
161 | .num_resources = 1, | ||
162 | }; | ||
163 | |||
164 | static struct w1_gpio_platform_data vulcan_w1_gpio_pdata = { | ||
165 | .pin = 14, | ||
166 | }; | ||
167 | |||
168 | static struct platform_device vulcan_w1_gpio = { | ||
169 | .name = "w1-gpio", | ||
170 | .id = 0, | ||
171 | .dev = { | ||
172 | .platform_data = &vulcan_w1_gpio_pdata, | ||
173 | }, | ||
174 | }; | ||
175 | |||
176 | static struct platform_device *vulcan_devices[] __initdata = { | ||
177 | &vulcan_uart, | ||
178 | &vulcan_flash, | ||
179 | &vulcan_sram, | ||
180 | &vulcan_max6369, | ||
181 | &vulcan_eth[0], | ||
182 | &vulcan_eth[1], | ||
183 | &vulcan_w1_gpio, | ||
184 | }; | ||
185 | |||
186 | static void __init vulcan_init(void) | ||
187 | { | ||
188 | ixp4xx_sys_init(); | ||
189 | |||
190 | /* Flash is spread over both CS0 and CS1 */ | ||
191 | vulcan_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); | ||
192 | vulcan_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1; | ||
193 | *IXP4XX_EXP_CS0 = IXP4XX_EXP_BUS_CS_EN | | ||
194 | IXP4XX_EXP_BUS_STROBE_T(3) | | ||
195 | IXP4XX_EXP_BUS_SIZE(0xF) | | ||
196 | IXP4XX_EXP_BUS_BYTE_RD16 | | ||
197 | IXP4XX_EXP_BUS_WR_EN; | ||
198 | *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0; | ||
199 | |||
200 | /* SRAM on CS2, (256kB, 8bit, writable) */ | ||
201 | vulcan_sram_resource.start = IXP4XX_EXP_BUS_BASE(2); | ||
202 | vulcan_sram_resource.end = IXP4XX_EXP_BUS_BASE(2) + SZ_256K - 1; | ||
203 | *IXP4XX_EXP_CS2 = IXP4XX_EXP_BUS_CS_EN | | ||
204 | IXP4XX_EXP_BUS_STROBE_T(1) | | ||
205 | IXP4XX_EXP_BUS_HOLD_T(2) | | ||
206 | IXP4XX_EXP_BUS_SIZE(9) | | ||
207 | IXP4XX_EXP_BUS_SPLT_EN | | ||
208 | IXP4XX_EXP_BUS_WR_EN | | ||
209 | IXP4XX_EXP_BUS_BYTE_EN; | ||
210 | |||
211 | /* XR16L2551 on CS3 (Moto style, 512 bytes, 8bits, writable) */ | ||
212 | vulcan_uart_resources[2].start = IXP4XX_EXP_BUS_BASE(3); | ||
213 | vulcan_uart_resources[2].end = IXP4XX_EXP_BUS_BASE(3) + 16 - 1; | ||
214 | vulcan_uart_data[2].mapbase = vulcan_uart_resources[2].start; | ||
215 | vulcan_uart_data[3].mapbase = vulcan_uart_data[2].mapbase + 8; | ||
216 | *IXP4XX_EXP_CS3 = IXP4XX_EXP_BUS_CS_EN | | ||
217 | IXP4XX_EXP_BUS_STROBE_T(3) | | ||
218 | IXP4XX_EXP_BUS_CYCLES(IXP4XX_EXP_BUS_CYCLES_MOTOROLA)| | ||
219 | IXP4XX_EXP_BUS_WR_EN | | ||
220 | IXP4XX_EXP_BUS_BYTE_EN; | ||
221 | |||
222 | /* GPIOS on CS4 (512 bytes, 8bits, writable) */ | ||
223 | *IXP4XX_EXP_CS4 = IXP4XX_EXP_BUS_CS_EN | | ||
224 | IXP4XX_EXP_BUS_WR_EN | | ||
225 | IXP4XX_EXP_BUS_BYTE_EN; | ||
226 | |||
227 | /* max6369 on CS5 (512 bytes, 8bits, writable) */ | ||
228 | vulcan_max6369_resource.start = IXP4XX_EXP_BUS_BASE(5); | ||
229 | vulcan_max6369_resource.end = IXP4XX_EXP_BUS_BASE(5); | ||
230 | *IXP4XX_EXP_CS5 = IXP4XX_EXP_BUS_CS_EN | | ||
231 | IXP4XX_EXP_BUS_WR_EN | | ||
232 | IXP4XX_EXP_BUS_BYTE_EN; | ||
233 | |||
234 | platform_add_devices(vulcan_devices, ARRAY_SIZE(vulcan_devices)); | ||
235 | } | ||
236 | |||
237 | MACHINE_START(ARCOM_VULCAN, "Arcom/Eurotech Vulcan") | ||
238 | /* Maintainer: Marc Zyngier <maz@misterjones.org> */ | ||
239 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, | ||
240 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, | ||
241 | .map_io = ixp4xx_map_io, | ||
242 | .init_irq = ixp4xx_init_irq, | ||
243 | .timer = &ixp4xx_timer, | ||
244 | .boot_params = 0x0100, | ||
245 | .init_machine = vulcan_init, | ||
246 | MACHINE_END | ||