/* * 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 irqreturn_t pcan_isr(int irq, void *dev_id) { struct pcan_pccard *card = dev_id; int irq_handled; for (irq_handled = 0; irq_handled < PCC_ISR_MAX_LOOP; irq_handled++) { int nothing_to_handle = 1; int i; for (i = 0; i < card->chan_count; i++) { struct net_device *netdev; if (!pcan_pccard_present(card)) { return IRQ_NONE; } netdev = card->channel[i].netdev; if (netdev && sja1000_interrupt(irq, netdev) == IRQ_HANDLED) nothing_to_handle = 0; } if (nothing_to_handle) break; } return (irq_handled) ? IRQ_HANDLED : IRQ_NONE; }
/* * interrupt service routine */ static irqreturn_t pcan_isr(int irq, void *dev_id) { struct pcan_pccard *card = dev_id; int irq_handled; /* prevent from infinite loop */ for (irq_handled = 0; irq_handled < PCC_ISR_MAX_LOOP; irq_handled++) { /* handle shared interrupt and next loop */ int nothing_to_handle = 1; int i; /* check interrupt for each channel */ for (i = 0; i < card->chan_count; i++) { struct net_device *netdev; /* * check whether the card is present before calling * sja1000_interrupt() to speed up hotplug detection */ if (!pcan_pccard_present(card)) { /* card unplugged during isr */ return IRQ_NONE; } /* * should check whether all or SJA1000_MAX_IRQ * interrupts have been handled: loop again to be sure. */ netdev = card->channel[i].netdev; if (netdev && sja1000_interrupt(irq, netdev) == IRQ_HANDLED) nothing_to_handle = 0; } if (nothing_to_handle) break; } return (irq_handled) ? IRQ_HANDLED : IRQ_NONE; }