// SPDX-License-Identifier: GPL-2.0-only
/*
 * SGI IOC3 master driver and IRQ demuxer
 *
 * Copyright (c) 2005 Stanislaw Skowronek <skylark@linux-mips.org>
 * Heavily based on similar work by:
 *   Brent Casavant <bcasavan@sgi.com> - IOC4 master driver
 *   Pat Gefre <pfg@sgi.com> - IOC3 serial port IRQ demuxer
 */

#include <linux/errno.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/ioc3.h>
#include <linux/rwsem.h>
#include <linux/slab.h>

#define IOC3_PCI_SIZE 0x100000

static LIST_HEAD(ioc3_devices);
static int ioc3_counter;
static DECLARE_RWSEM(ioc3_devices_rwsem);

static struct ioc3_submodule *ioc3_submodules[IOC3_MAX_SUBMODULES];
static struct ioc3_submodule *ioc3_ethernet;
static DEFINE_RWLOCK(ioc3_submodules_lock);

/* NIC probing code */

#define GPCR_MLAN_EN    0x00200000      /* enable MCR to pin 8 */

static inline unsigned mcr_pack(unsigned pulse, unsigned sample)
{
	return (pulse << 10) | (sample << 2);
}

static int nic_wait(struct ioc3_driver_data *idd)
{
	unsigned mcr;

        do {
                mcr = readl(&idd->vma->mcr);
        } while (!(mcr & 2));

        return mcr & 1;
}

static int nic_reset(struct ioc3_driver_data *idd)
{
        int presence;
	unsigned long flags;

	local_irq_save(flags);
	writel(mcr_pack(500, 65), &idd->vma->mcr);
	presence = nic_wait(idd);
	local_irq_restore(flags);

	udelay(500);

        return presence;
}

static int nic_read_bit(struct ioc3_driver_data *idd)
{
	int result;
	unsigned long flags;

	local_irq_save(flags);
	writel(mcr_pack(6, 13), &idd->vma->mcr);
	result = nic_wait(idd);
	local_irq_restore(flags);

	udelay(500);

	return result;
}

static void nic_write_bit(struct ioc3_driver_data *idd, int bit)
{
	if (bit)
		writel(mcr_pack(6, 110), &idd->vma->mcr);
	else
		writel(mcr_pack(80, 30), &idd->vma->mcr);

	nic_wait(idd);
}

static unsigned nic_read_byte(struct ioc3_driver_data *idd)
{
	unsigned result = 0;
	int i;

	for (i = 0; i < 8; i++)
		result = (result >> 1) | (nic_read_bit(idd) << 7);

	return result;
}

static void nic_write_byte(struct ioc3_driver_data *idd, int byte)
{
	int i, bit;

	for (i = 8; i; i--) {
		bit = byte & 1;
		byte >>= 1;

		nic_write_bit(idd, bit);
	}
}

static unsigned long
nic_find(struct ioc3_driver_data *idd, int *last, unsigned long addr)
{
	int a, b, index, disc;

	nic_reset(idd);

	/* Search ROM.  */
	nic_write_byte(idd, 0xF0);

	/* Algorithm from ``Book of iButton Standards''.  */
	for (index = 0, disc = 0; index < 64; index++) {
		a = nic_read_bit(idd);
		b = nic_read_bit(idd);

		if (a && b) {
			printk(KERN_WARNING "IOC3 NIC search failed.\n");
			*last = 0;
			return 0;
		}

		if (!a && !b) {
			if (index == *last) {
				addr |= 1UL << index;
			} else if (index > *last) {
				addr &= ~(1UL << index);
				disc = index;
			} else if ((addr & (1UL << index)) == 0)
				disc = index;
			nic_write_bit(idd, (addr>>index)&1);
			continue;
		} else {
			if (a)
				addr |= 1UL << index;
			else
				addr &= ~(1UL << index);
			nic_write_bit(idd, a);
			continue;
		}
	}
	*last = disc;
	return addr;
}

static void nic_addr(struct ioc3_driver_data *idd, unsigned long addr)
{
	int index;

	nic_reset(idd);
	nic_write_byte(idd, 0xF0);
	for (index = 0; index < 64; index++) {
		nic_read_bit(idd);
		nic_read_bit(idd);
		nic_write_bit(idd, (addr>>index)&1);
	}
}

static void crc16_byte(unsigned int *crc, unsigned char db)
{
	int i;

	for(i=0;i<8;i++) {
		*crc <<= 1;
		if((db^(*crc>>16)) & 1)
			*crc ^= 0x8005;
		db >>= 1;
	}
	*crc &= 0xFFFF;
}

static unsigned int crc16_area(unsigned char *dbs, int size, unsigned int crc)
{
	while(size--)
		crc16_byte(&crc, *(dbs++));
	return crc;
}

static void crc8_byte(unsigned int *crc, unsigned char db)
{
	int i,f;

	for(i=0;i<8;i++) {
		f = (*crc ^ db) & 1;
		*crc >>= 1;
		db >>= 1;
		if(f)
			*crc ^= 0x8c;
	}
	*crc &= 0xff;
}

static unsigned int crc8_addr(unsigned long addr)
{
	int i;
	unsigned int crc = 0x00;

	for(i=0;i<8;i++)
		crc8_byte(&crc, addr>>(i<<3));
	return crc;
}

static void
read_redir_page(struct ioc3_driver_data *idd, unsigned long addr, int page,
			unsigned char *redir, unsigned char *data)
{
	int loops = 16, i;

	while(redir[page] != 0xFF) {
		page = redir[page]^0xFF;
		loops--;
		if(loops<0) {
			printk(KERN_ERR "IOC3: NIC circular redirection\n");
			return;
		}
	}
	loops = 3;
	while(loops>0) {
		nic_addr(idd, addr);
		nic_write_byte(idd, 0xF0);
		nic_write_byte(idd, (page << 5) & 0xE0);
		nic_write_byte(idd, (page >> 3) & 0x1F);
		for(i=0;i<0x20;i++)
			data[i] = nic_read_byte(idd);
		if(crc16_area(data, 0x20, 0x0000) == 0x800d)
			return;
		loops--;
	}
	printk(KERN_ERR "IOC3: CRC error in data page\n");
	for(i=0;i<0x20;i++)
		data[i] = 0x00;
}

static void
read_redir_map(struct ioc3_driver_data *idd, unsigned long addr,
					 unsigned char *redir)
{
	int i,j,loops = 3,crc_ok;
	unsigned int crc;

	while(loops>0) {
		crc_ok = 1;
		nic_addr(idd, addr);
		nic_write_byte(idd, 0xAA);
		nic_write_byte(idd, 0x00);
		nic_write_byte(idd, 0x01);
		for(i=0;i<64;i+=8) {
			for(j=0;j<8;j++)
				redir[i+j] = nic_read_byte(idd);
			crc = crc16_area(redir+i, 8, (i==0)?0x8707:0x0000);
			crc16_byte(&crc, nic_read_byte(idd));
			crc16_byte(&crc, nic_read_byte(idd));
			if(crc != 0x800d)
				crc_ok = 0;
		}
		if(crc_ok)
			return;
		loops--;
	}
	printk(KERN_ERR "IOC3: CRC error in redirection page\n");
	for(i=0;i<64;i++)
		redir[i] = 0xFF;
}

static void read_nic(struct ioc3_driver_data *idd, unsigned long addr)
{
	unsigned char redir[64];
	unsigned char data[64],part[32];
	int i,j;

	/* read redirections */
	read_redir_map(idd, addr, redir);
	/* read data pages */
	read_redir_page(idd, addr, 0, redir, data);
	read_redir_page(idd, addr, 1, redir, data+32);
	/* assemble the part # */
	j=0;
	for(i=0;i<19;i++)
		if(data[i+11] != ' ')
			part[j++] = data[i+11];
	for(i=0;i<6;i++)
		if(data[i+32] != ' ')
			part[j++] = data[i+32];
	part[j] = 0;
	/* skip Octane power supplies */
	if(!strncmp(part, "060-0035-", 9))
		return;
	if(!strncmp(part, "060-0038-", 9))
		return;
	strcpy(idd->nic_part, part);
	/* assemble the serial # */
	j=0;
	for(i=0;i<10;i++)
		if(data[i+1] != ' ')
			idd->nic_serial[j++] = data[i+1];
	idd->nic_serial[j] = 0;
}

static void read_mac(struct ioc3_driver_data *idd, unsigned long addr)
{
	int i, loops = 3;
	unsigned char data[13];

	while(loops>0) {
		nic_addr(idd, addr);
		nic_write_byte(idd, 0xF0);
		nic_write_byte(idd, 0x00);
		nic_write_byte(idd, 0x00);
		nic_read_byte(idd);
		for(i=0;i<13;i++)
			data[i] = nic_read_byte(idd);
		if(crc16_area(data, 13, 0x0000) == 0x800d) {
			for(i=10;i>4;i--)
				idd->nic_mac[10-i] = data[i];
			return;
		}
		loops--;
	}
	printk(KERN_ERR "IOC3: CRC error in MAC address\n");
	for(i=0;i<6;i++)
		idd->nic_mac[i] = 0x00;
}

static void probe_nic(struct ioc3_driver_data *idd)
{
        int save = 0, loops = 3;
        unsigned long first, addr;

        writel(GPCR_MLAN_EN, &idd->vma->gpcr_s);

        while(loops>0) {
                idd->nic_part[0] = 0;
                idd->nic_serial[0] = 0;
                addr = first = nic_find(idd, &save, 0);
                if(!first)
                        return;
                while(1) {
                        if(crc8_addr(addr))
                                break;
                        else {
                                switch(addr & 0xFF) {
                                case 0x0B:
                                        read_nic(idd, addr);
                                        break;
                                case 0x09:
                                case 0x89:
                                case 0x91:
                                        read_mac(idd, addr);
                                        break;
                                }
                        }
                        addr = nic_find(idd, &save, addr);
                        if(addr == first)
                                return;
                }
                loops--;
        }
        printk(KERN_ERR "IOC3: CRC error in NIC address\n");
}

/* Interrupts */

static void write_ireg(struct ioc3_driver_data *idd, uint32_t val, int which)
{
	unsigned long flags;

	spin_lock_irqsave(&idd->ir_lock, flags);
	switch (which) {
	case IOC3_W_IES:
		writel(val, &idd->vma->sio_ies);
		break;
	case IOC3_W_IEC:
		writel(val, &idd->vma->sio_iec);
		break;
	}
	spin_unlock_irqrestore(&idd->ir_lock, flags);
}
static inline uint32_t get_pending_intrs(struct ioc3_driver_data *idd)
{
	unsigned long flag;
	uint32_t intrs = 0;

	spin_lock_irqsave(&idd->ir_lock, flag);
	intrs = readl(&idd->vma->sio_ir);
	intrs &= readl(&idd->vma->sio_ies);
	spin_unlock_irqrestore(&idd->ir_lock, flag);
	return intrs;
}

static irqreturn_t ioc3_intr_io(int irq, void *arg)
{
	unsigned long flags;
	struct ioc3_driver_data *idd = arg;
	int handled = 1, id;
	unsigned int pending;

	read_lock_irqsave(&ioc3_submodules_lock, flags);

	if(idd->dual_irq && readb(&idd->vma->eisr)) {
		/* send Ethernet IRQ to the driver */
		if(ioc3_ethernet && idd->active[ioc3_ethernet->id] &&
						ioc3_ethernet->intr) {
			handled = handled && !ioc3_ethernet->intr(ioc3_ethernet,
							idd, 0);
		}
	}
	pending = get_pending_intrs(idd);	/* look at the IO IRQs */

	for(id=0;id<IOC3_MAX_SUBMODULES;id++) {
		if(idd->active[id] && ioc3_submodules[id]
				&& (pending & ioc3_submodules[id]->irq_mask)
				&& ioc3_submodules[id]->intr) {
			write_ireg(idd, ioc3_submodules[id]->irq_mask,
							IOC3_W_IEC);
			if(!ioc3_submodules[id]->intr(ioc3_submodules[id],
				   idd, pending & ioc3_submodules[id]->irq_mask))
				pending &= ~ioc3_submodules[id]->irq_mask;
			if (ioc3_submodules[id]->reset_mask)
				write_ireg(idd, ioc3_submodules[id]->irq_mask,
							IOC3_W_IES);
		}
	}
	read_unlock_irqrestore(&ioc3_submodules_lock, flags);
	if(pending) {
		printk(KERN_WARNING
		  "IOC3: Pending IRQs 0x%08x discarded and disabled\n",pending);
		write_ireg(idd, pending, IOC3_W_IEC);
		handled = 1;
	}
	return handled?IRQ_HANDLED:IRQ_NONE;
}

static irqreturn_t ioc3_intr_eth(int irq, void *arg)
{
	unsigned long flags;
	struct ioc3_driver_data *idd = (struct ioc3_driver_data *)arg;
	int handled = 1;

	if(!idd->dual_irq)
		return IRQ_NONE;
	read_lock_irqsave(&ioc3_submodules_lock, flags);
	if(ioc3_ethernet && idd->active[ioc3_ethernet->id]
				&& ioc3_ethernet->intr)
		handled = handled && !ioc3_ethernet->intr(ioc3_ethernet, idd, 0);
	read_unlock_irqrestore(&ioc3_submodules_lock, flags);
	return handled?IRQ_HANDLED:IRQ_NONE;
}

void ioc3_enable(struct ioc3_submodule *is,
				struct ioc3_driver_data *idd, unsigned int irqs)
{
	write_ireg(idd, irqs & is->irq_mask, IOC3_W_IES);
}

void ioc3_ack(struct ioc3_submodule *is, struct ioc3_driver_data *idd,
				unsigned int irqs)
{
	writel(irqs & is->irq_mask, &idd->vma->sio_ir);
}

void ioc3_disable(struct ioc3_submodule *is,
				struct ioc3_driver_data *idd, unsigned int irqs)
{
	write_ireg(idd, irqs & is->irq_mask, IOC3_W_IEC);
}

void ioc3_gpcr_set(struct ioc3_driver_data *idd, unsigned int val)
{
	unsigned long flags;
	spin_lock_irqsave(&idd->gpio_lock, flags);
	writel(val, &idd->vma->gpcr_s);
	spin_unlock_irqrestore(&idd->gpio_lock, flags);
}

/* Keep it simple, stupid! */
static int find_slot(void **tab, int max)
{
	int i;
	for(i=0;i<max;i++)
		if(!(tab[i]))
			return i;
	return -1;
}

/* Register an IOC3 submodule */
int ioc3_register_submodule(struct ioc3_submodule *is)
{
	struct ioc3_driver_data *idd;
	int alloc_id;
	unsigned long flags;

	write_lock_irqsave(&ioc3_submodules_lock, flags);
	alloc_id = find_slot((void **)ioc3_submodules, IOC3_MAX_SUBMODULES);
	if(alloc_id != -1) {
		ioc3_submodules[alloc_id] = is;
		if(is->ethernet) {
			if(ioc3_ethernet==NULL)
				ioc3_ethernet=is;
			else
				printk(KERN_WARNING
				  "IOC3 Ethernet module already registered!\n");
		}
	}
	write_unlock_irqrestore(&ioc3_submodules_lock, flags);

	if(alloc_id == -1) {
		printk(KERN_WARNING "Increase IOC3_MAX_SUBMODULES!\n");
		return -ENOMEM;
	}

	is->id=alloc_id;

	/* Initialize submodule for each IOC3 */
	if (!is->probe)
		return 0;

	down_read(&ioc3_devices_rwsem);
	list_for_each_entry(idd, &ioc3_devices, list) {
		/* set to 1 for IRQs in probe */
		idd->active[alloc_id] = 1;
		idd->active[alloc_id] = !is->probe(is, idd);
	}
	up_read(&ioc3_devices_rwsem);

	return 0;
}

/* Unregister an IOC3 submodule */
void ioc3_unregister_submodule(struct ioc3_submodule *is)
{
	struct ioc3_driver_data *idd;
	unsigned long flags;

	write_lock_irqsave(&ioc3_submodules_lock, flags);
	if(ioc3_submodules[is->id]==is)
		ioc3_submodules[is->id]=NULL;
	else
		printk(KERN_WARNING
			"IOC3 submodule %s has wrong ID.\n",is->name);
	if(ioc3_ethernet==is)
		ioc3_ethernet = NULL;
	write_unlock_irqrestore(&ioc3_submodules_lock, flags);

	/* Remove submodule for each IOC3 */
	down_read(&ioc3_devices_rwsem);
	list_for_each_entry(idd, &ioc3_devices, list)
		if(idd->active[is->id]) {
			if(is->remove)
				if(is->remove(is, idd))
					printk(KERN_WARNING
					       "%s: IOC3 submodule %s remove failed "
					       "for pci_dev %s.\n",
					       __func__, module_name(is->owner),
					       pci_name(idd->pdev));
			idd->active[is->id] = 0;
			if(is->irq_mask)
				write_ireg(idd, is->irq_mask, IOC3_W_IEC);
		}
	up_read(&ioc3_devices_rwsem);
}

/*********************
 * Device management *
 *********************/

static char *ioc3_class_names[] = { "unknown", "IP27 BaseIO", "IP30 system",
			"MENET 1/2/3", "MENET 4", "CADduo", "Altix Serial" };

static int ioc3_class(struct ioc3_driver_data *idd)
{
	int res = IOC3_CLASS_NONE;
	/* NIC-based logic */
	if(!strncmp(idd->nic_part, "030-0891-", 9))
		res = IOC3_CLASS_BASE_IP30;
	if(!strncmp(idd->nic_part, "030-1155-", 9))
		res = IOC3_CLASS_CADDUO;
	if(!strncmp(idd->nic_part, "030-1657-", 9))
		res = IOC3_CLASS_SERIAL;
	if(!strncmp(idd->nic_part, "030-1664-", 9))
		res = IOC3_CLASS_SERIAL;
	/* total random heuristics */
#ifdef CONFIG_SGI_IP27
	if(!idd->nic_part[0])
		res = IOC3_CLASS_BASE_IP27;
#endif
	/* print educational message */
	printk(KERN_INFO "IOC3 part: [%s], serial: [%s] => class %s\n",
			idd->nic_part, idd->nic_serial, ioc3_class_names[res]);
	return res;
}
/* Adds a new instance of an IOC3 card */
static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
{
	struct ioc3_driver_data *idd;
	uint32_t pcmd;
	int ret, id;

	/* Enable IOC3 and take ownership of it */
	if ((ret = pci_enable_device(pdev))) {
		printk(KERN_WARNING
		       "%s: Failed to enable IOC3 device for pci_dev %s.\n",
		       __func__, pci_name(pdev));
		goto out;
	}
	pci_set_master(pdev);

#ifdef USE_64BIT_DMA
        ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
        if (!ret) {
                ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
                if (ret < 0) {
                        printk(KERN_WARNING "%s: Unable to obtain 64 bit DMA "
                               "for consistent allocations\n",
				__func__);
                }
	}
#endif

	/* Set up per-IOC3 data */
	idd = kzalloc(sizeof(struct ioc3_driver_data), GFP_KERNEL);
	if (!idd) {
		printk(KERN_WARNING
		       "%s: Failed to allocate IOC3 data for pci_dev %s.\n",
		       __func__, pci_name(pdev));
		ret = -ENODEV;
		goto out_idd;
	}
	spin_lock_init(&idd->ir_lock);
	spin_lock_init(&idd->gpio_lock);
	idd->pdev = pdev;

	/* Map all IOC3 registers.  These are shared between subdevices
	 * so the main IOC3 module manages them.
	 */
	idd->pma = pci_resource_start(pdev, 0);
	if (!idd->pma) {
		printk(KERN_WARNING
		       "%s: Unable to find IOC3 resource "
		       "for pci_dev %s.\n",
		       __func__, pci_name(pdev));
		ret = -ENODEV;
		goto out_pci;
	}
	if (!request_mem_region(idd->pma, IOC3_PCI_SIZE, "ioc3")) {
		printk(KERN_WARNING
		       "%s: Unable to request IOC3 region "
		       "for pci_dev %s.\n",
		       __func__, pci_name(pdev));
		ret = -ENODEV;
		goto out_pci;
	}
	idd->vma = ioremap(idd->pma, IOC3_PCI_SIZE);
	if (!idd->vma) {
		printk(KERN_WARNING
		       "%s: Unable to remap IOC3 region "
		       "for pci_dev %s.\n",
		       __func__, pci_name(pdev));
		ret = -ENODEV;
		goto out_misc_region;
	}

	/* Track PCI-device specific data */
	pci_set_drvdata(pdev, idd);
	down_write(&ioc3_devices_rwsem);
	list_add_tail(&idd->list, &ioc3_devices);
	idd->id = ioc3_counter++;
	up_write(&ioc3_devices_rwsem);

	idd->gpdr_shadow = readl(&idd->vma->gpdr);

	/* Read IOC3 NIC contents */
	probe_nic(idd);

	/* Detect IOC3 class */
	idd->class = ioc3_class(idd);

	/* Initialize IOC3 */
       pci_read_config_dword(pdev, PCI_COMMAND, &pcmd);
       pci_write_config_dword(pdev, PCI_COMMAND,
                               pcmd | PCI_COMMAND_MEMORY |
                               PCI_COMMAND_PARITY | PCI_COMMAND_SERR |
                               PCI_SCR_DROP_MODE_EN);

	write_ireg(idd, ~0, IOC3_W_IEC);
	writel(~0, &idd->vma->sio_ir);

	/* Set up IRQs */
	if(idd->class == IOC3_CLASS_BASE_IP30
				|| idd->class == IOC3_CLASS_BASE_IP27) {
		writel(0, &idd->vma->eier);
		writel(~0, &idd->vma->eisr);

		idd->dual_irq = 1;
		if (!request_irq(pdev->irq, ioc3_intr_eth, IRQF_SHARED,
				 "ioc3-eth", (void *)idd)) {
			idd->irq_eth = pdev->irq;
		} else {
			printk(KERN_WARNING
			       "%s : request_irq fails for IRQ 0x%x\n ",
			       __func__, pdev->irq);
		}
		if (!request_irq(pdev->irq+2, ioc3_intr_io, IRQF_SHARED,
				 "ioc3-io", (void *)idd)) {
			idd->irq_io = pdev->irq+2;
		} else {
			printk(KERN_WARNING
			       "%s : request_irq fails for IRQ 0x%x\n ",
			       __func__, pdev->irq+2);
		}
	} else {
		if (!request_irq(pdev->irq, ioc3_intr_io, IRQF_SHARED,
				 "ioc3", (void *)idd)) {
			idd->irq_io = pdev->irq;
		} else {
			printk(KERN_WARNING
			       "%s : request_irq fails for IRQ 0x%x\n ",
			       __func__, pdev->irq);
		}
	}

	/* Add this IOC3 to all submodules */
	for(id=0;id<IOC3_MAX_SUBMODULES;id++)
		if(ioc3_submodules[id] && ioc3_submodules[id]->probe) {
			idd->active[id] = 1;
			idd->active[id] = !ioc3_submodules[id]->probe
						(ioc3_submodules[id], idd);
		}

	printk(KERN_INFO "IOC3 Master Driver loaded for %s\n", pci_name(pdev));

	return 0;

out_misc_region:
	release_mem_region(idd->pma, IOC3_PCI_SIZE);
out_pci:
	kfree(idd);
out_idd:
	pci_disable_device(pdev);
out:
	return ret;
}

/* Removes a particular instance of an IOC3 card. */
static void ioc3_remove(struct pci_dev *pdev)
{
	int id;
	struct ioc3_driver_data *idd;

	idd = pci_get_drvdata(pdev);

	/* Remove this IOC3 from all submodules */
	for(id=0;id<IOC3_MAX_SUBMODULES;id++)
		if(idd->active[id]) {
			if(ioc3_submodules[id] && ioc3_submodules[id]->remove)
				if(ioc3_submodules[id]->remove(ioc3_submodules[id],
								idd))
					printk(KERN_WARNING
					       "%s: IOC3 submodule 0x%s remove failed "
					       "for pci_dev %s.\n",
						__func__,
						module_name(ioc3_submodules[id]->owner),
					        pci_name(pdev));
			idd->active[id] = 0;
		}

	/* Clear and disable all IRQs */
	write_ireg(idd, ~0, IOC3_W_IEC);
	writel(~0, &idd->vma->sio_ir);

	/* Release resources */
	free_irq(idd->irq_io, (void *)idd);
	if(idd->dual_irq)
		free_irq(idd->irq_eth, (void *)idd);
	iounmap(idd->vma);
	release_mem_region(idd->pma, IOC3_PCI_SIZE);

	/* Disable IOC3 and relinquish */
	pci_disable_device(pdev);

	/* Remove and free driver data */
	down_write(&ioc3_devices_rwsem);
	list_del(&idd->list);
	up_write(&ioc3_devices_rwsem);
	kfree(idd);
}

static struct pci_device_id ioc3_id_table[] = {
	{PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, PCI_ANY_ID, PCI_ANY_ID},
	{0}
};

static struct pci_driver ioc3_driver = {
	.name = "IOC3",
	.id_table = ioc3_id_table,
	.probe = ioc3_probe,
	.remove = ioc3_remove,
};

MODULE_DEVICE_TABLE(pci, ioc3_id_table);

/*********************
 * Module management *
 *********************/

/* Module load */
static int __init ioc3_init(void)
{
	if (ia64_platform_is("sn2"))
		return pci_register_driver(&ioc3_driver);
	return -ENODEV;
}

/* Module unload */
static void __exit ioc3_exit(void)
{
	pci_unregister_driver(&ioc3_driver);
}

module_init(ioc3_init);
module_exit(ioc3_exit);

MODULE_AUTHOR("Stanislaw Skowronek <skylark@linux-mips.org>");
MODULE_DESCRIPTION("PCI driver for SGI IOC3");
MODULE_LICENSE("GPL");

EXPORT_SYMBOL_GPL(ioc3_register_submodule);
EXPORT_SYMBOL_GPL(ioc3_unregister_submodule);
EXPORT_SYMBOL_GPL(ioc3_ack);
EXPORT_SYMBOL_GPL(ioc3_gpcr_set);
EXPORT_SYMBOL_GPL(ioc3_disable);
EXPORT_SYMBOL_GPL(ioc3_enable);
