static void kvaser_pci_del_chan(struct net_device *dev) { struct sja1000_priv *priv; struct kvaser_pci *board; int i; if (!dev) return; priv = netdev_priv(dev); board = priv->priv; if (!board) return; dev_info(&board->pci_dev->dev, "Removing device %s\n", dev->name); /* Disable PCI interrupts */ kvaser_pci_disable_irq(dev); for (i = 0; i < board->no_channels - 1; i++) { if (board->slave_dev[i]) { dev_info(&board->pci_dev->dev, "Removing device %s\n", board->slave_dev[i]->name); unregister_sja1000dev(board->slave_dev[i]); free_sja1000dev(board->slave_dev[i]); } } unregister_sja1000dev(dev); pci_iounmap(board->pci_dev, priv->reg_base); pci_iounmap(board->pci_dev, board->conf_addr); pci_iounmap(board->pci_dev, board->res_addr); free_sja1000dev(dev); }
static void ems_pci_del_card(struct pci_dev *pdev) { struct ems_pci_card *card = pci_get_drvdata(pdev); struct net_device *dev; int i = 0; for (i = 0; i < card->channels; i++) { dev = card->net_dev[i]; if (!dev) continue; dev_info(&pdev->dev, "Removing %s.\n", dev->name); unregister_sja1000dev(dev); free_sja1000dev(dev); } if (card->base_addr != NULL) pci_iounmap(card->pci_dev, card->base_addr); if (card->conf_addr != NULL) pci_iounmap(card->pci_dev, card->conf_addr); kfree(card); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); }
/* * Release claimed resources */ static int __devexit ems_104m_remove(struct device *pdev, unsigned int idx) { struct ems_104m_card *card = dev_get_drvdata(pdev); struct net_device *dev; int i = 0; if (!card) return 0; free_irq(card->irq, card); for (i = 0; i < card->channels; i++) { dev = card->net_dev[i]; if (!dev) continue; dev_info(pdev, "removing %s on channel #%d\n", dev->name, i); unregister_sja1000dev(dev); free_sja1000dev(dev); } writeb(EMS_CMD_UMAP, card->base); if (card->base != NULL) iounmap(card->base); kfree(card); dev_set_drvdata(pdev, NULL); return 0; }
/* * free all resources used by the channels and switch off leds and can power */ static void pcan_free_channels(struct pcan_pccard *card) { int i; u8 led_mask = 0; for (i = 0; i < card->chan_count; i++) { struct net_device *netdev; char name[IFNAMSIZ]; led_mask |= PCC_LED(i); netdev = card->channel[i].netdev; if (!netdev) continue; strncpy(name, netdev->name, IFNAMSIZ); unregister_sja1000dev(netdev); free_sja1000dev(netdev); dev_info(&card->pdev->dev, "%s removed\n", name); } /* do it only if device not removed */ if (pcan_pccard_present(card)) { pcan_set_leds(card, led_mask, PCC_LED_OFF); pcan_set_can_power(card, 0); } }
static void ems_pcmcia_del_card(struct pcmcia_device *pdev) { struct ems_pcmcia_card *card = pdev->priv; struct net_device *dev; int i; free_irq(pdev->irq, card); for (i = 0; i < card->channels; i++) { dev = card->net_dev[i]; if (!dev) continue; printk(KERN_INFO "%s: removing %s on channel #%d\n", DRV_NAME, dev->name, i); unregister_sja1000dev(dev); free_sja1000dev(dev); } writeb(EMS_CMD_UMAP, card->base_addr); iounmap(card->base_addr); kfree(card); pdev->priv = NULL; }
static void peak_pci_remove(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); /* Last device */ struct sja1000_priv *priv = netdev_priv(dev); struct peak_pci_chan *chan = priv->priv; void __iomem *cfg_base = chan->cfg_base; void __iomem *reg_base = priv->reg_base; /* Disable interrupts */ writew(0x0, cfg_base + PITA_ICR + 2); /* Loop over all registered devices */ while (1) { struct net_device *prev_dev = chan->prev_dev; dev_info(&pdev->dev, "removing device %s\n", dev->name); unregister_sja1000dev(dev); free_sja1000dev(dev); dev = prev_dev; if (!dev) { /* do that only for first channel */ if (chan->pciec_card) peak_pciec_remove(chan->pciec_card); break; } priv = netdev_priv(dev); chan = priv->priv; } pci_iounmap(pdev, reg_base); pci_iounmap(pdev, cfg_base); pci_release_regions(pdev); pci_disable_device(pdev); }
static int pcm027_remove (struct platform_device *pdev) { struct net_device *dev = dev_get_drvdata(&pdev->dev); struct resource *res; dev_set_drvdata(&pdev->dev, NULL); unregister_sja1000dev(dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, res->end - res->start + 1); if (dev->base_addr) iounmap ((void *)dev->base_addr); free_sja1000dev(dev); return 0; }
static int sja1000_ofp_remove(struct platform_device *ofdev) { struct net_device *dev = platform_get_drvdata(ofdev); struct sja1000_priv *priv = netdev_priv(dev); struct device_node *np = ofdev->dev.of_node; struct resource res; unregister_sja1000dev(dev); free_sja1000dev(dev); iounmap(priv->reg_base); irq_dispose_mapping(dev->irq); of_address_to_resource(np, 0, &res); release_mem_region(res.start, resource_size(&res)); return 0; }
static int sp_remove(struct platform_device *pdev) { struct net_device *dev = dev_get_drvdata(&pdev->dev); struct sja1000_priv *priv = netdev_priv(dev); struct resource *res; unregister_sja1000dev(dev); dev_set_drvdata(&pdev->dev, NULL); if (priv->reg_base) iounmap(priv->reg_base); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); free_sja1000dev(dev); return 0; }
static void plx_pci_del_card(struct pci_dev *pdev) { struct plx_pci_card *card = pci_get_drvdata(pdev); struct net_device *dev; struct sja1000_priv *priv; int i = 0; for (i = 0; i < card->channels; i++) { dev = card->net_dev[i]; if (!dev) continue; dev_info(&pdev->dev, "Removing %s\n", dev->name); unregister_sja1000dev(dev); priv = netdev_priv(dev); if (priv->reg_base) pci_iounmap(pdev, priv->reg_base); free_sja1000dev(dev); } card->reset_func(pdev); /* * Disable interrupts from PCI-card and disable local * interrupts */ if (pdev->device != PCI_DEVICE_ID_PLX_9056) iowrite32(0x0, card->conf_addr + PLX_INTCSR); else iowrite32(0x0, card->conf_addr + PLX9056_INTCSR); if (card->conf_addr) pci_iounmap(pdev, card->conf_addr); kfree(card); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); }
static int __devexit sja1000_isa_remove(struct platform_device *pdev) { struct net_device *dev = dev_get_drvdata(&pdev->dev); struct sja1000_priv *priv = netdev_priv(dev); int idx = pdev->id; unregister_sja1000dev(dev); dev_set_drvdata(&pdev->dev, NULL); if (mem[idx]) { iounmap(priv->reg_base); release_mem_region(mem[idx], SJA1000_IOSIZE); } else { if (priv->read_reg == sja1000_isa_port_read_reg_indirect) release_region(port[idx], SJA1000_IOSIZE_INDIRECT); else release_region(port[idx], SJA1000_IOSIZE); } free_sja1000dev(dev); return 0; }
static int tscan1_remove(struct device *dev, unsigned id /*unused*/) { struct net_device *netdev; struct sja1000_priv *priv; unsigned long pld_base, sja1000_base; netdev = dev_get_drvdata(dev); unregister_sja1000dev(netdev); dev_set_drvdata(dev, NULL); priv = netdev_priv(netdev); pld_base = netdev->base_addr; sja1000_base = (unsigned long)priv->reg_base; outb(0, pld_base + TSCAN1_MODE); /* disable SJA1000 IO space */ release_region(sja1000_base, TSCAN1_SJA1000_SIZE); release_region(pld_base, TSCAN1_PLD_SIZE); free_sja1000dev(netdev); return 0; }
static int pcan_add_channels(struct pcan_pccard *card) { struct pcmcia_device *pdev = card->pdev; int i, err = 0; u8 ccr = PCC_CCR_INIT; /* init common registers (reset channels and leds off) */ card->ccr = ~ccr; pcan_write_reg(card, PCC_CCR, ccr); /* wait 2ms before unresetting channels */ mdelay(2); ccr &= ~PCC_CCR_RST_ALL; pcan_write_reg(card, PCC_CCR, ccr); /* create one network device per channel detected */ for (i = 0; i < ARRAY_SIZE(card->channel); i++) { struct net_device *netdev; struct sja1000_priv *priv; netdev = alloc_sja1000dev(0); if (!netdev) { err = -ENOMEM; break; } /* update linkages */ priv = netdev_priv(netdev); priv->priv = card; SET_NETDEV_DEV(netdev, &pdev->dev); priv->irq_flags = IRQF_SHARED; netdev->irq = pdev->irq; priv->reg_base = card->ioport_addr + PCC_CHAN_OFF(i); /* check if channel is present */ if (!pcan_channel_present(priv)) { dev_err(&pdev->dev, "channel %d not present\n", i); free_sja1000dev(netdev); continue; } priv->read_reg = pcan_read_canreg; priv->write_reg = pcan_write_canreg; priv->can.clock.freq = PCC_CAN_CLOCK; priv->ocr = PCC_OCR; priv->cdr = PCC_CDR; /* Neither a slave device distributes the clock */ if (i > 0) priv->cdr |= CDR_CLK_OFF; priv->flags |= SJA1000_CUSTOM_IRQ_HANDLER; /* register SJA1000 device */ err = register_sja1000dev(netdev); if (err) { free_sja1000dev(netdev); continue; } card->channel[i].netdev = netdev; card->chan_count++; /* set corresponding led on in the new ccr */ ccr &= ~PCC_CCR_LED_OFF_CHAN(i); dev_info(&pdev->dev, "%s on channel %d at 0x%p irq %d\n", netdev->name, i, priv->reg_base, pdev->irq); } /* write new ccr (change leds state) */ pcan_write_reg(card, PCC_CCR, ccr); return err; }
static int __devinit sja1000_ofp_probe(struct of_device *ofdev, const struct of_device_id *id) { struct device_node *np = ofdev->node; struct net_device *dev; struct sja1000_priv *priv; struct resource res; const u32 *prop; int err, irq, res_size, prop_size; void __iomem *base; err = of_address_to_resource(np, 0, &res); if (err) { dev_err(&ofdev->dev, "invalid address\n"); return err; } res_size = resource_size(&res); if (!request_mem_region(res.start, res_size, DRV_NAME)) { dev_err(&ofdev->dev, "couldn't request %#llx..%#llx\n", (unsigned long long)res.start, (unsigned long long)res.end); return -EBUSY; } base = ioremap_nocache(res.start, res_size); if (!base) { dev_err(&ofdev->dev, "couldn't ioremap %#llx..%#llx\n", (unsigned long long)res.start, (unsigned long long)res.end); err = -ENOMEM; goto exit_release_mem; } irq = irq_of_parse_and_map(np, 0); if (irq == NO_IRQ) { dev_err(&ofdev->dev, "no irq found\n"); err = -ENODEV; goto exit_unmap_mem; } dev = alloc_sja1000dev(0); if (!dev) { err = -ENOMEM; goto exit_dispose_irq; } priv = netdev_priv(dev); priv->read_reg = sja1000_ofp_read_reg; priv->write_reg = sja1000_ofp_write_reg; prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size); if (prop && (prop_size == sizeof(u32))) priv->can.clock.freq = *prop / 2; else priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */ prop = of_get_property(np, "nxp,tx-output-mode", &prop_size); if (prop && (prop_size == sizeof(u32))) priv->ocr |= *prop & OCR_MODE_MASK; else priv->ocr |= OCR_MODE_NORMAL; /* default */ prop = of_get_property(np, "nxp,tx-output-config", &prop_size); if (prop && (prop_size == sizeof(u32))) priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK; else priv->ocr |= OCR_TX0_PULLDOWN; /* default */ prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size); if (prop && (prop_size == sizeof(u32)) && *prop) { u32 divider = priv->can.clock.freq * 2 / *prop; if (divider > 1) priv->cdr |= divider / 2 - 1; else priv->cdr |= CDR_CLKOUT_MASK; } else { priv->cdr |= CDR_CLK_OFF; /* default */ } prop = of_get_property(np, "nxp,no-comparator-bypass", NULL); if (!prop) priv->cdr |= CDR_CBP; /* default */ priv->irq_flags = IRQF_SHARED; priv->reg_base = base; dev->irq = irq; dev_info(&ofdev->dev, "reg_base=0x%p irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n", priv->reg_base, dev->irq, priv->can.clock.freq, priv->ocr, priv->cdr); dev_set_drvdata(&ofdev->dev, dev); SET_NETDEV_DEV(dev, &ofdev->dev); err = register_sja1000dev(dev); if (err) { dev_err(&ofdev->dev, "registering %s failed (err=%d)\n", DRV_NAME, err); goto exit_free_sja1000; } return 0; exit_free_sja1000: free_sja1000dev(dev); exit_dispose_irq: irq_dispose_mapping(irq); exit_unmap_mem: iounmap(base); exit_release_mem: release_mem_region(res.start, res_size); return err; }
static int pcm027_probe(struct platform_device *pdev) { int err, irq; void __iomem *addr = 0; struct net_device *dev; struct sja1000_priv *priv; struct resource *res; err = -ENODEV; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); if (!res || !irq) goto exit; err = -EBUSY; if (!request_mem_region(res->start, res->end - res->start + 1, DRV_NAME)) { goto exit; } err = -ENOMEM; addr = ioremap_nocache(res->start, res->end - res->start + 1); if (!addr) { goto exit_release; } dev = alloc_sja1000dev(0); if (!dev) goto exit_iounmap; priv = netdev_priv(dev); priv->read_reg = pcm027_read_reg; priv->write_reg = pcm027_write_reg; priv->can.can_sys_clock = PCM027_CAN_CLOCK; priv->ocr = PCM027_OCR; priv->cdr = PCM027_CDR; dev->irq = irq; dev->base_addr = (unsigned long)addr; dev_set_drvdata(&pdev->dev, dev); err = register_sja1000dev(dev); if (err) { dev_err(&pdev->dev, "registering %s failed (err=%d)\n", DRV_NAME, err); goto exit_free; } printk("%s: %s device registered (base_addr=%#lx, irq=%d)\n", dev->name, DRV_NAME, dev->base_addr, dev->irq); return 0; exit_free: free_sja1000dev(dev); exit_iounmap: iounmap(addr); exit_release: release_mem_region(res->start, res->end - res->start + 1); exit: return err; }
static int __devinit ems_pcmcia_add_card(struct pcmcia_device *pdev, unsigned long base) { struct sja1000_priv *priv; struct net_device *dev; struct ems_pcmcia_card *card; int err, i; /* */ card = kzalloc(sizeof(struct ems_pcmcia_card), GFP_KERNEL); if (!card) return -ENOMEM; pdev->priv = card; card->channels = 0; card->base_addr = ioremap(base, EMS_PCMCIA_MEM_SIZE); if (!card->base_addr) { err = -ENOMEM; goto failure_cleanup; } /* */ if (readw(card->base_addr) != 0xAA55) { err = -ENODEV; goto failure_cleanup; } /* */ writeb(EMS_CMD_RESET, card->base_addr); /* */ writeb(EMS_CMD_MAP, card->base_addr); /* */ for (i = 0; i < EMS_PCMCIA_MAX_CHAN; i++) { dev = alloc_sja1000dev(0); if (!dev) { err = -ENOMEM; goto failure_cleanup; } card->net_dev[i] = dev; priv = netdev_priv(dev); priv->priv = card; SET_NETDEV_DEV(dev, &pdev->dev); priv->irq_flags = IRQF_SHARED; dev->irq = pdev->irq; priv->reg_base = card->base_addr + EMS_PCMCIA_CAN_BASE_OFFSET + (i * EMS_PCMCIA_CAN_CTRL_SIZE); /* */ if (ems_pcmcia_check_chan(priv)) { priv->read_reg = ems_pcmcia_read_reg; priv->write_reg = ems_pcmcia_write_reg; priv->can.clock.freq = EMS_PCMCIA_CAN_CLOCK; priv->ocr = EMS_PCMCIA_OCR; priv->cdr = EMS_PCMCIA_CDR; priv->flags |= SJA1000_CUSTOM_IRQ_HANDLER; /* */ err = register_sja1000dev(dev); if (err) { free_sja1000dev(dev); goto failure_cleanup; } card->channels++; printk(KERN_INFO "%s: registered %s on channel " "#%d at 0x%p, irq %d\n", DRV_NAME, dev->name, i, priv->reg_base, dev->irq); } else free_sja1000dev(dev); } err = request_irq(dev->irq, &ems_pcmcia_interrupt, IRQF_SHARED, DRV_NAME, card); if (!err) return 0; failure_cleanup: ems_pcmcia_del_card(pdev); return err; }
/* * Probe ISA device for EMS CAN signature and register each available * CAN channel to SJA1000 Socket-CAN subsystem. */ static int __devinit ems_104m_probe(struct device *pdev, unsigned int idx) { struct sja1000_priv *priv; struct net_device *dev; struct ems_104m_card *card; int err, i; /* Allocating card structures to hold addresses, ... */ card = kzalloc(sizeof(struct ems_104m_card), GFP_KERNEL); if (card == NULL) { dev_err(pdev, "couldn't allocate memory\n"); return -ENOMEM; } dev_set_drvdata(pdev, card); card->channels = 0; card->irq = irq[idx]; card->base = ioremap_nocache(mem[idx], EMS_104M_MEM_SIZE); if (card->base == NULL) { dev_err(pdev, "couldn't map memory\n"); err = -ENOMEM; goto failure_cleanup; } /* Check for unique EMS CAN signature */ if (readw(card->base) != 0xAA55) { dev_err(pdev, "No EMS CPC Card hardware found.\n"); err = -ENODEV; goto failure_cleanup; } writeb(EMS_CMD_RESET, card->base); /* Wait for reset to finish */ i = 0; while (readb(card->base + EMS_104M_CARD_REG_STATUS) == 0x01) { /* Check for timeout (50ms.) */ if (i >= 50) { dev_err(pdev, "couldn't reset card.\n"); err = -EBUSY; goto failure_cleanup; } msleep(1); } /* Make sure CAN controllers are mapped into card's memory space */ writeb(EMS_CMD_MAP, card->base); writeb(EMS_CMD_MAP, card->base); /* Second call to workaround bug */ /* Detect available channels */ for (i = 0; i < EMS_104M_MAX_CHAN; i++) { dev = alloc_sja1000dev(0); if (dev == NULL) { err = -ENOMEM; goto failure_cleanup; } card->net_dev[i] = dev; priv = netdev_priv(dev); priv->priv = card; SET_NETDEV_DEV(dev, pdev); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) priv->irq_flags = SA_SHIRQ; #else priv->irq_flags = IRQF_SHARED; #endif dev->irq = irq[idx]; priv->reg_base = card->base + EMS_104M_CAN_BASE_OFFSET + (i * EMS_104M_CAN_CTRL_SIZE); /* Check if channel is present */ if (ems_104m_check_chan(priv)) { priv->read_reg = ems_104m_read_reg; priv->write_reg = ems_104m_write_reg; priv->can.clock.freq = EMS_104M_CAN_CLOCK; priv->ocr = EMS_104M_OCR; priv->cdr = EMS_104M_CDR; priv->flags |= SJA1000_CUSTOM_IRQ_HANDLER; /* Register SJA1000 device */ err = register_sja1000dev(dev); if (err) { dev_err(pdev, "registering device failed" " (err=%d)\n", err); free_sja1000dev(dev); goto failure_cleanup; } /* Enable interrupts of this channel */ writeb(0x3 << (i * 2), card->base + EMS_104M_CARD_REG_IRQ_CTRL); card->channels++; dev_info(pdev, "registered %s on channel at 0x%p," " irq %d\n", dev->name, priv->reg_base, dev->irq); } else { free_sja1000dev(dev); } } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) err = request_irq(card->irq, &ems_104m_interrupt, SA_SHIRQ, DRV_NAME, (void *)card); #else err = request_irq(card->irq, &ems_104m_interrupt, IRQF_SHARED, DRV_NAME, (void *)card); #endif if (err) { dev_err(pdev, "registering device failed (err=%d)\n", err); goto failure_cleanup; } return 0; failure_cleanup: dev_err(pdev, "error: %d. Cleaning Up.\n", err); if (card->base) iounmap(card->base); kfree(card); return err; }
/* * Probe PLX90xx based device for the SJA1000 chips and register each * available CAN channel to SJA1000 Socket-CAN subsystem. */ static int __devinit plx_pci_add_card(struct pci_dev *pdev, const struct pci_device_id *ent) { struct sja1000_priv *priv; struct net_device *dev; struct plx_pci_card *card; struct plx_pci_card_info *ci; int err, i; u32 val; void __iomem *addr; ci = (struct plx_pci_card_info *)ent->driver_data; if (pci_enable_device(pdev) < 0) { dev_err(&pdev->dev, "Failed to enable PCI device\n"); return -ENODEV; } dev_info(&pdev->dev, "Detected \"%s\" card at slot #%i\n", ci->name, PCI_SLOT(pdev->devfn)); /* Allocate card structures to hold addresses, ... */ card = kzalloc(sizeof(*card), GFP_KERNEL); if (!card) { dev_err(&pdev->dev, "Unable to allocate memory\n"); pci_disable_device(pdev); return -ENOMEM; } pci_set_drvdata(pdev, card); card->channels = 0; /* Remap PLX90xx configuration space */ addr = pci_iomap(pdev, ci->conf_map.bar, ci->conf_map.size); if (!addr) { err = -ENOMEM; dev_err(&pdev->dev, "Failed to remap configuration space " "(BAR%d)\n", ci->conf_map.bar); goto failure_cleanup; } card->conf_addr = addr + ci->conf_map.offset; ci->reset_func(pdev); card->reset_func = ci->reset_func; /* Detect available channels */ for (i = 0; i < ci->channel_count; i++) { struct plx_pci_channel_map *cm = &ci->chan_map_tbl[i]; dev = alloc_sja1000dev(0); if (!dev) { err = -ENOMEM; goto failure_cleanup; } card->net_dev[i] = dev; priv = netdev_priv(dev); priv->priv = card; priv->irq_flags = IRQF_SHARED; dev->irq = pdev->irq; /* * Remap IO space of the SJA1000 chips * This is device-dependent mapping */ addr = pci_iomap(pdev, cm->bar, cm->size); if (!addr) { err = -ENOMEM; dev_err(&pdev->dev, "Failed to remap BAR%d\n", cm->bar); goto failure_cleanup; } priv->reg_base = addr + cm->offset; priv->read_reg = plx_pci_read_reg; priv->write_reg = plx_pci_write_reg; /* Check if channel is present */ if (plx_pci_check_sja1000(priv)) { priv->can.clock.freq = ci->can_clock; priv->ocr = ci->ocr; priv->cdr = ci->cdr; SET_NETDEV_DEV(dev, &pdev->dev); /* Register SJA1000 device */ err = register_sja1000dev(dev); if (err) { dev_err(&pdev->dev, "Registering device failed " "(err=%d)\n", err); free_sja1000dev(dev); goto failure_cleanup; } card->channels++; dev_info(&pdev->dev, "Channel #%d at 0x%p, irq %d " "registered as %s\n", i + 1, priv->reg_base, dev->irq, dev->name); } else { dev_err(&pdev->dev, "Channel #%d not detected\n", i + 1); free_sja1000dev(dev); } } if (!card->channels) { err = -ENODEV; goto failure_cleanup; } /* * Enable interrupts from PCI-card (PLX90xx) and enable Local_1, * Local_2 interrupts from the SJA1000 chips */ if (pdev->device != PCI_DEVICE_ID_PLX_9056) { val = ioread32(card->conf_addr + PLX_INTCSR); if (pdev->subsystem_vendor == PCI_VENDOR_ID_ESDGMBH) val |= PLX_LINT1_EN | PLX_PCI_INT_EN; else val |= PLX_LINT1_EN | PLX_LINT2_EN | PLX_PCI_INT_EN; iowrite32(val, card->conf_addr + PLX_INTCSR); } else { iowrite32(PLX9056_LINTI | PLX9056_PCI_INT_EN, card->conf_addr + PLX9056_INTCSR); } return 0; failure_cleanup: dev_err(&pdev->dev, "Error: %d. Cleaning Up.\n", err); plx_pci_del_card(pdev); return err; }
/* * Probe PCI device for EMS CAN signature and register each available * CAN channel to SJA1000 Socket-CAN subsystem. */ static int __devinit ems_pci_add_card(struct pci_dev *pdev, const struct pci_device_id *ent) { struct sja1000_priv *priv; struct net_device *dev; struct ems_pci_card *card; int max_chan, conf_size, base_bar; int err, i; /* Enabling PCI device */ if (pci_enable_device(pdev) < 0) { dev_err(&pdev->dev, "Enabling PCI device failed\n"); return -ENODEV; } /* Allocating card structures to hold addresses, ... */ card = kzalloc(sizeof(struct ems_pci_card), GFP_KERNEL); if (card == NULL) { dev_err(&pdev->dev, "Unable to allocate memory\n"); pci_disable_device(pdev); return -ENOMEM; } pci_set_drvdata(pdev, card); card->pci_dev = pdev; card->channels = 0; if (pdev->vendor == PCI_VENDOR_ID_PLX) { card->version = 2; /* CPC-PCI v2 */ max_chan = EMS_PCI_V2_MAX_CHAN; base_bar = EMS_PCI_V2_BASE_BAR; conf_size = EMS_PCI_V2_CONF_SIZE; } else { card->version = 1; /* CPC-PCI v1 */ max_chan = EMS_PCI_V1_MAX_CHAN; base_bar = EMS_PCI_V1_BASE_BAR; conf_size = EMS_PCI_V1_CONF_SIZE; } /* Remap configuration space and controller memory area */ card->conf_addr = pci_iomap(pdev, 0, conf_size); if (card->conf_addr == NULL) { err = -ENOMEM; goto failure_cleanup; } card->base_addr = pci_iomap(pdev, base_bar, EMS_PCI_BASE_SIZE); if (card->base_addr == NULL) { err = -ENOMEM; goto failure_cleanup; } if (card->version == 1) { /* Configure PITA-2 parallel interface (enable MUX) */ writel(PITA2_MISC_CONFIG, card->conf_addr + PITA2_MISC); /* Check for unique EMS CAN signature */ if (ems_pci_v1_readb(card, 0) != 0x55 || ems_pci_v1_readb(card, 1) != 0xAA || ems_pci_v1_readb(card, 2) != 0x01 || ems_pci_v1_readb(card, 3) != 0xCB || ems_pci_v1_readb(card, 4) != 0x11) { dev_err(&pdev->dev, "Not EMS Dr. Thomas Wuensche interface\n"); err = -ENODEV; goto failure_cleanup; } } ems_pci_card_reset(card); /* Detect available channels */ for (i = 0; i < max_chan; i++) { dev = alloc_sja1000dev(0); if (dev == NULL) { err = -ENOMEM; goto failure_cleanup; } card->net_dev[i] = dev; priv = netdev_priv(dev); priv->priv = card; priv->irq_flags = IRQF_SHARED; dev->irq = pdev->irq; priv->reg_base = card->base_addr + EMS_PCI_CAN_BASE_OFFSET + (i * EMS_PCI_CAN_CTRL_SIZE); if (card->version == 1) { priv->read_reg = ems_pci_v1_read_reg; priv->write_reg = ems_pci_v1_write_reg; priv->post_irq = ems_pci_v1_post_irq; } else { priv->read_reg = ems_pci_v2_read_reg; priv->write_reg = ems_pci_v2_write_reg; priv->post_irq = ems_pci_v2_post_irq; } /* Check if channel is present */ if (ems_pci_check_chan(priv)) { priv->can.clock.freq = EMS_PCI_CAN_CLOCK; priv->ocr = EMS_PCI_OCR; priv->cdr = EMS_PCI_CDR; SET_NETDEV_DEV(dev, &pdev->dev); if (card->version == 1) /* reset int flag of pita */ writel(PITA2_ICR_INT0_EN | PITA2_ICR_INT0, card->conf_addr + PITA2_ICR); else /* enable IRQ in PLX 9030 */ writel(PLX_ICSR_ENA_CLR, card->conf_addr + PLX_ICSR); /* Register SJA1000 device */ err = register_sja1000dev(dev); if (err) { dev_err(&pdev->dev, "Registering device failed " "(err=%d)\n", err); free_sja1000dev(dev); goto failure_cleanup; } card->channels++; dev_info(&pdev->dev, "Channel #%d at 0x%p, irq %d\n", i + 1, priv->reg_base, dev->irq); } else { free_sja1000dev(dev); } } return 0; failure_cleanup: dev_err(&pdev->dev, "Error: %d. Cleaning Up.\n", err); ems_pci_del_card(pdev); return err; }
static int sp_probe(struct platform_device *pdev) { int err; void __iomem *addr; struct net_device *dev; struct sja1000_priv *priv; struct resource *res_mem, *res_irq; struct sja1000_platform_data *pdata; pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "No platform data provided!\n"); err = -ENODEV; goto exit; } res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res_mem || !res_irq) { err = -ENODEV; goto exit; } if (!request_mem_region(res_mem->start, resource_size(res_mem), DRV_NAME)) { err = -EBUSY; goto exit; } addr = ioremap_nocache(res_mem->start, resource_size(res_mem)); if (!addr) { err = -ENOMEM; goto exit_release; } dev = alloc_sja1000dev(0); if (!dev) { err = -ENOMEM; goto exit_iounmap; } priv = netdev_priv(dev); dev->irq = res_irq->start; priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; priv->reg_base = addr; priv->read_reg = sp_read_reg; priv->write_reg = sp_write_reg; priv->can.clock.freq = pdata->clock; priv->ocr = pdata->ocr; priv->cdr = pdata->cdr; dev_set_drvdata(&pdev->dev, dev); SET_NETDEV_DEV(dev, &pdev->dev); err = register_sja1000dev(dev); if (err) { dev_err(&pdev->dev, "registering %s failed (err=%d)\n", DRV_NAME, err); goto exit_free; } dev_info(&pdev->dev, "%s device registered (reg_base=%p, irq=%d)\n", DRV_NAME, priv->reg_base, dev->irq); return 0; exit_free: free_sja1000dev(dev); exit_iounmap: iounmap(addr); exit_release: release_mem_region(res_mem->start, resource_size(res_mem)); exit: return err; }
static int pcan_add_channels(struct pcan_pccard *card) { struct pcmcia_device *pdev = card->pdev; int i, err = 0; u8 ccr = PCC_CCR_INIT; card->ccr = ~ccr; pcan_write_reg(card, PCC_CCR, ccr); mdelay(2); ccr &= ~PCC_CCR_RST_ALL; pcan_write_reg(card, PCC_CCR, ccr); for (i = 0; i < ARRAY_SIZE(card->channel); i++) { struct net_device *netdev; struct sja1000_priv *priv; netdev = alloc_sja1000dev(0); if (!netdev) { err = -ENOMEM; break; } priv = netdev_priv(netdev); priv->priv = card; SET_NETDEV_DEV(netdev, &pdev->dev); priv->irq_flags = IRQF_SHARED; netdev->irq = pdev->irq; priv->reg_base = card->ioport_addr + PCC_CHAN_OFF(i); if (!pcan_channel_present(priv)) { dev_err(&pdev->dev, "channel %d not present\n", i); free_sja1000dev(netdev); continue; } priv->read_reg = pcan_read_canreg; priv->write_reg = pcan_write_canreg; priv->can.clock.freq = PCC_CAN_CLOCK; priv->ocr = PCC_OCR; priv->cdr = PCC_CDR; if (i > 0) priv->cdr |= CDR_CLK_OFF; priv->flags |= SJA1000_CUSTOM_IRQ_HANDLER; err = register_sja1000dev(netdev); if (err) { free_sja1000dev(netdev); continue; } card->channel[i].netdev = netdev; card->chan_count++; ccr &= ~PCC_CCR_LED_OFF_CHAN(i); dev_info(&pdev->dev, "%s on channel %d at 0x%p irq %d\n", netdev->name, i, priv->reg_base, pdev->irq); } pcan_write_reg(card, PCC_CCR, ccr); return err; }
/* Probe for a TS-CAN1 board with JP2:JP1 jumper setting ID */ static int tscan1_probe(struct device *dev, unsigned id) { struct net_device *netdev; struct sja1000_priv *priv; unsigned long pld_base, sja1000_base; int irq, i; pld_base = TSCAN1_PLD_ADDRESS + id * TSCAN1_PLD_SIZE; if (!request_region(pld_base, TSCAN1_PLD_SIZE, dev_name(dev))) return -EBUSY; if (inb(pld_base + TSCAN1_ID1) != TSCAN1_ID1_VALUE || inb(pld_base + TSCAN1_ID2) != TSCAN1_ID2_VALUE) { release_region(pld_base, TSCAN1_PLD_SIZE); return -ENODEV; } switch (inb(pld_base + TSCAN1_JUMPERS) & (TSCAN1_JP4 | TSCAN1_JP5)) { case TSCAN1_JP4: irq = 6; break; case TSCAN1_JP5: irq = 7; break; case TSCAN1_JP4 | TSCAN1_JP5: irq = 5; break; default: dev_err(dev, "invalid JP4:JP5 setting (no IRQ)\n"); release_region(pld_base, TSCAN1_PLD_SIZE); return -EINVAL; } netdev = alloc_sja1000dev(0); if (!netdev) { release_region(pld_base, TSCAN1_PLD_SIZE); return -ENOMEM; } dev_set_drvdata(dev, netdev); SET_NETDEV_DEV(netdev, dev); netdev->base_addr = pld_base; netdev->irq = irq; priv = netdev_priv(netdev); priv->read_reg = tscan1_read; priv->write_reg = tscan1_write; priv->can.clock.freq = TSCAN1_SJA1000_XTAL / 2; priv->cdr = CDR_CBP | CDR_CLK_OFF; priv->ocr = OCR_TX0_PUSHPULL; /* Select the first SJA1000 IO address that is free and that works */ for (i = 0; i < ARRAY_SIZE(tscan1_sja1000_addresses); i++) { sja1000_base = tscan1_sja1000_addresses[i]; if (!request_region(sja1000_base, TSCAN1_SJA1000_SIZE, dev_name(dev))) continue; /* Set SJA1000 IO base address and enable it */ outb(TSCAN1_MODE_ENABLE | i, pld_base + TSCAN1_MODE); priv->reg_base = (void __iomem *)sja1000_base; if (!register_sja1000dev(netdev)) { /* SJA1000 probe succeeded; turn LED off and return */ outb(0, pld_base + TSCAN1_LED); netdev_info(netdev, "TS-CAN1 at 0x%lx 0x%lx irq %d\n", pld_base, sja1000_base, irq); return 0; } /* SJA1000 probe failed; release and try next address */ outb(0, pld_base + TSCAN1_MODE); release_region(sja1000_base, TSCAN1_SJA1000_SIZE); } dev_err(dev, "failed to assign SJA1000 IO address\n"); dev_set_drvdata(dev, NULL); free_sja1000dev(netdev); release_region(pld_base, TSCAN1_PLD_SIZE); return -ENXIO; }
static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct sja1000_priv *priv; struct peak_pci_chan *chan; struct net_device *dev, *prev_dev; void __iomem *cfg_base, *reg_base; u16 sub_sys_id, icr; int i, err, channels; err = pci_enable_device(pdev); if (err) return err; err = pci_request_regions(pdev, DRV_NAME); if (err) goto failure_disable_pci; err = pci_read_config_word(pdev, 0x2e, &sub_sys_id); if (err) goto failure_release_regions; dev_dbg(&pdev->dev, "probing device %04x:%04x:%04x\n", pdev->vendor, pdev->device, sub_sys_id); err = pci_write_config_word(pdev, 0x44, 0); if (err) goto failure_release_regions; if (sub_sys_id >= 12) channels = 4; else if (sub_sys_id >= 10) channels = 3; else if (sub_sys_id >= 4) channels = 2; else channels = 1; cfg_base = pci_iomap(pdev, 0, PEAK_PCI_CFG_SIZE); if (!cfg_base) { dev_err(&pdev->dev, "failed to map PCI resource #0\n"); err = -ENOMEM; goto failure_release_regions; } reg_base = pci_iomap(pdev, 1, PEAK_PCI_CHAN_SIZE * channels); if (!reg_base) { dev_err(&pdev->dev, "failed to map PCI resource #1\n"); err = -ENOMEM; goto failure_unmap_cfg_base; } /* Set GPIO control register */ writew(0x0005, cfg_base + PITA_GPIOICR + 2); /* Enable all channels of this card */ writeb(0x00, cfg_base + PITA_GPIOICR); /* Toggle reset */ writeb(0x05, cfg_base + PITA_MISC + 3); mdelay(5); /* Leave parport mux mode */ writeb(0x04, cfg_base + PITA_MISC + 3); icr = readw(cfg_base + PITA_ICR + 2); for (i = 0; i < channels; i++) { dev = alloc_sja1000dev(sizeof(struct peak_pci_chan)); if (!dev) { err = -ENOMEM; goto failure_remove_channels; } priv = netdev_priv(dev); chan = priv->priv; chan->cfg_base = cfg_base; priv->reg_base = reg_base + i * PEAK_PCI_CHAN_SIZE; priv->read_reg = peak_pci_read_reg; priv->write_reg = peak_pci_write_reg; priv->post_irq = peak_pci_post_irq; priv->can.clock.freq = PEAK_PCI_CAN_CLOCK; priv->ocr = PEAK_PCI_OCR; priv->cdr = PEAK_PCI_CDR; /* Neither a slave nor a single device distributes the clock */ if (channels == 1 || i > 0) priv->cdr |= CDR_CLK_OFF; /* Setup interrupt handling */ priv->irq_flags = IRQF_SHARED; dev->irq = pdev->irq; chan->icr_mask = peak_pci_icr_masks[i]; icr |= chan->icr_mask; SET_NETDEV_DEV(dev, &pdev->dev); dev->dev_id = i; /* Create chain of SJA1000 devices */ chan->prev_dev = pci_get_drvdata(pdev); pci_set_drvdata(pdev, dev); /* * PCAN-ExpressCard needs some additional i2c init. * This must be done *before* register_sja1000dev() but * *after* devices linkage */ if (pdev->device == PEAK_PCIEC_DEVICE_ID || pdev->device == PEAK_PCIEC34_DEVICE_ID) { err = peak_pciec_probe(pdev, dev); if (err) { dev_err(&pdev->dev, "failed to probe device (err %d)\n", err); goto failure_free_dev; } } err = register_sja1000dev(dev); if (err) { dev_err(&pdev->dev, "failed to register device\n"); goto failure_free_dev; } dev_info(&pdev->dev, "%s at reg_base=0x%p cfg_base=0x%p irq=%d\n", dev->name, priv->reg_base, chan->cfg_base, dev->irq); } /* Enable interrupts */ writew(icr, cfg_base + PITA_ICR + 2); return 0; failure_free_dev: pci_set_drvdata(pdev, chan->prev_dev); free_sja1000dev(dev); failure_remove_channels: /* Disable interrupts */ writew(0x0, cfg_base + PITA_ICR + 2); chan = NULL; for (dev = pci_get_drvdata(pdev); dev; dev = prev_dev) { priv = netdev_priv(dev); chan = priv->priv; prev_dev = chan->prev_dev; unregister_sja1000dev(dev); free_sja1000dev(dev); } /* free any PCIeC resources too */ if (chan && chan->pciec_card) peak_pciec_remove(chan->pciec_card); pci_iounmap(pdev, reg_base); failure_unmap_cfg_base: pci_iounmap(pdev, cfg_base); failure_release_regions: pci_release_regions(pdev); failure_disable_pci: pci_disable_device(pdev); return err; }