From 0fec53a24a5e5f7ba68d891b68f568b6aeafaca6 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 8 Jan 2006 22:37:46 +0000 Subject: [ARM] Remove EPXA10DB machine support EPXA10DB seems to be uncared for: - the "PLD" code has never been merged - no one has reported that this platform has been broken since at least 2.6.10 - interest seems to have dried up around March 2003. Therefore, remove EPXA10DB support. Signed-off-by: Russell King --- drivers/mtd/maps/Kconfig | 8 - drivers/mtd/maps/Makefile | 1 - drivers/mtd/maps/epxa10db-flash.c | 179 ------- drivers/net/arm/Kconfig | 13 - drivers/net/arm/Makefile | 1 - drivers/net/arm/ether00.c | 1017 ------------------------------------- drivers/serial/Kconfig | 23 - drivers/serial/Makefile | 1 - drivers/serial/uart00.c | 782 ---------------------------- 9 files changed, 2025 deletions(-) delete mode 100644 drivers/mtd/maps/epxa10db-flash.c delete mode 100644 drivers/net/arm/ether00.c delete mode 100644 drivers/serial/uart00.c (limited to 'drivers') diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index b9b77cf39a1..7abd7fee0dd 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -473,14 +473,6 @@ config MTD_IXP2000 IXDP425 and Coyote. If you have an IXP2000 based board and would like to use the flash chips on it, say 'Y'. -config MTD_EPXA10DB - tristate "CFI Flash device mapped on Epxa10db" - depends on MTD_CFI && MTD_PARTITIONS && ARCH_CAMELOT - help - This enables support for the flash devices on the Altera - Excalibur XA10 Development Board. If you are building a kernel - for on of these boards then you should say 'Y' otherwise say 'N'. - config MTD_FORTUNET tristate "CFI Flash device mapped on the FortuNet board" depends on MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 2f7e254912f..ab71f172eb7 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -15,7 +15,6 @@ obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o obj-$(CONFIG_MTD_CSTM_MIPS_IXX) += cstm_mips_ixx.o obj-$(CONFIG_MTD_DC21285) += dc21285.o obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o -obj-$(CONFIG_MTD_EPXA10DB) += epxa10db-flash.o obj-$(CONFIG_MTD_IQ80310) += iq80310.o obj-$(CONFIG_MTD_L440GX) += l440gx.o obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o diff --git a/drivers/mtd/maps/epxa10db-flash.c b/drivers/mtd/maps/epxa10db-flash.c deleted file mode 100644 index 265b079fe93..00000000000 --- a/drivers/mtd/maps/epxa10db-flash.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Flash memory access on EPXA based devices - * - * (C) 2000 Nicolas Pitre - * Copyright (C) 2001 Altera Corporation - * Copyright (C) 2001 Red Hat, Inc. - * - * $Id: epxa10db-flash.c,v 1.15 2005/11/07 11:14:27 gleixner Exp $ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#ifdef CONFIG_EPXA10DB -#define BOARD_NAME "EPXA10DB" -#else -#define BOARD_NAME "EPXA1DB" -#endif - -static int nr_parts = 0; -static struct mtd_partition *parts; - -static struct mtd_info *mymtd; - -static int epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts); - - -static struct map_info epxa_map = { - .name = "EPXA flash", - .size = FLASH_SIZE, - .bankwidth = 2, - .phys = FLASH_START, -}; - -static const char *probes[] = { "RedBoot", "afs", NULL }; - -static int __init epxa_mtd_init(void) -{ - int i; - - printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START); - - epxa_map.virt = ioremap(FLASH_START, FLASH_SIZE); - if (!epxa_map.virt) { - printk("Failed to ioremap %s flash\n",BOARD_NAME); - return -EIO; - } - simple_map_init(&epxa_map); - - mymtd = do_map_probe("cfi_probe", &epxa_map); - if (!mymtd) { - iounmap((void *)epxa_map.virt); - return -ENXIO; - } - - mymtd->owner = THIS_MODULE; - - /* Unlock the flash device. */ - if(mymtd->unlock){ - for (i=0; inumeraseregions;i++){ - int j; - for(j=0;jeraseregions[i].numblocks;j++){ - mymtd->unlock(mymtd,mymtd->eraseregions[i].offset + j * mymtd->eraseregions[i].erasesize,mymtd->eraseregions[i].erasesize); - } - } - } - -#ifdef CONFIG_MTD_PARTITIONS - nr_parts = parse_mtd_partitions(mymtd, probes, &parts, 0); - - if (nr_parts > 0) { - add_mtd_partitions(mymtd, parts, nr_parts); - return 0; - } -#endif - /* No recognised partitioning schemes found - use defaults */ - nr_parts = epxa_default_partitions(mymtd, &parts); - if (nr_parts > 0) { - add_mtd_partitions(mymtd, parts, nr_parts); - return 0; - } - - /* If all else fails... */ - add_mtd_device(mymtd); - return 0; -} - -static void __exit epxa_mtd_cleanup(void) -{ - if (mymtd) { - if (nr_parts) - del_mtd_partitions(mymtd); - else - del_mtd_device(mymtd); - map_destroy(mymtd); - } - if (epxa_map.virt) { - iounmap((void *)epxa_map.virt); - epxa_map.virt = 0; - } -} - - -/* - * This will do for now, once we decide which bootldr we're finally - * going to use then we'll remove this function and do it properly - * - * Partions are currently (as offsets from base of flash): - * 0x00000000 - 0x003FFFFF - bootloader (!) - * 0x00400000 - 0x00FFFFFF - Flashdisk - */ - -static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts) -{ - struct mtd_partition *parts; - int ret, i; - int npartitions = 0; - char *names; - const char *name = "jffs"; - - printk("Using default partitions for %s\n",BOARD_NAME); - npartitions=1; - parts = kmalloc(npartitions*sizeof(*parts)+strlen(name), GFP_KERNEL); - memzero(parts,npartitions*sizeof(*parts)+strlen(name)); - if (!parts) { - ret = -ENOMEM; - goto out; - } - i=0; - names = (char *)&parts[npartitions]; - parts[i].name = names; - names += strlen(name) + 1; - strcpy(parts[i].name, name); - -#ifdef CONFIG_EPXA10DB - parts[i].size = FLASH_SIZE-0x00400000; - parts[i].offset = 0x00400000; -#else - parts[i].size = FLASH_SIZE-0x00180000; - parts[i].offset = 0x00180000; -#endif - - out: - *pparts = parts; - return npartitions; -} - - -module_init(epxa_mtd_init); -module_exit(epxa_mtd_cleanup); - -MODULE_AUTHOR("Clive Davies"); -MODULE_DESCRIPTION("Altera epxa mtd flash map"); -MODULE_LICENSE("GPL"); diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig index 470364deded..625184b65e3 100644 --- a/drivers/net/arm/Kconfig +++ b/drivers/net/arm/Kconfig @@ -31,16 +31,3 @@ config ARM_ETHERH help If you have an Acorn system with one of these network cards, you should say Y to this option if you wish to use it with Linux. - -config ARM_ETHER00 - tristate "Altera Ether00 support" - depends on NET_ETHERNET && ARM && ARCH_CAMELOT - help - This is the driver for Altera's ether00 ethernet mac IP core. Say - Y here if you want to build support for this into the kernel. It - is also available as a module (say M here) that can be inserted/ - removed from the kernel at the same time as the PLD is configured. - If this driver is running on an epxa10 development board then it - will generate a suitable hw address based on the board serial - number (MTD support is required for this). Otherwise you will - need to set a suitable hw address using ifconfig. diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile index b0d706834d8..bc263edf06a 100644 --- a/drivers/net/arm/Makefile +++ b/drivers/net/arm/Makefile @@ -4,7 +4,6 @@ # obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o -obj-$(CONFIG_ARM_ETHER00) += ether00.o obj-$(CONFIG_ARM_ETHERH) += etherh.o obj-$(CONFIG_ARM_ETHER3) += ether3.o obj-$(CONFIG_ARM_ETHER1) += ether1.o diff --git a/drivers/net/arm/ether00.c b/drivers/net/arm/ether00.c deleted file mode 100644 index 4f1f4e31bda..00000000000 --- a/drivers/net/arm/ether00.c +++ /dev/null @@ -1,1017 +0,0 @@ -/* - * drivers/net/ether00.c - * - * Copyright (C) 2001 Altera Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -MODULE_AUTHOR("Clive Davies"); -MODULE_DESCRIPTION("Altera Ether00 IP core driver"); -MODULE_LICENSE("GPL"); - -#define PKT_BUF_SZ 1540 /* Size of each rx buffer */ -#define ETH_NR 4 /* Number of MACs this driver supports */ - -#define DEBUG(x) - -#define __dma_va(x) (unsigned int)((unsigned int)priv->dma_data+(((unsigned int)(x))&(EXC_SPSRAM_BLOCK0_SIZE-1))) -#define __dma_pa(x) (unsigned int)(EXC_SPSRAM_BLOCK0_BASE+(((unsigned int)(x))-(unsigned int)priv->dma_data)) - -#define ETHER00_BASE 0 -#define ETHER00_TYPE -#define ETHER00_NAME "ether00" -#define MAC_REG_SIZE 0x400 /* size of MAC register area */ - - - -/* typedefs */ - -/* The definition of the driver control structure */ - -#define RX_NUM_BUFF 10 -#define RX_NUM_FDESC 10 -#define TX_NUM_FDESC 10 - -struct tx_fda_ent{ - FDA_DESC fd; - BUF_DESC bd; - BUF_DESC pad; -}; -struct rx_fda_ent{ - FDA_DESC fd; - BUF_DESC bd; - BUF_DESC pad; -}; -struct rx_blist_ent{ - FDA_DESC fd; - BUF_DESC bd; - BUF_DESC pad; -}; -struct net_priv -{ - struct net_device_stats stats; - struct sk_buff* skb; - void* dma_data; - struct rx_blist_ent* rx_blist_vp; - struct rx_fda_ent* rx_fda_ptr; - struct tx_fda_ent* tx_fdalist_vp; - struct tq_struct tq_memupdate; - unsigned char memupdate_scheduled; - unsigned char rx_disabled; - unsigned char queue_stopped; - spinlock_t rx_lock; -}; - -static const char vendor_id[2]={0x07,0xed}; - -#ifdef ETHER00_DEBUG - -/* Dump (most) registers for debugging puposes */ - -static void dump_regs(struct net_device *dev){ - struct net_priv* priv=dev->priv; - unsigned int* i; - - printk("\n RX free descriptor area:\n"); - - for(i=(unsigned int*)priv->rx_fda_ptr; - i<((unsigned int*)(priv->rx_fda_ptr+RX_NUM_FDESC));){ - printk("%#8x %#8x %#8x %#8x\n",*i,*(i+1),*(i+2),*(i+3)); - i+=4; - } - - printk("\n RX buffer list:\n"); - - for(i=(unsigned int*)priv->rx_blist_vp; - i<((unsigned int*)(priv->rx_blist_vp+RX_NUM_BUFF));){ - printk("%#8x %#8x %#8x %#8x\n",*i,*(i+1),*(i+2),*(i+3)); - i+=4; - } - - printk("\n TX frame descriptor list:\n"); - - for(i=(unsigned int*)priv->tx_fdalist_vp; - i<((unsigned int*)(priv->tx_fdalist_vp+TX_NUM_FDESC));){ - printk("%#8x %#8x %#8x %#8x\n",*i,*(i+1),*(i+2),*(i+3)); - i+=4; - } - - printk("\ndma ctl=%#x\n",readw(ETHER_DMA_CTL(dev->base_addr))); - printk("txfrmptr=%#x\n",readw(ETHER_TXFRMPTR(dev->base_addr))); - printk("txthrsh=%#x\n",readw(ETHER_TXTHRSH(dev->base_addr))); - printk("txpollctr=%#x\n",readw(ETHER_TXPOLLCTR(dev->base_addr))); - printk("blfrmptr=%#x\n",readw(ETHER_BLFRMPTR(dev->base_addr))); - printk("rxfragsize=%#x\n",readw(ETHER_RXFRAGSIZE(dev->base_addr))); - printk("tx_int_en=%#x\n",readw(ETHER_INT_EN(dev->base_addr))); - printk("fda_bas=%#x\n",readw(ETHER_FDA_BAS(dev->base_addr))); - printk("fda_lim=%#x\n",readw(ETHER_FDA_LIM(dev->base_addr))); - printk("int_src=%#x\n",readw(ETHER_INT_SRC(dev->base_addr))); - printk("pausecnt=%#x\n",readw(ETHER_PAUSECNT(dev->base_addr))); - printk("rempaucnt=%#x\n",readw(ETHER_REMPAUCNT(dev->base_addr))); - printk("txconfrmstat=%#x\n",readw(ETHER_TXCONFRMSTAT(dev->base_addr))); - printk("mac_ctl=%#x\n",readw(ETHER_MAC_CTL(dev->base_addr))); - printk("arc_ctl=%#x\n",readw(ETHER_ARC_CTL(dev->base_addr))); - printk("tx_ctl=%#x\n",readw(ETHER_TX_CTL(dev->base_addr))); -} -#endif /* ETHER00_DEBUG */ - - -static int ether00_write_phy(struct net_device *dev, short address, short value) -{ - volatile int count = 1024; - writew(value,ETHER_MD_DATA(dev->base_addr)); - writew( ETHER_MD_CA_BUSY_MSK | - ETHER_MD_CA_WR_MSK | - (address & ETHER_MD_CA_ADDR_MSK), - ETHER_MD_CA(dev->base_addr)); - - /* Wait for the command to complete */ - while((readw(ETHER_MD_CA(dev->base_addr)) & ETHER_MD_CA_BUSY_MSK)&&count){ - count--; - } - if (!count){ - printk("Write to phy failed, addr=%#x, data=%#x\n",address, value); - return -EIO; - } - return 0; -} - -static int ether00_read_phy(struct net_device *dev, short address) -{ - volatile int count = 1024; - writew( ETHER_MD_CA_BUSY_MSK | - (address & ETHER_MD_CA_ADDR_MSK), - ETHER_MD_CA(dev->base_addr)); - - /* Wait for the command to complete */ - while((readw(ETHER_MD_CA(dev->base_addr)) & ETHER_MD_CA_BUSY_MSK)&&count){ - count--; - } - if (!count){ - printk(KERN_WARNING "Read from phy timed out\n"); - return -EIO; - } - return readw(ETHER_MD_DATA(dev->base_addr)); -} - -static void ether00_phy_int(int irq_num, void* dev_id, struct pt_regs* regs) -{ - struct net_device* dev=dev_id; - int irq_status; - - irq_status=ether00_read_phy(dev, PHY_IRQ_CONTROL); - - if(irq_status & PHY_IRQ_CONTROL_ANEG_COMP_INT_MSK){ - /* - * Autonegotiation complete on epxa10db. The mac doesn't - * twig if we're in full duplex so we need to check the - * phy status register and configure the mac accordingly - */ - if(ether00_read_phy(dev, PHY_STATUS)&(PHY_STATUS_10T_F_MSK|PHY_STATUS_100_X_F_MSK)){ - int tmp; - tmp=readl(ETHER_MAC_CTL(dev->base_addr)); - writel(tmp|ETHER_MAC_CTL_FULLDUP_MSK,ETHER_MAC_CTL(dev->base_addr)); - } - } - - if(irq_status&PHY_IRQ_CONTROL_LS_CHG_INT_MSK){ - - if(ether00_read_phy(dev, PHY_STATUS)& PHY_STATUS_LINK_MSK){ - /* Link is up */ - netif_carrier_on(dev); - //printk("Carrier on\n"); - }else{ - netif_carrier_off(dev); - //printk("Carrier off\n"); - - } - } - -} - -static void setup_blist_entry(struct sk_buff* skb,struct rx_blist_ent* blist_ent_ptr){ - /* Make the buffer consistent with the cache as the mac is going to write - * directly into it*/ - blist_ent_ptr->fd.FDSystem=(unsigned int)skb; - blist_ent_ptr->bd.BuffData=(char*)__pa(skb->data); - consistent_sync(skb->data,PKT_BUF_SZ,PCI_DMA_FROMDEVICE); - /* align IP on 16 Byte (DMA_CTL set to skip 2 bytes) */ - skb_reserve(skb,2); - blist_ent_ptr->bd.BuffLength=PKT_BUF_SZ-2; - blist_ent_ptr->fd.FDLength=1; - blist_ent_ptr->fd.FDCtl=FDCTL_COWNSFD_MSK; - blist_ent_ptr->bd.BDCtl=BDCTL_COWNSBD_MSK; -} - - -static int ether00_mem_init(struct net_device* dev) -{ - struct net_priv* priv=dev->priv; - struct tx_fda_ent *tx_fd_ptr,*tx_end_ptr; - struct rx_blist_ent* blist_ent_ptr; - int i; - - /* - * Grab a block of on chip SRAM to contain the control stuctures for - * the ethernet MAC. This uncached becuase it needs to be accesses by both - * bus masters (cpu + mac). However, it shouldn't matter too much in terms - * of speed as its on chip memory - */ - priv->dma_data=ioremap_nocache(EXC_SPSRAM_BLOCK0_BASE,EXC_SPSRAM_BLOCK0_SIZE ); - if (!priv->dma_data) - return -ENOMEM; - - priv->rx_fda_ptr=(struct rx_fda_ent*)priv->dma_data; - /* - * Now share it out amongst the Frame descriptors and the buffer list - */ - priv->rx_blist_vp=(struct rx_blist_ent*)((unsigned int)priv->dma_data+RX_NUM_FDESC*sizeof(struct rx_fda_ent)); - - /* - *Initalise the FDA list - */ - /* set ownership to the controller */ - memset(priv->rx_fda_ptr,0x80,RX_NUM_FDESC*sizeof(struct rx_fda_ent)); - - /* - *Initialise the buffer list - */ - blist_ent_ptr=priv->rx_blist_vp; - i=0; - while(blist_ent_ptr<(priv->rx_blist_vp+RX_NUM_BUFF)){ - struct sk_buff *skb; - blist_ent_ptr->fd.FDLength=1; - skb=dev_alloc_skb(PKT_BUF_SZ); - if(skb){ - setup_blist_entry(skb,blist_ent_ptr); - blist_ent_ptr->fd.FDNext=(FDA_DESC*)__dma_pa(blist_ent_ptr+1); - blist_ent_ptr->bd.BDStat=i++; - blist_ent_ptr++; - } - else - { - printk("Failed to initalise buffer list\n"); - } - - } - blist_ent_ptr--; - blist_ent_ptr->fd.FDNext=(FDA_DESC*)__dma_pa(priv->rx_blist_vp); - - priv->tx_fdalist_vp=(struct tx_fda_ent*)(priv->rx_blist_vp+RX_NUM_BUFF); - - /* Initialise the buffers to be a circular list. The mac will then go poll - * the list until it finds a frame ready to transmit */ - tx_end_ptr=priv->tx_fdalist_vp+TX_NUM_FDESC; - for(tx_fd_ptr=priv->tx_fdalist_vp;tx_fd_ptrfd.FDNext=(FDA_DESC*)__dma_pa((tx_fd_ptr+1)); - tx_fd_ptr->fd.FDCtl=1; - tx_fd_ptr->fd.FDStat=0; - tx_fd_ptr->fd.FDLength=1; - - } - /* Change the last FDNext pointer to make a circular list */ - tx_fd_ptr--; - tx_fd_ptr->fd.FDNext=(FDA_DESC*)__dma_pa(priv->tx_fdalist_vp); - - /* Point the device at the chain of Rx and Tx Buffers */ - writel((unsigned int)__dma_pa(priv->rx_fda_ptr),ETHER_FDA_BAS(dev->base_addr)); - writel((RX_NUM_FDESC-1)*sizeof(struct rx_fda_ent),ETHER_FDA_LIM(dev->base_addr)); - writel((unsigned int)__dma_pa(priv->rx_blist_vp),ETHER_BLFRMPTR(dev->base_addr)); - - writel((unsigned int)__dma_pa(priv->tx_fdalist_vp),ETHER_TXFRMPTR(dev->base_addr)); - - return 0; -} - - -void ether00_mem_update(void* dev_id) -{ - struct net_device* dev=dev_id; - struct net_priv* priv=dev->priv; - struct sk_buff* skb; - struct tx_fda_ent *fda_ptr=priv->tx_fdalist_vp; - struct rx_blist_ent* blist_ent_ptr; - unsigned long flags; - - priv->tq_memupdate.sync=0; - //priv->tq_memupdate.list= - priv->memupdate_scheduled=0; - - /* Transmit interrupt */ - while(fda_ptr<(priv->tx_fdalist_vp+TX_NUM_FDESC)){ - if(!(FDCTL_COWNSFD_MSK&fda_ptr->fd.FDCtl) && (ETHER_TX_STAT_COMP_MSK&fda_ptr->fd.FDStat)){ - priv->stats.tx_packets++; - priv->stats.tx_bytes+=fda_ptr->bd.BuffLength; - skb=(struct sk_buff*)fda_ptr->fd.FDSystem; - //printk("%d:txcln:fda=%#x skb=%#x\n",jiffies,fda_ptr,skb); - dev_kfree_skb(skb); - fda_ptr->fd.FDSystem=0; - fda_ptr->fd.FDStat=0; - fda_ptr->fd.FDCtl=0; - } - fda_ptr++; - } - /* Fill in any missing buffers from the received queue */ - spin_lock_irqsave(&priv->rx_lock,flags); - blist_ent_ptr=priv->rx_blist_vp; - while(blist_ent_ptr<(priv->rx_blist_vp+RX_NUM_BUFF)){ - /* fd.FDSystem of 0 indicates we failed to allocate the buffer in the ISR */ - if(!blist_ent_ptr->fd.FDSystem){ - struct sk_buff *skb; - skb=dev_alloc_skb(PKT_BUF_SZ); - blist_ent_ptr->fd.FDSystem=(unsigned int)skb; - if(skb){ - setup_blist_entry(skb,blist_ent_ptr); - } - else - { - break; - } - } - blist_ent_ptr++; - } - spin_unlock_irqrestore(&priv->rx_lock,flags); - if(priv->queue_stopped){ - //printk("%d:cln:start q\n",jiffies); - netif_start_queue(dev); - } - if(priv->rx_disabled){ - //printk("%d:enable_irq\n",jiffies); - priv->rx_disabled=0; - writel(ETHER_RX_CTL_RXEN_MSK,ETHER_RX_CTL(dev->base_addr)); - - } -} - - -static void ether00_int( int irq_num, void* dev_id, struct pt_regs* regs) -{ - struct net_device* dev=dev_id; - struct net_priv* priv=dev->priv; - - unsigned int interruptValue; - - interruptValue=readl(ETHER_INT_SRC(dev->base_addr)); - - //printk("INT_SRC=%x\n",interruptValue); - - if(!(readl(ETHER_INT_SRC(dev->base_addr)) & ETHER_INT_SRC_IRQ_MSK)) - { - return; /* Interrupt wasn't caused by us!! */ - } - - if(readl(ETHER_INT_SRC(dev->base_addr))& - (ETHER_INT_SRC_INTMACRX_MSK | - ETHER_INT_SRC_FDAEX_MSK | - ETHER_INT_SRC_BLEX_MSK)) { - struct rx_blist_ent* blist_ent_ptr; - struct rx_fda_ent* fda_ent_ptr; - struct sk_buff* skb; - - fda_ent_ptr=priv->rx_fda_ptr; - spin_lock(&priv->rx_lock); - while(fda_ent_ptr<(priv->rx_fda_ptr+RX_NUM_FDESC)){ - int result; - - if(!(fda_ent_ptr->fd.FDCtl&FDCTL_COWNSFD_MSK)) - { - /* This frame is ready for processing */ - /*find the corresponding buffer in the bufferlist */ - blist_ent_ptr=priv->rx_blist_vp+fda_ent_ptr->bd.BDStat; - skb=(struct sk_buff*)blist_ent_ptr->fd.FDSystem; - - /* Pass this skb up the stack */ - skb->dev=dev; - skb_put(skb,fda_ent_ptr->fd.FDLength); - skb->protocol=eth_type_trans(skb,dev); - skb->ip_summed=CHECKSUM_UNNECESSARY; - result=netif_rx(skb); - /* Update statistics */ - priv->stats.rx_packets++; - priv->stats.rx_bytes+=fda_ent_ptr->fd.FDLength; - - /* Free the FDA entry */ - fda_ent_ptr->bd.BDStat=0xff; - fda_ent_ptr->fd.FDCtl=FDCTL_COWNSFD_MSK; - - /* Allocate a new skb and point the bd entry to it */ - blist_ent_ptr->fd.FDSystem=0; - skb=dev_alloc_skb(PKT_BUF_SZ); - //printk("allocskb=%#x\n",skb); - if(skb){ - setup_blist_entry(skb,blist_ent_ptr); - - } - else if(!priv->memupdate_scheduled){ - int tmp; - /* There are no buffers at the moment, so schedule */ - /* the background task to sort this out */ - schedule_task(&priv->tq_memupdate); - priv->memupdate_scheduled=1; - printk(KERN_DEBUG "%s:No buffers",dev->name); - /* If this interrupt was due to a lack of buffers then - * we'd better stop the receiver too */ - if(interruptValueÐER_INT_SRC_BLEX_MSK){ - priv->rx_disabled=1; - tmp=readl(ETHER_INT_SRC(dev->base_addr)); - writel(tmp&~ETHER_RX_CTL_RXEN_MSK,ETHER_RX_CTL(dev->base_addr)); - printk(KERN_DEBUG "%s:Halting rx",dev->name); - } - - } - - } - fda_ent_ptr++; - } - spin_unlock(&priv->rx_lock); - - /* Clear the interrupts */ - writel(ETHER_INT_SRC_INTMACRX_MSK | ETHER_INT_SRC_FDAEX_MSK - | ETHER_INT_SRC_BLEX_MSK,ETHER_INT_SRC(dev->base_addr)); - - } - - if(readl(ETHER_INT_SRC(dev->base_addr))ÐER_INT_SRC_INTMACTX_MSK){ - - if(!priv->memupdate_scheduled){ - schedule_task(&priv->tq_memupdate); - priv->memupdate_scheduled=1; - } - /* Clear the interrupt */ - writel(ETHER_INT_SRC_INTMACTX_MSK,ETHER_INT_SRC(dev->base_addr)); - } - - if (readl(ETHER_INT_SRC(dev->base_addr)) & (ETHER_INT_SRC_SWINT_MSK| - ETHER_INT_SRC_INTEARNOT_MSK| - ETHER_INT_SRC_INTLINK_MSK| - ETHER_INT_SRC_INTEXBD_MSK| - ETHER_INT_SRC_INTTXCTLCMP_MSK)) - { - /* - * Not using any of these so they shouldn't happen - * - * In the cased of INTEXBD - if you allocate more - * than 28 decsriptors you may need to think about this - */ - printk("Not using this interrupt\n"); - } - - if (readl(ETHER_INT_SRC(dev->base_addr)) & - (ETHER_INT_SRC_INTSBUS_MSK | - ETHER_INT_SRC_INTNRABT_MSK - |ETHER_INT_SRC_DMPARERR_MSK)) - { - /* - * Hardware errors, we can either ignore them and hope they go away - *or reset the device, I'll try the first for now to see if they happen - */ - printk("Hardware error\n"); - } -} - -static void ether00_setup_ethernet_address(struct net_device* dev) -{ - int tmp; - - dev->addr_len=6; - writew(0,ETHER_ARC_ADR(dev->base_addr)); - writel((dev->dev_addr[0]<<24) | - (dev->dev_addr[1]<<16) | - (dev->dev_addr[2]<<8) | - dev->dev_addr[3], - ETHER_ARC_DATA(dev->base_addr)); - - writew(4,ETHER_ARC_ADR(dev->base_addr)); - tmp=readl(ETHER_ARC_DATA(dev->base_addr)); - tmp&=0xffff; - tmp|=(dev->dev_addr[4]<<24) | (dev->dev_addr[5]<<16); - writel(tmp, ETHER_ARC_DATA(dev->base_addr)); - /* Enable this entry in the ARC */ - - writel(1,ETHER_ARC_ENA(dev->base_addr)); - - return; -} - - -static void ether00_reset(struct net_device *dev) -{ - /* reset the controller */ - writew(ETHER_MAC_CTL_RESET_MSK,ETHER_MAC_CTL(dev->base_addr)); - - /* - * Make sure we're not going to send anything - */ - - writew(ETHER_TX_CTL_TXHALT_MSK,ETHER_TX_CTL(dev->base_addr)); - - /* - * Make sure we're not going to receive anything - */ - writew(ETHER_RX_CTL_RXHALT_MSK,ETHER_RX_CTL(dev->base_addr)); - - /* - * Disable Interrupts for now, and set the burst size to 8 bytes - */ - - writel(ETHER_DMA_CTL_INTMASK_MSK | - ((8 << ETHER_DMA_CTL_DMBURST_OFST) & ETHER_DMA_CTL_DMBURST_MSK) - |(2<base_addr)); - - - /* - * Set TxThrsh - start transmitting a packet after 1514 - * bytes or when a packet is complete, whichever comes first - */ - writew(1514,ETHER_TXTHRSH(dev->base_addr)); - - /* - * Set TxPollCtr. Each cycle is - * 61.44 microseconds with a 33 MHz bus - */ - writew(1,ETHER_TXPOLLCTR(dev->base_addr)); - - /* - * Set Rx_Ctl - Turn off reception and let RxData turn it - * on later - */ - writew(ETHER_RX_CTL_RXHALT_MSK,ETHER_RX_CTL(dev->base_addr)); - -} - - -static void ether00_set_multicast(struct net_device* dev) -{ - int count=dev->mc_count; - - /* Set promiscuous mode if it's asked for. */ - - if (dev->flags&IFF_PROMISC){ - - writew( ETHER_ARC_CTL_COMPEN_MSK | - ETHER_ARC_CTL_BROADACC_MSK | - ETHER_ARC_CTL_GROUPACC_MSK | - ETHER_ARC_CTL_STATIONACC_MSK, - ETHER_ARC_CTL(dev->base_addr)); - return; - } - - /* - * Get all multicast packets if required, or if there are too - * many addresses to fit in hardware - */ - if (dev->flags & IFF_ALLMULTI){ - writew( ETHER_ARC_CTL_COMPEN_MSK | - ETHER_ARC_CTL_GROUPACC_MSK | - ETHER_ARC_CTL_BROADACC_MSK, - ETHER_ARC_CTL(dev->base_addr)); - return; - } - if (dev->mc_count > (ETHER_ARC_SIZE - 1)){ - - printk(KERN_WARNING "Too many multicast addresses for hardware to filter - receiving all multicast packets\n"); - writew( ETHER_ARC_CTL_COMPEN_MSK | - ETHER_ARC_CTL_GROUPACC_MSK | - ETHER_ARC_CTL_BROADACC_MSK, - ETHER_ARC_CTL(dev->base_addr)); - return; - } - - if(dev->mc_count){ - struct dev_mc_list *mc_list_ent=dev->mc_list; - unsigned int temp,i; - DEBUG(printk("mc_count=%d mc_list=%#x\n",dev-> mc_count, dev->mc_list)); - DEBUG(printk("mc addr=%02#x%02x%02x%02x%02x%02x\n", - mc_list_ent->dmi_addr[5], - mc_list_ent->dmi_addr[4], - mc_list_ent->dmi_addr[3], - mc_list_ent->dmi_addr[2], - mc_list_ent->dmi_addr[1], - mc_list_ent->dmi_addr[0]);) - - /* - * The first 6 bytes are the MAC address, so - * don't change them! - */ - writew(4,ETHER_ARC_ADR(dev->base_addr)); - temp=readl(ETHER_ARC_DATA(dev->base_addr)); - temp&=0xffff0000; - - /* Disable the current multicast stuff */ - writel(1,ETHER_ARC_ENA(dev->base_addr)); - - for(;;){ - temp|=mc_list_ent->dmi_addr[1] | - mc_list_ent->dmi_addr[0]<<8; - writel(temp,ETHER_ARC_DATA(dev->base_addr)); - - i=readl(ETHER_ARC_ADR(dev->base_addr)); - writew(i+4,ETHER_ARC_ADR(dev->base_addr)); - - temp=mc_list_ent->dmi_addr[5]| - mc_list_ent->dmi_addr[4]<<8 | - mc_list_ent->dmi_addr[3]<<16 | - mc_list_ent->dmi_addr[2]<<24; - writel(temp,ETHER_ARC_DATA(dev->base_addr)); - - count--; - if(!mc_list_ent->next || !count){ - break; - } - DEBUG(printk("mc_list_next=%#x\n",mc_list_ent->next);) - mc_list_ent=mc_list_ent->next; - - - i=readl(ETHER_ARC_ADR(dev->base_addr)); - writel(i+4,ETHER_ARC_ADR(dev->base_addr)); - - temp=mc_list_ent->dmi_addr[3]| - mc_list_ent->dmi_addr[2]<<8 | - mc_list_ent->dmi_addr[1]<<16 | - mc_list_ent->dmi_addr[0]<<24; - writel(temp,ETHER_ARC_DATA(dev->base_addr)); - - i=readl(ETHER_ARC_ADR(dev->base_addr)); - writel(i+4,ETHER_ARC_ADR(dev->base_addr)); - - temp=mc_list_ent->dmi_addr[4]<<16 | - mc_list_ent->dmi_addr[5]<<24; - - writel(temp,ETHER_ARC_DATA(dev->base_addr)); - - count--; - if(!mc_list_ent->next || !count){ - break; - } - mc_list_ent=mc_list_ent->next; - } - - - if(count) - printk(KERN_WARNING "Multicast list size error\n"); - - - writew( ETHER_ARC_CTL_BROADACC_MSK| - ETHER_ARC_CTL_COMPEN_MSK, - ETHER_ARC_CTL(dev->base_addr)); - - } - - /* enable the active ARC enties */ - writew((1<<(count+2))-1,ETHER_ARC_ENA(dev->base_addr)); -} - - -static int ether00_open(struct net_device* dev) -{ - int result,tmp; - struct net_priv* priv; - - if (!is_valid_ether_addr(dev->dev_addr)) - return -EINVAL; - - /* Install interrupt handlers */ - result=request_irq(dev->irq,ether00_int,0,"ether00",dev); - if(result) - goto open_err1; - - result=request_irq(2,ether00_phy_int,0,"ether00_phy",dev); - if(result) - goto open_err2; - - ether00_reset(dev); - result=ether00_mem_init(dev); - if(result) - goto open_err3; - - - ether00_setup_ethernet_address(dev); - - ether00_set_multicast(dev); - - result=ether00_write_phy(dev,PHY_CONTROL, PHY_CONTROL_ANEGEN_MSK | PHY_CONTROL_RANEG_MSK); - if(result) - goto open_err4; - result=ether00_write_phy(dev,PHY_IRQ_CONTROL, PHY_IRQ_CONTROL_LS_CHG_IE_MSK | - PHY_IRQ_CONTROL_ANEG_COMP_IE_MSK); - if(result) - goto open_err4; - - /* Start the device enable interrupts */ - writew(ETHER_RX_CTL_RXEN_MSK -// | ETHER_RX_CTL_STRIPCRC_MSK - | ETHER_RX_CTL_ENGOOD_MSK - | ETHER_RX_CTL_ENRXPAR_MSK| ETHER_RX_CTL_ENLONGERR_MSK - | ETHER_RX_CTL_ENOVER_MSK| ETHER_RX_CTL_ENCRCERR_MSK, - ETHER_RX_CTL(dev->base_addr)); - - writew(ETHER_TX_CTL_TXEN_MSK| - ETHER_TX_CTL_ENEXDEFER_MSK| - ETHER_TX_CTL_ENLCARR_MSK| - ETHER_TX_CTL_ENEXCOLL_MSK| - ETHER_TX_CTL_ENLATECOLL_MSK| - ETHER_TX_CTL_ENTXPAR_MSK| - ETHER_TX_CTL_ENCOMP_MSK, - ETHER_TX_CTL(dev->base_addr)); - - tmp=readl(ETHER_DMA_CTL(dev->base_addr)); - writel(tmp&~ETHER_DMA_CTL_INTMASK_MSK,ETHER_DMA_CTL(dev->base_addr)); - - return 0; - - open_err4: - ether00_reset(dev); - open_err3: - free_irq(2,dev); - open_err2: - free_irq(dev->irq,dev); - open_err1: - return result; - -} - - -static int ether00_tx(struct sk_buff* skb, struct net_device* dev) -{ - struct net_priv *priv=dev->priv; - struct tx_fda_ent *fda_ptr; - int i; - - - /* - * Find an empty slot in which to stick the frame - */ - fda_ptr=(struct tx_fda_ent*)__dma_va(readl(ETHER_TXFRMPTR(dev->base_addr))); - i=0; - while(ifd.FDStat||(fda_ptr->fd.FDCtl & FDCTL_COWNSFD_MSK)){ - fda_ptr =(struct tx_fda_ent*) __dma_va((struct tx_fda_ent*)fda_ptr->fd.FDNext); - } - else { - break; - } - i++; - } - - /* Write the skb data from the cache*/ - consistent_sync(skb->data,skb->len,PCI_DMA_TODEVICE); - fda_ptr->bd.BuffData=(char*)__pa(skb->data); - fda_ptr->bd.BuffLength=(unsigned short)skb->len; - /* Save the pointer to the skb for freeing later */ - fda_ptr->fd.FDSystem=(unsigned int)skb; - fda_ptr->fd.FDStat=0; - /* Pass ownership of the buffers to the controller */ - fda_ptr->fd.FDCtl=1; - fda_ptr->fd.FDCtl|=FDCTL_COWNSFD_MSK; - - /* If the next buffer in the list is full, stop the queue */ - fda_ptr=(struct tx_fda_ent*)__dma_va(fda_ptr->fd.FDNext); - if ((fda_ptr->fd.FDStat)||(fda_ptr->fd.FDCtl & FDCTL_COWNSFD_MSK)){ - netif_stop_queue(dev); - priv->queue_stopped=1; - } - - return 0; -} - -static struct net_device_stats *ether00_stats(struct net_device* dev) -{ - struct net_priv *priv=dev->priv; - return &priv->stats; -} - - -static int ether00_stop(struct net_device* dev) -{ - struct net_priv *priv=dev->priv; - int tmp; - - /* Stop/disable the device. */ - tmp=readw(ETHER_RX_CTL(dev->base_addr)); - tmp&=~(ETHER_RX_CTL_RXEN_MSK | ETHER_RX_CTL_ENGOOD_MSK); - tmp|=ETHER_RX_CTL_RXHALT_MSK; - writew(tmp,ETHER_RX_CTL(dev->base_addr)); - - tmp=readl(ETHER_TX_CTL(dev->base_addr)); - tmp&=~ETHER_TX_CTL_TXEN_MSK; - tmp|=ETHER_TX_CTL_TXHALT_MSK; - writel(tmp,ETHER_TX_CTL(dev->base_addr)); - - /* Free up system resources */ - free_irq(dev->irq,dev); - free_irq(2,dev); - iounmap(priv->dma_data); - - return 0; -} - - -static void ether00_get_ethernet_address(struct net_device* dev) -{ - struct mtd_info *mymtd=NULL; - int i; - size_t retlen; - - /* - * For the Epxa10 dev board (camelot), the ethernet MAC - * address is of the form 00:aa:aa:00:xx:xx where - * 00:aa:aa is the Altera vendor ID and xx:xx is the - * last 2 bytes of the board serial number, as programmed - * into the OTP area of the flash device on EBI1. If this - * isn't an expa10 dev board, or there's no mtd support to - * read the serial number from flash then we'll force the - * use to set their own mac address using ifconfig. - */ - -#ifdef CONFIG_ARCH_CAMELOT -#ifdef CONFIG_MTD - /* get the mtd_info structure for the first mtd device*/ - for(i=0;iname,"EPXA10DB flash")) - break; - } - - if(!mymtd || !mymtd->read_user_prot_reg){ - printk(KERN_WARNING "%s: Failed to read MAC address from flash\n",dev->name); - }else{ - mymtd->read_user_prot_reg(mymtd,2,1,&retlen,&dev->dev_addr[5]); - mymtd->read_user_prot_reg(mymtd,3,1,&retlen,&dev->dev_addr[4]); - dev->dev_addr[3]=0; - dev->dev_addr[2]=vendor_id[1]; - dev->dev_addr[1]=vendor_id[0]; - dev->dev_addr[0]=0; - } -#else - printk(KERN_WARNING "%s: MTD support required to read MAC address from EPXA10 dev board\n", dev->name); -#endif -#endif - - if (!is_valid_ether_addr(dev->dev_addr)) - printk("%s: Invalid ethernet MAC address. Please set using " - "ifconfig\n", dev->name); - -} - -/* - * Keep a mapping of dev_info addresses -> port lines to use when - * removing ports dev==NULL indicates unused entry - */ - - -static struct net_device* dev_list[ETH_NR]; - -static int ether00_add_device(struct pldhs_dev_info* dev_info,void* dev_ps_data) -{ - struct net_device *dev; - struct net_priv *priv; - void *map_addr; - int result; - int i; - - i=0; - while(dev_list[i] && i < ETH_NR) - i++; - - if(i==ETH_NR){ - printk(KERN_WARNING "ether00: Maximum number of ports reached\n"); - return 0; - } - - - if (!request_mem_region(dev_info->base_addr, MAC_REG_SIZE, "ether00")) - return -EBUSY; - - dev = alloc_etherdev(sizeof(struct net_priv)); - if(!dev) { - result = -ENOMEM; - goto out_release; - } - priv = dev->priv; - - priv->tq_memupdate.routine=ether00_mem_update; - priv->tq_memupdate.data=(void*) dev; - - spin_lock_init(&priv->rx_lock); - - map_addr=ioremap_nocache(dev_info->base_addr,SZ_4K); - if(!map_addr){ - result = -ENOMEM; - out_kfree; - } - - dev->open=ether00_open; - dev->stop=ether00_stop; - dev->set_multicast_list=ether00_set_multicast; - dev->hard_start_xmit=ether00_tx; - dev->get_stats=ether00_stats; - - ether00_get_ethernet_address(dev); - - SET_MODULE_OWNER(dev); - - dev->base_addr=(unsigned int)map_addr; - dev->irq=dev_info->irq; - dev->features=NETIF_F_DYNALLOC | NETIF_F_HW_CSUM; - - result=register_netdev(dev); - if(result){ - printk("Ether00: Error %i registering driver\n",result); - goto out_unmap; - } - printk("registered ether00 device at %#x\n",dev_info->base_addr); - - dev_list[i]=dev; - - return result; - - out_unmap: - iounmap(map_addr); - out_kfree: - free_netdev(dev); - out_release: - release_mem_region(dev_info->base_addr, MAC_REG_SIZE); - return result; -} - - -static int ether00_remove_devices(void) -{ - int i; - - for(i=0;ibase_addr); - release_mem_region(dev_list[i]->base_addr, MAC_REG_SIZE); - free_netdev(dev_list[i]); - dev_list[i]=0; - } - } - return 0; -} - -static struct pld_hotswap_ops ether00_pldhs_ops={ - .name = ETHER00_NAME, - .add_device = ether00_add_device, - .remove_devices = ether00_remove_devices, -}; - - -static void __exit ether00_cleanup_module(void) -{ - int result; - result=ether00_remove_devices(); - if(result) - printk(KERN_WARNING "ether00: failed to remove all devices\n"); - - pldhs_unregister_driver(ETHER00_NAME); -} -module_exit(ether00_cleanup_module); - - -static int __init ether00_mod_init(void) -{ - printk("mod init\n"); - return pldhs_register_driver(ðer00_pldhs_ops); - -} - -module_init(ether00_mod_init); - diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 812bae62c8e..47ea8338c03 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -359,29 +359,6 @@ config SERIAL_21285_CONSOLE your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) -config SERIAL_UART00 - bool "Excalibur serial port (uart00) support" - depends on ARM && ARCH_CAMELOT - select SERIAL_CORE - help - Say Y here if you want to use the hard logic uart on Excalibur. This - driver also supports soft logic implementations of this uart core. - -config SERIAL_UART00_CONSOLE - bool "Support for console on Excalibur serial port" - depends on SERIAL_UART00 - select SERIAL_CORE_CONSOLE - help - Say Y here if you want to support a serial console on an Excalibur - hard logic uart or uart00 IP core. - - Even if you say Y here, the currently visible virtual console - (/dev/tty0) will still be used as the system console by default, but - you can alter that using a kernel command line option such as - "console=ttyS1". (Try "man bootparam" or see the documentation of - your boot loader (lilo or loadlin) about how to pass options to the - kernel at boot time.) - config SERIAL_MPSC bool "Marvell MPSC serial port support" depends on PPC32 && MV64X60 diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index d7c7c7180e3..137148bba4f 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -29,7 +29,6 @@ obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o obj-$(CONFIG_SERIAL_PXA) += pxa.o obj-$(CONFIG_SERIAL_SA1100) += sa1100.o obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o -obj-$(CONFIG_SERIAL_UART00) += uart00.o obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o diff --git a/drivers/serial/uart00.c b/drivers/serial/uart00.c deleted file mode 100644 index 47b504ff38b..00000000000 --- a/drivers/serial/uart00.c +++ /dev/null @@ -1,782 +0,0 @@ -/* - * linux/drivers/serial/uart00.c - * - * Driver for UART00 serial ports - * - * Based on drivers/char/serial_amba.c, by ARM Limited & - * Deep Blue Solutions Ltd. - * Copyright 2001 Altera Corporation - * - * Update for 2.6.4 by Dirk Behme - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: uart00.c,v 1.35 2002/07/28 10:03:28 rmk Exp $ - * - */ -#include - -#if defined(CONFIG_SERIAL_UART00_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#define UART00_TYPE (volatile unsigned int*) -#include -#include - -#define UART_NR 2 - -#define SERIAL_UART00_NAME "ttyUA" -#define SERIAL_UART00_MAJOR 204 -#define SERIAL_UART00_MINOR 16 /* Temporary - will change in future */ -#define SERIAL_UART00_NR UART_NR -#define UART_PORT_SIZE 0x50 - -#define UART00_ISR_PASS_LIMIT 256 - -/* - * Access macros for the UART00 UARTs - */ -#define UART_GET_INT_STATUS(p) inl(UART_ISR((p)->membase)) -#define UART_PUT_IES(p, c) outl(c,UART_IES((p)->membase)) -#define UART_GET_IES(p) inl(UART_IES((p)->membase)) -#define UART_PUT_IEC(p, c) outl(c,UART_IEC((p)->membase)) -#define UART_GET_IEC(p) inl(UART_IEC((p)->membase)) -#define UART_PUT_CHAR(p, c) outl(c,UART_TD((p)->membase)) -#define UART_GET_CHAR(p) inl(UART_RD((p)->membase)) -#define UART_GET_RSR(p) inl(UART_RSR((p)->membase)) -#define UART_GET_RDS(p) inl(UART_RDS((p)->membase)) -#define UART_GET_MSR(p) inl(UART_MSR((p)->membase)) -#define UART_GET_MCR(p) inl(UART_MCR((p)->membase)) -#define UART_PUT_MCR(p, c) outl(c,UART_MCR((p)->membase)) -#define UART_GET_MC(p) inl(UART_MC((p)->membase)) -#define UART_PUT_MC(p, c) outl(c,UART_MC((p)->membase)) -#define UART_GET_TSR(p) inl(UART_TSR((p)->membase)) -#define UART_GET_DIV_HI(p) inl(UART_DIV_HI((p)->membase)) -#define UART_PUT_DIV_HI(p,c) outl(c,UART_DIV_HI((p)->membase)) -#define UART_GET_DIV_LO(p) inl(UART_DIV_LO((p)->membase)) -#define UART_PUT_DIV_LO(p,c) outl(c,UART_DIV_LO((p)->membase)) -#define UART_RX_DATA(s) ((s) & UART_RSR_RX_LEVEL_MSK) -#define UART_TX_READY(s) (((s) & UART_TSR_TX_LEVEL_MSK) < 15) -//#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & UART00_UARTFR_TMSK) == 0) - -static void uart00_stop_tx(struct uart_port *port) -{ - UART_PUT_IEC(port, UART_IEC_TIE_MSK); -} - -static void uart00_stop_rx(struct uart_port *port) -{ - UART_PUT_IEC(port, UART_IEC_RE_MSK); -} - -static void uart00_enable_ms(struct uart_port *port) -{ - UART_PUT_IES(port, UART_IES_ME_MSK); -} - -static void -uart00_rx_chars(struct uart_port *port, struct pt_regs *regs) -{ - struct tty_struct *tty = port->info->tty; - unsigned int status, ch, rds, flg, ignored = 0; - - status = UART_GET_RSR(port); - while (UART_RX_DATA(status)) { - /* - * We need to read rds before reading the - * character from the fifo - */ - rds = UART_GET_RDS(port); - ch = UART_GET_CHAR(port); - port->icount.rx++; - - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - goto ignore_char; - - flg = TTY_NORMAL; - - /* - * Note that the error handling code is - * out of the main execution path - */ - if (rds & (UART_RDS_BI_MSK |UART_RDS_FE_MSK| - UART_RDS_PE_MSK |UART_RDS_PE_MSK)) - goto handle_error; - if (uart_handle_sysrq_char(port, ch, regs)) - goto ignore_char; - - error_return: - tty_insert_flip_char(tty, ch, flg); - - ignore_char: - status = UART_GET_RSR(port); - } - out: - tty_flip_buffer_push(tty); - return; - - handle_error: - if (rds & UART_RDS_BI_MSK) { - status &= ~(UART_RDS_FE_MSK | UART_RDS_PE_MSK); - port->icount.brk++; - if (uart_handle_break(port)) - goto ignore_char; - } else if (rds & UART_RDS_PE_MSK) - port->icount.parity++; - else if (rds & UART_RDS_FE_MSK) - port->icount.frame++; - if (rds & UART_RDS_OE_MSK) - port->icount.overrun++; - - if (rds & port->ignore_status_mask) { - if (++ignored > 100) - goto out; - goto ignore_char; - } - rds &= port->read_status_mask; - - if (rds & UART_RDS_BI_MSK) - flg = TTY_BREAK; - else if (rds & UART_RDS_PE_MSK) - flg = TTY_PARITY; - else if (rds & UART_RDS_FE_MSK) - flg = TTY_FRAME; - - if (rds & UART_RDS_OE_MSK) { - /* - * CHECK: does overrun affect the current character? - * ASSUMPTION: it does not. - */ - tty_insert_flip_char(tty, ch, flg); - ch = 0; - flg = TTY_OVERRUN; - } -#ifdef SUPPORT_SYSRQ - port->sysrq = 0; -#endif - goto error_return; -} - -static void uart00_tx_chars(struct uart_port *port) -{ - struct circ_buf *xmit = &port->info->xmit; - int count; - - if (port->x_char) { - while ((UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK) == 15) - barrier(); - UART_PUT_CHAR(port, port->x_char); - port->icount.tx++; - port->x_char = 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - uart00_stop_tx(port); - return; - } - - count = port->fifosize >> 1; - do { - while ((UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK) == 15) - barrier(); - UART_PUT_CHAR(port, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (uart_circ_empty(xmit)) - uart00_stop_tx(port); -} - -static void uart00_start_tx(struct uart_port *port) -{ - UART_PUT_IES(port, UART_IES_TIE_MSK); - uart00_tx_chars(port); -} - -static void uart00_modem_status(struct uart_port *port) -{ - unsigned int status; - - status = UART_GET_MSR(port); - - if (!(status & (UART_MSR_DCTS_MSK | UART_MSR_DDSR_MSK | - UART_MSR_TERI_MSK | UART_MSR_DDCD_MSK))) - return; - - if (status & UART_MSR_DDCD_MSK) - uart_handle_dcd_change(port, status & UART_MSR_DCD_MSK); - - if (status & UART_MSR_DDSR_MSK) - port->icount.dsr++; - - if (status & UART_MSR_DCTS_MSK) - uart_handle_cts_change(port, status & UART_MSR_CTS_MSK); - - wake_up_interruptible(&port->info->delta_msr_wait); -} - -static irqreturn_t uart00_int(int irq, void *dev_id, struct pt_regs *regs) -{ - struct uart_port *port = dev_id; - unsigned int status, pass_counter = 0; - - status = UART_GET_INT_STATUS(port); - do { - if (status & UART_ISR_RI_MSK) - uart00_rx_chars(port, regs); - if (status & UART_ISR_MI_MSK) - uart00_modem_status(port); - if (status & (UART_ISR_TI_MSK | UART_ISR_TII_MSK)) - uart00_tx_chars(port); - if (pass_counter++ > UART00_ISR_PASS_LIMIT) - break; - - status = UART_GET_INT_STATUS(port); - } while (status); - - return IRQ_HANDLED; -} - -static unsigned int uart00_tx_empty(struct uart_port *port) -{ - return UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK? 0 : TIOCSER_TEMT; -} - -static unsigned int uart00_get_mctrl(struct uart_port *port) -{ - unsigned int result = 0; - unsigned int status; - - status = UART_GET_MSR(port); - if (status & UART_MSR_DCD_MSK) - result |= TIOCM_CAR; - if (status & UART_MSR_DSR_MSK) - result |= TIOCM_DSR; - if (status & UART_MSR_CTS_MSK) - result |= TIOCM_CTS; - if (status & UART_MSR_RI_MSK) - result |= TIOCM_RI; - - return result; -} - -static void uart00_set_mctrl_null(struct uart_port *port, unsigned int mctrl) -{ -} - -static void uart00_break_ctl(struct uart_port *port, int break_state) -{ - unsigned long flags; - unsigned int mcr; - - spin_lock_irqsave(&port->lock, flags); - mcr = UART_GET_MCR(port); - if (break_state == -1) - mcr |= UART_MCR_BR_MSK; - else - mcr &= ~UART_MCR_BR_MSK; - UART_PUT_MCR(port, mcr); - spin_unlock_irqrestore(&port->lock, flags); -} - -static void -uart00_set_termios(struct uart_port *port, struct termios *termios, - struct termios *old) -{ - unsigned int uart_mc, old_ies, baud, quot; - unsigned long flags; - - /* - * We don't support CREAD (yet) - */ - termios->c_cflag |= CREAD; - - /* - * Ask the core to calculate the divisor for us. - */ - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); - quot = uart_get_divisor(port, baud); - - /* byte size and parity */ - switch (termios->c_cflag & CSIZE) { - case CS5: - uart_mc = UART_MC_CLS_CHARLEN_5; - break; - case CS6: - uart_mc = UART_MC_CLS_CHARLEN_6; - break; - case CS7: - uart_mc = UART_MC_CLS_CHARLEN_7; - break; - default: // CS8 - uart_mc = UART_MC_CLS_CHARLEN_8; - break; - } - if (termios->c_cflag & CSTOPB) - uart_mc|= UART_MC_ST_TWO; - if (termios->c_cflag & PARENB) { - uart_mc |= UART_MC_PE_MSK; - if (!(termios->c_cflag & PARODD)) - uart_mc |= UART_MC_EP_MSK; - } - - spin_lock_irqsave(&port->lock, flags); - - /* - * Update the per-port timeout. - */ - uart_update_timeout(port, termios->c_cflag, baud); - - port->read_status_mask = UART_RDS_OE_MSK; - if (termios->c_iflag & INPCK) - port->read_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK; - if (termios->c_iflag & (BRKINT | PARMRK)) - port->read_status_mask |= UART_RDS_BI_MSK; - - /* - * Characters to ignore - */ - port->ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK; - if (termios->c_iflag & IGNBRK) { - port->ignore_status_mask |= UART_RDS_BI_MSK; - /* - * If we're ignoring parity and break indicators, - * ignore overruns to (for real raw support). - */ - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= UART_RDS_OE_MSK; - } - - /* first, disable everything */ - old_ies = UART_GET_IES(port); - - if (UART_ENABLE_MS(port, termios->c_cflag)) - old_ies |= UART_IES_ME_MSK; - - /* Set baud rate */ - UART_PUT_DIV_LO(port, (quot & 0xff)); - UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8)); - - UART_PUT_MC(port, uart_mc); - UART_PUT_IES(port, old_ies); - - spin_unlock_irqrestore(&port->lock, flags); -} - -static int uart00_startup(struct uart_port *port) -{ - int result; - - /* - * Allocate the IRQ - */ - result = request_irq(port->irq, uart00_int, 0, "uart00", port); - if (result) { - printk(KERN_ERR "Request of irq %d failed\n", port->irq); - return result; - } - - /* - * Finally, enable interrupts. Use the TII interrupt to minimise - * the number of interrupts generated. If higher performance is - * needed, consider using the TI interrupt with a suitable FIFO - * threshold - */ - UART_PUT_IES(port, UART_IES_RE_MSK | UART_IES_TIE_MSK); - - return 0; -} - -static void uart00_shutdown(struct uart_port *port) -{ - /* - * disable all interrupts, disable the port - */ - UART_PUT_IEC(port, 0xff); - - /* disable break condition and fifos */ - UART_PUT_MCR(port, UART_GET_MCR(port) &~UART_MCR_BR_MSK); - - /* - * Free the interrupt - */ - free_irq(port->irq, port); -} - -static const char *uart00_type(struct uart_port *port) -{ - return port->type == PORT_UART00 ? "Altera UART00" : NULL; -} - -/* - * Release the memory region(s) being used by 'port' - */ -static void uart00_release_port(struct uart_port *port) -{ - release_mem_region(port->mapbase, UART_PORT_SIZE); - -#ifdef CONFIG_ARCH_CAMELOT - if (port->membase != (void*)IO_ADDRESS(EXC_UART00_BASE)) { - iounmap(port->membase); - } -#endif -} - -/* - * Request the memory region(s) being used by 'port' - */ -static int uart00_request_port(struct uart_port *port) -{ - return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_uart00") - != NULL ? 0 : -EBUSY; -} - -/* - * Configure/autoconfigure the port. - */ -static void uart00_config_port(struct uart_port *port, int flags) -{ - - /* - * Map the io memory if this is a soft uart - */ - if (!port->membase) - port->membase = ioremap_nocache(port->mapbase,SZ_4K); - - if (!port->membase) - printk(KERN_ERR "serial00: cannot map io memory\n"); - else - port->type = PORT_UART00; - -} - -/* - * verify the new serial_struct (for TIOCSSERIAL). - */ -static int uart00_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - int ret = 0; - if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00) - ret = -EINVAL; - if (ser->irq < 0 || ser->irq >= NR_IRQS) - ret = -EINVAL; - if (ser->baud_base < 9600) - ret = -EINVAL; - return ret; -} - -static struct uart_ops uart00_pops = { - .tx_empty = uart00_tx_empty, - .set_mctrl = uart00_set_mctrl_null, - .get_mctrl = uart00_get_mctrl, - .stop_tx = uart00_stop_tx, - .start_tx = uart00_start_tx, - .stop_rx = uart00_stop_rx, - .enable_ms = uart00_enable_ms, - .break_ctl = uart00_break_ctl, - .startup = uart00_startup, - .shutdown = uart00_shutdown, - .set_termios = uart00_set_termios, - .type = uart00_type, - .release_port = uart00_release_port, - .request_port = uart00_request_port, - .config_port = uart00_config_port, - .verify_port = uart00_verify_port, -}; - - -#ifdef CONFIG_ARCH_CAMELOT -static struct uart_port epxa10db_port = { - .membase = (void*)IO_ADDRESS(EXC_UART00_BASE), - .mapbase = EXC_UART00_BASE, - .iotype = SERIAL_IO_MEM, - .irq = IRQ_UART, - .uartclk = EXC_AHB2_CLK_FREQUENCY, - .fifosize = 16, - .ops = &uart00_pops, - .flags = ASYNC_BOOT_AUTOCONF, -}; -#endif - - -#ifdef CONFIG_SERIAL_UART00_CONSOLE -static void uart00_console_write(struct console *co, const char *s, unsigned count) -{ -#ifdef CONFIG_ARCH_CAMELOT - struct uart_port *port = &epxa10db_port; - unsigned int status, old_ies; - int i; - - /* - * First save the CR then disable the interrupts - */ - old_ies = UART_GET_IES(port); - UART_PUT_IEC(port,0xff); - - /* - * Now, do each character - */ - for (i = 0; i < count; i++) { - do { - status = UART_GET_TSR(port); - } while (!UART_TX_READY(status)); - UART_PUT_CHAR(port, s[i]); - if (s[i] == '\n') { - do { - status = UART_GET_TSR(port); - } while (!UART_TX_READY(status)); - UART_PUT_CHAR(port, '\r'); - } - } - - /* - * Finally, wait for transmitter to become empty - * and restore the IES - */ - do { - status = UART_GET_TSR(port); - } while (status & UART_TSR_TX_LEVEL_MSK); - UART_PUT_IES(port, old_ies); -#endif -} - -static void __init -uart00_console_get_options(struct uart_port *port, int *baud, - int *parity, int *bits) -{ - unsigned int uart_mc, quot; - - uart_mc = UART_GET_MC(port); - - *parity = 'n'; - if (uart_mc & UART_MC_PE_MSK) { - if (uart_mc & UART_MC_EP_MSK) - *parity = 'e'; - else - *parity = 'o'; - } - - switch (uart_mc & UART_MC_CLS_MSK) { - case UART_MC_CLS_CHARLEN_5: - *bits = 5; - break; - case UART_MC_CLS_CHARLEN_6: - *bits = 6; - break; - case UART_MC_CLS_CHARLEN_7: - *bits = 7; - break; - case UART_MC_CLS_CHARLEN_8: - *bits = 8; - break; - } - quot = UART_GET_DIV_LO(port) | (UART_GET_DIV_HI(port) << 8); - *baud = port->uartclk / (16 *quot ); -} - -static int __init uart00_console_setup(struct console *co, char *options) -{ - struct uart_port *port; - int baud = 115200; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - -#ifdef CONFIG_ARCH_CAMELOT - port = &epxa10db_port; ; -#else - return -ENODEV; -#endif - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - else - uart00_console_get_options(port, &baud, &parity, &bits); - - return uart_set_options(port, co, baud, parity, bits, flow); -} - -extern struct uart_driver uart00_reg; -static struct console uart00_console = { - .name = SERIAL_UART00_NAME, - .write = uart00_console_write, - .device = uart_console_device, - .setup = uart00_console_setup, - .flags = CON_PRINTBUFFER, - .index = 0, - .data = &uart00_reg, -}; - -static int __init uart00_console_init(void) -{ - register_console(&uart00_console); - return 0; -} -console_initcall(uart00_console_init); - -#define UART00_CONSOLE &uart00_console -#else -#define UART00_CONSOLE NULL -#endif - -static struct uart_driver uart00_reg = { - .owner = NULL, - .driver_name = SERIAL_UART00_NAME, - .dev_name = SERIAL_UART00_NAME, - .major = SERIAL_UART00_MAJOR, - .minor = SERIAL_UART00_MINOR, - .nr = UART_NR, - .cons = UART00_CONSOLE, -}; - -struct dev_port_entry{ - unsigned int base_addr; - struct uart_port *port; -}; - -#ifdef CONFIG_PLD_HOTSWAP - -static struct dev_port_entry dev_port_map[UART_NR]; - -/* - * Keep a mapping of dev_info addresses -> port lines to use when - * removing ports dev==NULL indicates unused entry - */ - -struct uart00_ps_data{ - unsigned int clk; - unsigned int fifosize; -}; - -int uart00_add_device(struct pldhs_dev_info* dev_info, void* dev_ps_data) -{ - struct uart00_ps_data* dev_ps=dev_ps_data; - struct uart_port * port; - int i,result; - - i=0; - while(dev_port_map[i].port) - i++; - - if(i==UART_NR){ - printk(KERN_WARNING "uart00: Maximum number of ports reached\n"); - return 0; - } - - port=kmalloc(sizeof(struct uart_port),GFP_KERNEL); - if(!port) - return -ENOMEM; - - printk("clk=%d fifo=%d\n",dev_ps->clk,dev_ps->fifosize); - port->membase=0; - port->mapbase=dev_info->base_addr; - port->iotype=SERIAL_IO_MEM; - port->irq=dev_info->irq; - port->uartclk=dev_ps->clk; - port->fifosize=dev_ps->fifosize; - port->ops=&uart00_pops; - port->line=i; - port->flags=ASYNC_BOOT_AUTOCONF; - - result=uart_add_one_port(&uart00_reg, port); - if(result){ - printk("uart_add_one_port returned %d\n",result); - return result; - } - dev_port_map[i].base_addr=dev_info->base_addr; - dev_port_map[i].port=port; - printk("uart00: added device at %x as ttyUA%d\n",dev_port_map[i].base_addr,i); - return 0; - -} - -int uart00_remove_devices(void) -{ - int i,result; - - - result=0; - for(i=1;i