n2100.c (8144B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * arch/arm/mach-iop32x/n2100.c 4 * 5 * Board support code for the Thecus N2100 platform. 6 * 7 * Author: Rory Bolt <rorybolt@pacbell.net> 8 * Copyright (C) 2002 Rory Bolt 9 * Copyright 2003 (c) MontaVista, Software, Inc. 10 * Copyright (C) 2004 Intel Corp. 11 */ 12 13#include <linux/mm.h> 14#include <linux/init.h> 15#include <linux/f75375s.h> 16#include <linux/leds-pca9532.h> 17#include <linux/delay.h> 18#include <linux/kernel.h> 19#include <linux/pci.h> 20#include <linux/pm.h> 21#include <linux/string.h> 22#include <linux/serial_core.h> 23#include <linux/serial_8250.h> 24#include <linux/mtd/physmap.h> 25#include <linux/i2c.h> 26#include <linux/platform_device.h> 27#include <linux/reboot.h> 28#include <linux/io.h> 29#include <linux/gpio.h> 30#include <linux/gpio/machine.h> 31#include <asm/irq.h> 32#include <asm/mach/arch.h> 33#include <asm/mach/map.h> 34#include <asm/mach/pci.h> 35#include <asm/mach/time.h> 36#include <asm/mach-types.h> 37#include <asm/page.h> 38 39#include "hardware.h" 40#include "irqs.h" 41#include "gpio-iop32x.h" 42 43/* 44 * N2100 timer tick configuration. 45 */ 46static void __init n2100_timer_init(void) 47{ 48 /* 33.000 MHz crystal. */ 49 iop_init_time(198000000); 50} 51 52 53/* 54 * N2100 I/O. 55 */ 56static struct map_desc n2100_io_desc[] __initdata = { 57 { /* on-board devices */ 58 .virtual = N2100_UART, 59 .pfn = __phys_to_pfn(N2100_UART), 60 .length = 0x00100000, 61 .type = MT_DEVICE 62 }, 63}; 64 65void __init n2100_map_io(void) 66{ 67 iop3xx_map_io(); 68 iotable_init(n2100_io_desc, ARRAY_SIZE(n2100_io_desc)); 69} 70 71 72/* 73 * N2100 PCI. 74 */ 75static int n2100_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 76{ 77 int irq; 78 79 if (PCI_SLOT(dev->devfn) == 1) { 80 /* RTL8110SB #1 */ 81 irq = IRQ_IOP32X_XINT0; 82 } else if (PCI_SLOT(dev->devfn) == 2) { 83 /* RTL8110SB #2 */ 84 irq = IRQ_IOP32X_XINT3; 85 } else if (PCI_SLOT(dev->devfn) == 3) { 86 /* Sil3512 */ 87 irq = IRQ_IOP32X_XINT2; 88 } else if (PCI_SLOT(dev->devfn) == 4 && pin == 1) { 89 /* VT6212 INTA */ 90 irq = IRQ_IOP32X_XINT1; 91 } else if (PCI_SLOT(dev->devfn) == 4 && pin == 2) { 92 /* VT6212 INTB */ 93 irq = IRQ_IOP32X_XINT0; 94 } else if (PCI_SLOT(dev->devfn) == 4 && pin == 3) { 95 /* VT6212 INTC */ 96 irq = IRQ_IOP32X_XINT2; 97 } else if (PCI_SLOT(dev->devfn) == 5) { 98 /* Mini-PCI slot */ 99 irq = IRQ_IOP32X_XINT3; 100 } else { 101 printk(KERN_ERR "n2100_pci_map_irq() called for unknown " 102 "device PCI:%d:%d:%d\n", dev->bus->number, 103 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); 104 irq = -1; 105 } 106 107 return irq; 108} 109 110static struct hw_pci n2100_pci __initdata = { 111 .nr_controllers = 1, 112 .ops = &iop3xx_ops, 113 .setup = iop3xx_pci_setup, 114 .preinit = iop3xx_pci_preinit, 115 .map_irq = n2100_pci_map_irq, 116}; 117 118/* 119 * Both r8169 chips on the n2100 exhibit PCI parity problems. Turn 120 * off parity reporting for both ports so we don't get error interrupts 121 * for them. 122 */ 123static void n2100_fixup_r8169(struct pci_dev *dev) 124{ 125 if (dev->bus->number == 0 && 126 (dev->devfn == PCI_DEVFN(1, 0) || 127 dev->devfn == PCI_DEVFN(2, 0))) 128 pci_disable_parity(dev); 129} 130DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REALTEK, PCI_ANY_ID, n2100_fixup_r8169); 131 132static int __init n2100_pci_init(void) 133{ 134 if (machine_is_n2100()) 135 pci_common_init(&n2100_pci); 136 137 return 0; 138} 139 140subsys_initcall(n2100_pci_init); 141 142 143/* 144 * N2100 machine initialisation. 145 */ 146static struct physmap_flash_data n2100_flash_data = { 147 .width = 2, 148}; 149 150static struct resource n2100_flash_resource = { 151 .start = 0xf0000000, 152 .end = 0xf0ffffff, 153 .flags = IORESOURCE_MEM, 154}; 155 156static struct platform_device n2100_flash_device = { 157 .name = "physmap-flash", 158 .id = 0, 159 .dev = { 160 .platform_data = &n2100_flash_data, 161 }, 162 .num_resources = 1, 163 .resource = &n2100_flash_resource, 164}; 165 166 167static struct plat_serial8250_port n2100_serial_port[] = { 168 { 169 .mapbase = N2100_UART, 170 .membase = (char *)N2100_UART, 171 .irq = 0, 172 .flags = UPF_SKIP_TEST | UPF_AUTO_IRQ | UPF_SHARE_IRQ, 173 .iotype = UPIO_MEM, 174 .regshift = 0, 175 .uartclk = 1843200, 176 }, 177 { }, 178}; 179 180static struct resource n2100_uart_resource = { 181 .start = N2100_UART, 182 .end = N2100_UART + 7, 183 .flags = IORESOURCE_MEM, 184}; 185 186static struct platform_device n2100_serial_device = { 187 .name = "serial8250", 188 .id = PLAT8250_DEV_PLATFORM, 189 .dev = { 190 .platform_data = n2100_serial_port, 191 }, 192 .num_resources = 1, 193 .resource = &n2100_uart_resource, 194}; 195 196static struct f75375s_platform_data n2100_f75375s = { 197 .pwm = { 255, 255 }, 198 .pwm_enable = { 0, 0 }, 199}; 200 201static struct pca9532_platform_data n2100_leds = { 202 .leds = { 203 { .name = "n2100:red:satafail0", 204 .state = PCA9532_OFF, 205 .type = PCA9532_TYPE_LED, 206 }, 207 { .name = "n2100:red:satafail1", 208 .state = PCA9532_OFF, 209 .type = PCA9532_TYPE_LED, 210 }, 211 { .name = "n2100:blue:usb", 212 .state = PCA9532_OFF, 213 .type = PCA9532_TYPE_LED, 214 }, 215 { .type = PCA9532_TYPE_NONE }, 216 217 { .type = PCA9532_TYPE_NONE }, 218 { .type = PCA9532_TYPE_NONE }, 219 { .type = PCA9532_TYPE_NONE }, 220 { .name = "n2100:red:usb", 221 .state = PCA9532_OFF, 222 .type = PCA9532_TYPE_LED, 223 }, 224 225 { .type = PCA9532_TYPE_NONE }, /* power OFF gpio */ 226 { .type = PCA9532_TYPE_NONE }, /* reset gpio */ 227 { .type = PCA9532_TYPE_NONE }, 228 { .type = PCA9532_TYPE_NONE }, 229 230 { .type = PCA9532_TYPE_NONE }, 231 { .name = "n2100:orange:system", 232 .state = PCA9532_OFF, 233 .type = PCA9532_TYPE_LED, 234 }, 235 { .name = "n2100:red:system", 236 .state = PCA9532_OFF, 237 .type = PCA9532_TYPE_LED, 238 }, 239 { .name = "N2100 beeper" , 240 .state = PCA9532_OFF, 241 .type = PCA9532_TYPE_N2100_BEEP, 242 }, 243 }, 244 .psc = { 0, 0 }, 245 .pwm = { 0, 0 }, 246}; 247 248static struct i2c_board_info __initdata n2100_i2c_devices[] = { 249 { 250 I2C_BOARD_INFO("rs5c372b", 0x32), 251 }, 252 { 253 I2C_BOARD_INFO("f75375", 0x2e), 254 .platform_data = &n2100_f75375s, 255 }, 256 { 257 I2C_BOARD_INFO("pca9532", 0x60), 258 .platform_data = &n2100_leds, 259 }, 260}; 261 262/* 263 * Pull PCA9532 GPIO #8 low to power off the machine. 264 */ 265static void n2100_power_off(void) 266{ 267 local_irq_disable(); 268 269 /* Start condition, I2C address of PCA9532, write transaction. */ 270 *IOP3XX_IDBR0 = 0xc0; 271 *IOP3XX_ICR0 = 0xe9; 272 mdelay(1); 273 274 /* Write address 0x08. */ 275 *IOP3XX_IDBR0 = 0x08; 276 *IOP3XX_ICR0 = 0xe8; 277 mdelay(1); 278 279 /* Write data 0x01, stop condition. */ 280 *IOP3XX_IDBR0 = 0x01; 281 *IOP3XX_ICR0 = 0xea; 282 283 while (1) 284 ; 285} 286 287static void n2100_restart(enum reboot_mode mode, const char *cmd) 288{ 289 int ret; 290 291 ret = gpio_direction_output(N2100_HARDWARE_RESET, 0); 292 if (ret) { 293 pr_crit("could not drive reset GPIO low\n"); 294 return; 295 } 296 /* Wait for reset to happen */ 297 while (1) 298 ; 299} 300 301 302static struct timer_list power_button_poll_timer; 303 304static void power_button_poll(struct timer_list *unused) 305{ 306 if (gpio_get_value(N2100_POWER_BUTTON) == 0) { 307 ctrl_alt_del(); 308 return; 309 } 310 311 power_button_poll_timer.expires = jiffies + (HZ / 10); 312 add_timer(&power_button_poll_timer); 313} 314 315static int __init n2100_request_gpios(void) 316{ 317 int ret; 318 319 if (!machine_is_n2100()) 320 return 0; 321 322 ret = gpio_request(N2100_HARDWARE_RESET, "reset"); 323 if (ret) 324 pr_err("could not request reset GPIO\n"); 325 326 ret = gpio_request(N2100_POWER_BUTTON, "power"); 327 if (ret) 328 pr_err("could not request power GPIO\n"); 329 else { 330 ret = gpio_direction_input(N2100_POWER_BUTTON); 331 if (ret) 332 pr_err("could not set power GPIO as input\n"); 333 } 334 /* Set up power button poll timer */ 335 timer_setup(&power_button_poll_timer, power_button_poll, 0); 336 power_button_poll_timer.expires = jiffies + (HZ / 10); 337 add_timer(&power_button_poll_timer); 338 return 0; 339} 340device_initcall(n2100_request_gpios); 341 342static void __init n2100_init_machine(void) 343{ 344 register_iop32x_gpio(); 345 gpiod_add_lookup_table(&iop3xx_i2c0_gpio_lookup); 346 platform_device_register(&iop3xx_i2c0_device); 347 platform_device_register(&n2100_flash_device); 348 platform_device_register(&n2100_serial_device); 349 platform_device_register(&iop3xx_dma_0_channel); 350 platform_device_register(&iop3xx_dma_1_channel); 351 352 i2c_register_board_info(0, n2100_i2c_devices, 353 ARRAY_SIZE(n2100_i2c_devices)); 354 355 pm_power_off = n2100_power_off; 356} 357 358MACHINE_START(N2100, "Thecus N2100") 359 /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ 360 .atag_offset = 0x100, 361 .nr_irqs = IOP32X_NR_IRQS, 362 .map_io = n2100_map_io, 363 .init_irq = iop32x_init_irq, 364 .init_time = n2100_timer_init, 365 .init_machine = n2100_init_machine, 366 .restart = n2100_restart, 367MACHINE_END