Пример #1
0
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;
}
Пример #2
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);
}
Пример #3
0
/* 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);
}
Пример #4
0
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);
}
Пример #5
0
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 */
}
Пример #6
0
/* 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;
}
Пример #7
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;
}