static int bcma_gpio_irq_init(struct bcma_drv_cc *cc) { struct gpio_chip *chip = &cc->gpio; int hwirq, err; if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) return 0; hwirq = bcma_core_irq(cc->core, 0); err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio", cc); if (err) return err; bcma_chipco_gpio_intmask(cc, ~0, 0); bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO); err = gpiochip_irqchip_add(chip, &bcma_gpio_irq_chip, 0, handle_simple_irq, IRQ_TYPE_NONE); if (err) { free_irq(hwirq, cc); return err; } return 0; }
static void bcma_gpio_irq_exit(struct bcma_drv_cc *cc) { if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) return; bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO); free_irq(bcma_core_irq(cc->core, 0), cc); }
/* PCI device IRQ mapping. */ int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev) { struct bcma_drv_pci_host *pc_host; if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { /* This is not a device on the PCI-core bridge. */ return -ENODEV; } pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host, pci_ops); return bcma_core_irq(pc_host->pdev->core); }
static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc) { struct gpio_chip *chip = &cc->gpio; int gpio; if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) return; bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO); free_irq(bcma_core_irq(cc->core, 0), cc); for (gpio = 0; gpio < chip->ngpio; gpio++) { int irq = irq_find_mapping(cc->irq_domain, gpio); irq_dispose_mapping(irq); } irq_domain_remove(cc->irq_domain); }
static void bcma_chipco_serial_init(struct bcma_drv_cc *cc) { #if IS_BUILTIN(CONFIG_BCM47XX) unsigned int irq; u32 baud_base; u32 i; unsigned int ccrev = cc->core->id.rev; struct bcma_serial_port *ports = cc->serial_ports; if (ccrev >= 11 && ccrev != 15) { baud_base = bcma_chipco_get_alp_clock(cc); if (ccrev >= 21) { /* Turn off UART clock before switching clocksource. */ bcma_cc_write32(cc, BCMA_CC_CORECTL, bcma_cc_read32(cc, BCMA_CC_CORECTL) & ~BCMA_CC_CORECTL_UARTCLKEN); } /* Set the override bit so we don't divide it */ bcma_cc_write32(cc, BCMA_CC_CORECTL, bcma_cc_read32(cc, BCMA_CC_CORECTL) | BCMA_CC_CORECTL_UARTCLK0); if (ccrev >= 21) { /* Re-enable the UART clock. */ bcma_cc_write32(cc, BCMA_CC_CORECTL, bcma_cc_read32(cc, BCMA_CC_CORECTL) | BCMA_CC_CORECTL_UARTCLKEN); } } else { bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n", ccrev); return; } irq = bcma_core_irq(cc->core, 0); /* Determine the registers of the UARTs */ cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART); for (i = 0; i < cc->nr_serial_ports; i++) { ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA + (i * 256); ports[i].irq = irq; ports[i].baud_base = baud_base; ports[i].reg_shift = 0; } #endif /* CONFIG_BCM47XX */ }
/* This function is called when doing a pci_enable_device(). * We must first check if the device is a device on the PCI-core bridge. */ int bcma_core_pci_plat_dev_init(struct pci_dev *dev) { struct bcma_drv_pci_host *pc_host; if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { /* This is not a device on the PCI-core bridge. */ return -ENODEV; } pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host, pci_ops); pr_info("PCI: Fixing up device %s\n", pci_name(dev)); /* Fix up interrupt lines */ dev->irq = bcma_core_irq(pc_host->pdev->core); pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); return 0; }
static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc) { struct gpio_chip *chip = &cc->gpio; int gpio, hwirq, err; if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) return 0; cc->irq_domain = irq_domain_add_linear(NULL, chip->ngpio, &irq_domain_simple_ops, cc); if (!cc->irq_domain) { err = -ENODEV; goto err_irq_domain; } for (gpio = 0; gpio < chip->ngpio; gpio++) { int irq = irq_create_mapping(cc->irq_domain, gpio); irq_set_chip_data(irq, cc); irq_set_chip_and_handler(irq, &bcma_gpio_irq_chip, handle_simple_irq); } hwirq = bcma_core_irq(cc->core, 0); err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio", cc); if (err) goto err_req_irq; bcma_chipco_gpio_intmask(cc, ~0, 0); bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO); return 0; err_req_irq: for (gpio = 0; gpio < chip->ngpio; gpio++) { int irq = irq_find_mapping(cc->irq_domain, gpio); irq_dispose_mapping(irq); } irq_domain_remove(cc->irq_domain); err_irq_domain: return err; }