static void rtcan_ems_pci_del_chan(struct rtcan_device *dev,
				   int init_step)
{
	struct rtcan_ems_pci *board;

	if (!dev)
		return;

	board = (struct rtcan_ems_pci *)dev->board_priv;

	switch (init_step) {
	case 0:			/* Full cleanup */
		RTCAN_DBG("Removing %s %s device %s\n",
			  ems_pci_board_name, dev->ctrl_name, dev->name);
		rtcan_sja1000_unregister(dev);
	case 5:
	case 4:
		iounmap((void *)board->base_addr);
	case 3:
		if (board->channel != EMS_PCI_SLAVE)
			iounmap((void *)board->conf_addr);
	case 2:
		rtcan_dev_free(dev);
	case 1:
		break;
	}
}
static int __devinit ems_pci_init_one (struct pci_dev *pdev,
				       const struct pci_device_id *ent)
{
	struct rtcan_device *master_dev = NULL;
	int err;

	RTCAN_DBG("%s: initializing device %04x:%04x\n",
		  RTCAN_DRV_NAME,  pdev->vendor, pdev->device);

	if ((err = pci_enable_device (pdev)))
		goto failure;

	if ((err = pci_request_regions(pdev, RTCAN_DRV_NAME)))
		goto failure;

	if ((err = pci_write_config_word(pdev, 0x04, 2)))
		goto failure_cleanup;

	if ((err = rtcan_ems_pci_add_chan(pdev, EMS_PCI_MASTER,
					  &master_dev)))
		goto failure_cleanup;
	if ((err = rtcan_ems_pci_add_chan(pdev, EMS_PCI_SLAVE,
					  &master_dev)))
		goto failure_cleanup;

	pci_set_drvdata(pdev, master_dev);
	return 0;

failure_cleanup:
	if (master_dev)
		rtcan_ems_pci_del_chan(master_dev, 0);

	pci_release_regions(pdev);

failure:
	return err;

}
static int __devinit adv_pci_init_one(struct pci_dev *pdev,
				      const struct pci_device_id *ent)
{
	int ret, channel;
	unsigned int nb_ports = 0;
	unsigned int bar = 0;
	unsigned int bar_flag = 0;
	unsigned int offset = 0;
	unsigned int ix;

	struct rtcan_device *master_dev = NULL;

	dev_info(&pdev->dev, "RTCAN Registering card");

	ret = pci_enable_device(pdev);
	if (ret)
		goto failure;

	dev_info(&pdev->dev, "RTCAN detected Advantech PCI card at slot #%i\n",
		 PCI_SLOT(pdev->devfn));

	ret = pci_request_regions(pdev, RTCAN_DRV_NAME);
	if (ret)
		goto failure_device;

	switch (pdev->device) {
	case 0xc001:
	case 0xc002:
	case 0xc004:
	case 0xc101:
	case 0xc102:
	case 0xc104:
		nb_ports = pdev->device & 0x7;
		offset = 0x100;
		bar = 0;
		break;
	case 0x1680:
	case 0x2052:
		nb_ports = 2;
		bar = 2;
		bar_flag = 1;
		break;
	case 0x1681:
		nb_ports = 1;
		bar = 2;
		bar_flag = 1;
		break;
	default:
		goto failure_regions;
	}

	if (nb_ports > 1)
		channel = CHANNEL_MASTER;
	else
		channel = CHANNEL_SINGLE;

	RTCAN_DBG("%s: Initializing device %04x:%04x:%04x\n",
		   RTCAN_DRV_NAME,
		   pdev->vendor,
		   pdev->device,
		   pdev->subsystem_device);

	ret = rtcan_adv_pci_add_chan(pdev, channel, bar, offset, &master_dev);
	if (ret)
		goto failure_iounmap;

	/* register slave channel, if any */

	for (ix = 1; ix < nb_ports; ix++) {
		ret = rtcan_adv_pci_add_chan(pdev,
					     CHANNEL_SLAVE,
					     bar + (bar_flag ? ix : 0),
					     offset * ix,
					     &master_dev);
		if (ret)
			goto failure_iounmap;
	}

	pci_set_drvdata(pdev, master_dev);

	return 0;

failure_iounmap:
	if (master_dev)
		rtcan_adv_pci_del_chan(pdev, master_dev);

failure_regions:
	pci_release_regions(pdev);

failure_device:
	pci_disable_device(pdev);

failure:
	return ret;
}
static int rtcan_adv_pci_add_chan(struct pci_dev *pdev,
				  int channel,
				  unsigned int bar,
				  unsigned int offset,
				  struct rtcan_device **master_dev)
{
	struct rtcan_device *dev;
	struct rtcan_sja1000 *chip;
	struct rtcan_adv_pci *board;
	void __iomem *base_addr;
	int ret;

	dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000),
			      sizeof(struct rtcan_adv_pci));
	if (dev == NULL)
		return -ENOMEM;

	chip = (struct rtcan_sja1000 *)dev->priv;
	board = (struct rtcan_adv_pci *)dev->board_priv;

	if (channel == CHANNEL_SLAVE) {
		struct rtcan_adv_pci *master_board =
			(struct rtcan_adv_pci *)(*master_dev)->board_priv;
		master_board->slave_dev = dev;

		if (offset)
			base_addr = master_board->base_addr+offset;
		else
			base_addr = pci_iomap(pdev, bar, ADV_PCI_BASE_SIZE);
			if (!base_addr) {
				ret = -EIO;
				goto failure;
			}
	} else {
		base_addr = pci_iomap(pdev, bar, ADV_PCI_BASE_SIZE) + offset;
		if (!base_addr) {
			ret = -EIO;
			goto failure;
		}
	}

	board->pci_dev = pdev;
	board->conf_addr = NULL;
	board->base_addr = base_addr;

	dev->board_name = adv_pci_board_name;

	chip->read_reg = rtcan_adv_pci_read_reg;
	chip->write_reg = rtcan_adv_pci_write_reg;

	/* Clock frequency in Hz */
	dev->can_sys_clock = ADV_PCI_CAN_CLOCK;

	/* Output control register */
	chip->ocr = ADV_PCI_OCR;

	/* Clock divider register */
	chip->cdr = ADV_PCI_CDR;

	strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ);

	/* Make sure SJA1000 is in reset mode */
	chip->write_reg(dev, SJA_MOD, SJA_MOD_RM);
	/* Set PeliCAN mode */
	chip->write_reg(dev, SJA_CDR, SJA_CDR_CAN_MODE);

	/* check if mode is set */
	ret = chip->read_reg(dev, SJA_CDR);
	if (ret != SJA_CDR_CAN_MODE) {
		ret = -EIO;
		goto failure_iounmap;
	}

	/* Register and setup interrupt handling */
	chip->irq_flags = RTDM_IRQTYPE_SHARED;
	chip->irq_num = pdev->irq;

	RTCAN_DBG("%s: base_addr=%p conf_addr=%p irq=%d ocr=%#x cdr=%#x\n",
		   RTCAN_DRV_NAME, board->base_addr, board->conf_addr,
		   chip->irq_num, chip->ocr, chip->cdr);

	/* Register SJA1000 device */
	ret = rtcan_sja1000_register(dev);
	if (ret) {
		printk(KERN_ERR "ERROR %d while trying to register SJA1000 device!\n",
		       ret);
		goto failure_iounmap;
	}

	if (channel != CHANNEL_SLAVE)
		*master_dev = dev;

	return 0;

failure_iounmap:
	if (channel != CHANNEL_SLAVE || !offset)
		pci_iounmap(pdev, base_addr);
failure:
	rtcan_dev_free(dev);

	return ret;
}
Example #5
0
static int ixxat_pci_init_one(struct pci_dev *pdev,
			      const struct pci_device_id *ent)
{
    int ret, channel, conf_addr;
    unsigned long addr;
    void __iomem *base_addr;
    struct rtcan_device *master_dev = NULL;

    if ((ret = pci_enable_device (pdev)))
	goto failure;

    if ((ret = pci_request_regions(pdev, RTCAN_DRV_NAME)))
	goto failure;

    RTCAN_DBG("%s: Initializing device %04x:%04x:%04x\n",
	      RTCAN_DRV_NAME, pdev->vendor, pdev->device,
	      pdev->subsystem_device);

    /* Enable memory and I/O space */
    if ((ret = pci_write_config_word(pdev, 0x04, 0x3)))
	goto failure_release_pci;

    conf_addr = pci_resource_start(pdev, 1);

    addr = pci_resource_start(pdev, 2);
    base_addr = ioremap(addr, IXXAT_BASE_PORT_SIZE);
    if (base_addr == 0) {
	ret = -ENODEV;
	goto failure_release_pci;
    }

    /* Check if second channel is available after reset */
    writeb(0x1, base_addr + CHANNEL_MASTER_RESET);
    writeb(0x1, base_addr + CHANNEL_SLAVE_RESET);
    udelay(100);
    if ( (readb(base_addr + CHANNEL_OFFSET + SJA_MOD) & IXXAT_SJA_MOD_MASK ) != 0x21 ||
	readb(base_addr + CHANNEL_OFFSET + SJA_SR ) != 0x0c ||
	readb(base_addr + CHANNEL_OFFSET + SJA_IR ) != 0xe0)
	channel = CHANNEL_SINGLE;
    else
	channel = CHANNEL_MASTER;

    if ((ret = rtcan_ixxat_pci_add_chan(pdev, channel, &master_dev,
					conf_addr, base_addr)))
	goto failure_iounmap;

    if (channel != CHANNEL_SINGLE) {
	channel = CHANNEL_SLAVE;
	if ((ret = rtcan_ixxat_pci_add_chan(pdev, channel,
					    &master_dev, conf_addr,
					    base_addr + CHANNEL_OFFSET)))
	    goto failure_iounmap;
    }

    pci_set_drvdata(pdev, master_dev);
    return 0;

failure_iounmap:
    if (master_dev)
	rtcan_ixxat_pci_del_chan(master_dev);
    iounmap(base_addr);

failure_release_pci:
    pci_release_regions(pdev);

failure:
    return ret;
}
Example #6
0
static int rtcan_ixxat_pci_add_chan(struct pci_dev *pdev,
				    int channel,
				    struct rtcan_device **master_dev,
				    int conf_addr,
				    void __iomem *base_addr)
{
    struct rtcan_device *dev;
    struct rtcan_sja1000 *chip;
    struct rtcan_ixxat_pci *board;
    u8 intcsr;
    int ret;

    dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000),
			  sizeof(struct rtcan_ixxat_pci));
    if (dev == NULL)
	return -ENOMEM;

    chip = (struct rtcan_sja1000 *)dev->priv;
    board = (struct rtcan_ixxat_pci *)dev->board_priv;

    board->pci_dev = pdev;
    board->conf_addr = conf_addr;
    board->base_addr = base_addr;

    if (channel == CHANNEL_SLAVE) {
	struct rtcan_ixxat_pci *master_board =
	    (struct rtcan_ixxat_pci *)(*master_dev)->board_priv;
	master_board->slave_dev = dev;
    }

    dev->board_name = ixxat_pci_board_name;

    chip->read_reg = rtcan_ixxat_pci_read_reg;
    chip->write_reg = rtcan_ixxat_pci_write_reg;

    /* Clock frequency in Hz */
    dev->can_sys_clock = IXXAT_PCI_CAN_SYS_CLOCK;

    /* Output control register */
    chip->ocr = (SJA_OCR_MODE_NORMAL | SJA_OCR_TX0_INVERT |
		 SJA_OCR_TX0_PUSHPULL | SJA_OCR_TX1_PUSHPULL);

    /* Clock divider register */
    chip->cdr = SJA_CDR_CAN_MODE;

    strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ);

    /* Enable PCI interrupts */
    intcsr = inb(board->conf_addr + IXXAT_INTCSR_OFFSET);
    if (channel == CHANNEL_SLAVE)
	intcsr |= IXXAT_INTCSR_SLAVE;
    else
	intcsr |= IXXAT_INTCSR_MASTER;
    outb(intcsr, board->conf_addr + IXXAT_INTCSR_OFFSET);

    /* Register and setup interrupt handling */
    chip->irq_flags = RTDM_IRQTYPE_SHARED;
    chip->irq_num = pdev->irq;

    RTCAN_DBG("%s: base_addr=0x%p conf_addr=%#x irq=%d ocr=%#x cdr=%#x\n",
	      RTCAN_DRV_NAME, board->base_addr, board->conf_addr,
	      chip->irq_num, chip->ocr, chip->cdr);

    /* Register SJA1000 device */
    ret = rtcan_sja1000_register(dev);
    if (ret) {
	printk(KERN_ERR "ERROR %d while trying to register SJA1000 device!\n",
	       ret);
	goto failure;
    }

    if (channel != CHANNEL_SLAVE)
	*master_dev = dev;

    return 0;

 failure:
    rtcan_dev_free(dev);
    return ret;
}