8250_gsc.c revision 8e8e8267f0a08c2415d5f51bc9a9fde6d5400619
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Serial Device Initialisation for Lasi/Asp/Wax/Dino 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (c) Copyright Matthew Wilcox <willy@debian.org> 2001-2002 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License as published by 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (at your option) any later version. 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ioport.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/serial_core.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/signal.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/hardware.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/parisc-device.h> 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "8250.h" 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 288b4a483be544569cd61156be86c0becf21a02e8bAlan Coxstatic int __init serial_init_chip(struct parisc_device *dev) 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct uart_port port; 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long address; 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev->irq) { 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* We find some unattached serial ports by walking native 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * busses. These should be silently ignored. Otherwise, 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * what we have here is a missing parent device, so tell 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the user what they're missing. 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 408b4a483be544569cd61156be86c0becf21a02e8bAlan Cox if (parisc_parent(dev)->id.hw_type != HPHW_IOA) 418b4a483be544569cd61156be86c0becf21a02e8bAlan Cox printk(KERN_INFO 428e8e8267f0a08c2415d5f51bc9a9fde6d5400619Alexander Beregalov "Serial: device 0x%llx not configured.\n" 4353f01bba49938f115237fe43a261c31ac13ae5c6Matthew Wilcox "Enable support for Wax, Lasi, Asp or Dino.\n", 448e8e8267f0a08c2415d5f51bc9a9fde6d5400619Alexander Beregalov (unsigned long long)dev->hpa.start); 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4853f01bba49938f115237fe43a261c31ac13ae5c6Matthew Wilcox address = dev->hpa.start; 498b4a483be544569cd61156be86c0becf21a02e8bAlan Cox if (dev->id.sversion != 0x8d) 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds address += 0x800; 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 525076c15862644edb91d2e3436b2fa3e07b28385dHelge Deller memset(&port, 0, sizeof(port)); 535076c15862644edb91d2e3436b2fa3e07b28385dHelge Deller port.iotype = UPIO_MEM; 54136ce40e9f1f24ca1dbf7714c669a7bca56440eaMatthew Wilcox /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */ 55136ce40e9f1f24ca1dbf7714c669a7bca56440eaMatthew Wilcox port.uartclk = 7272727; 565076c15862644edb91d2e3436b2fa3e07b28385dHelge Deller port.mapbase = address; 575076c15862644edb91d2e3436b2fa3e07b28385dHelge Deller port.membase = ioremap_nocache(address, 16); 585076c15862644edb91d2e3436b2fa3e07b28385dHelge Deller port.irq = dev->irq; 595076c15862644edb91d2e3436b2fa3e07b28385dHelge Deller port.flags = UPF_BOOT_AUTOCONF; 605076c15862644edb91d2e3436b2fa3e07b28385dHelge Deller port.dev = &dev->dev; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = serial8250_register_port(&port); 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err < 0) { 648b4a483be544569cd61156be86c0becf21a02e8bAlan Cox printk(KERN_WARNING 658b4a483be544569cd61156be86c0becf21a02e8bAlan Cox "serial8250_register_port returned error %d\n", err); 66d9964d5c9067fe58fecb7ba10b2de4771d2005d9Amol Lad iounmap(port.membase); 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 698b4a483be544569cd61156be86c0becf21a02e8bAlan Cox 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct parisc_device_id serial_tbl[] = { 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 }, 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c }, 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d }, 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0 } 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Hack. Some machines have SERIAL_0 attached to Lasi and SERIAL_1 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * attached to Dino. Unfortunately, Dino appears before Lasi in the device 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * tree. To ensure that ttyS0 == SERIAL_0, we register two drivers; one 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * which only knows about Lasi and then a second which will find all the 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * other serial ports. HPUX ignores this problem. 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct parisc_device_id lasi_tbl[] = { 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */ 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */ 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */ 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03E, 0x0008C }, /* B132L+ */ 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03F, 0x0008C }, /* B180L+ */ 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { HPHW_FIO, HVERSION_REV_ANY_ID, 0x046, 0x0008C }, /* Rocky2 120 */ 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { HPHW_FIO, HVERSION_REV_ANY_ID, 0x047, 0x0008C }, /* Rocky2 150 */ 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { HPHW_FIO, HVERSION_REV_ANY_ID, 0x04E, 0x0008C }, /* Kiji L2 132 */ 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { HPHW_FIO, HVERSION_REV_ANY_ID, 0x056, 0x0008C }, /* Raven+ */ 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0 } 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DEVICE_TABLE(parisc, serial_tbl); 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct parisc_driver lasi_driver = { 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "serial_1", 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .id_table = lasi_tbl, 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .probe = serial_init_chip, 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct parisc_driver serial_driver = { 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "serial", 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .id_table = serial_tbl, 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .probe = serial_init_chip, 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1149f561dfceaafaae73ecfc81b1156dde3056e1ec9Adrian Bunkstatic int __init probe_serial_gsc(void) 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register_parisc_driver(&lasi_driver); 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register_parisc_driver(&serial_driver); 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(probe_serial_gsc); 122920519c1c31ca46ef6caab1a4be102ed0dfb5fbcAdrian Bunk 123920519c1c31ca46ef6caab1a4be102ed0dfb5fbcAdrian BunkMODULE_LICENSE("GPL"); 124