コード例 #1
0
ファイル: mcip.c プロジェクト: 343829084/linux-study
static int __init
idu_of_init(struct device_node *intc, struct device_node *parent)
{
	struct irq_domain *domain;
	/* Read IDU BCR to confirm nr_irqs */
	int nr_irqs = of_irq_count(intc);
	int i, irq;

	if (!idu_detected)
		panic("IDU not detected, but DeviceTree using it");

	pr_info("MCIP: IDU referenced from Devicetree %d irqs\n", nr_irqs);

	domain = irq_domain_add_linear(intc, nr_irqs, &idu_irq_ops, NULL);

	/* Parent interrupts (core-intc) are already mapped */

	for (i = 0; i < nr_irqs; i++) {
		/*
		 * Return parent uplink IRQs (towards core intc) 24,25,.....
		 * this step has been done before already
		 * however we need it to get the parent virq and set IDU handler
		 * as first level isr
		 */
		irq = irq_of_parse_and_map(intc, i);
		if (!i)
			idu_first_irq = irq;

		irq_set_chained_handler_and_data(irq, idu_cascade_isr, domain);
	}

	__mcip_cmd(CMD_IDU_ENABLE, 0);

	return 0;
}
コード例 #2
0
ファイル: irq.c プロジェクト: mozzwald/linux-2.6
int __init vt8500_irq_init(struct device_node *node, struct device_node *parent)
{
    struct irq_domain *vt8500_irq_domain;
    struct vt8500_irq_priv *priv;
    int irq, i;
    struct device_node *np = node;

    priv = kzalloc(sizeof(struct vt8500_irq_priv), GFP_KERNEL);
    priv->base = of_iomap(np, 0);

    vt8500_irq_domain = irq_domain_add_legacy(node, 64, irq_cnt, 0,
                        &vt8500_irq_domain_ops, priv);
    if (!vt8500_irq_domain)
        pr_err("%s: Unable to add wmt irq domain!\n", __func__);

    irq_set_default_host(vt8500_irq_domain);

    vt8500_init_irq_hw(priv->base);

    pr_info("Added IRQ Controller @ %x [virq_base = %d]\n",
            (u32)(priv->base), irq_cnt);

    /* check if this is a slaved controller */
    if (of_irq_count(np) != 0) {
        /* check that we have the correct number of interrupts */
        if (of_irq_count(np) != 8) {
            pr_err("%s: Incorrect IRQ map for slave controller\n",
                   __func__);
            return -EINVAL;
        }

        for (i = 0; i < 8; i++) {
            irq = irq_of_parse_and_map(np, i);
            enable_irq(irq);
        }

        pr_info("vt8500-irq: Enabled slave->parent interrupts\n");
    }

    irq_cnt += 64;

    return 0;
}
コード例 #3
0
/**
 * of_device_alloc - Allocate and initialize an of_device
 * @np: device node to assign to device
 * @bus_id: Name to assign to the device.  May be null to use default name.
 * @parent: Parent device.
 */
struct platform_device *of_device_alloc(struct device_node *np,
				  const char *bus_id,
				  struct device *parent)
{
	struct platform_device *dev;
	int rc, i, num_reg = 0, num_irq;
	struct resource *res, temp_res;

	dev = platform_device_alloc("", -1);
	if (!dev)
		return NULL;

	/* count the io and irq resources */
	if (of_can_translate_address(np))
		while (of_address_to_resource(np, num_reg, &temp_res) == 0)
			num_reg++;
	num_irq = of_irq_count(np);

	/* Populate the resource table */
	if (num_irq || num_reg) {
		res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
		if (!res) {
			platform_device_put(dev);
			return NULL;
		}

		dev->num_resources = num_reg + num_irq;
		dev->resource = res;
		for (i = 0; i < num_reg; i++, res++) {
			rc = of_address_to_resource(np, i, res);
			WARN_ON(rc);
		}
		WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq);
	}

	dev->dev.of_node = of_node_get(np);
#if defined(CONFIG_MICROBLAZE)
	dev->dev.dma_mask = &dev->archdata.dma_mask;
#endif
	dev->dev.parent = parent;

	if (bus_id)
		dev_set_name(&dev->dev, "%s", bus_id);
	else
		of_device_make_bus_id(&dev->dev);

	return dev;
}
コード例 #4
0
ファイル: platform.c プロジェクト: mhei/linux
/**
 * of_device_alloc - Allocate and initialize an of_device
 * @np: device node to assign to device
 * @bus_id: Name to assign to the device.  May be null to use default name.
 * @parent: Parent device.
 */
struct platform_device *of_device_alloc(struct device_node *np,
                                        const char *bus_id,
                                        struct device *parent)
{
    struct platform_device *dev;
    int rc, i, num_reg = 0, num_irq;
    struct resource *res, temp_res;

    dev = platform_device_alloc("", -1);
    if (!dev)
        return NULL;

    /* count the io and irq resources */
    while (of_address_to_resource(np, num_reg, &temp_res) == 0)
        num_reg++;
    num_irq = of_irq_count(np);

    /* Populate the resource table */
    if (num_irq || num_reg) {
        res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
        if (!res) {
            platform_device_put(dev);
            return NULL;
        }

        dev->num_resources = num_reg + num_irq;
        dev->resource = res;
        for (i = 0; i < num_reg; i++, res++) {
            rc = of_address_to_resource(np, i, res);
            WARN_ON(rc);
        }
        if (of_irq_to_resource_table(np, res, num_irq) != num_irq)
            pr_debug("not all legacy IRQ resources mapped for %s\n",
                     np->name);
    }

    dev->dev.of_node = of_node_get(np);
    dev->dev.fwnode = &np->fwnode;
    dev->dev.parent = parent ? : &platform_bus;

    if (bus_id)
        dev_set_name(&dev->dev, "%s", bus_id);
    else
        of_device_make_bus_id(&dev->dev);

    return dev;
}
コード例 #5
0
ファイル: irq.c プロジェクト: 4oh4ed/linux
int __init icu_of_init(struct device_node *node, struct device_node *parent)
{
	struct device_node *eiu_node;
	struct resource res;
	int i, ret;

	for (i = 0; i < MAX_IM; i++) {
		if (of_address_to_resource(node, i, &res))
			panic("Failed to get icu memory range");

		if (request_mem_region(res.start, resource_size(&res),
					res.name) < 0)
			pr_err("Failed to request icu memory");

		ltq_icu_membase[i] = ioremap_nocache(res.start,
					resource_size(&res));
		if (!ltq_icu_membase[i])
			panic("Failed to remap icu memory");
	}

	/* the external interrupts are optional and xway only */
	eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway");
	if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
		/* find out how many external irq sources we have */
		exin_avail = of_irq_count(eiu_node);

		if (exin_avail > MAX_EIU)
			exin_avail = MAX_EIU;

		ret = of_irq_to_resource_table(eiu_node,
						ltq_eiu_irq, exin_avail);
		if (ret != exin_avail)
			panic("failed to load external irq resources");

		if (request_mem_region(res.start, resource_size(&res),
							res.name) < 0)
			pr_err("Failed to request eiu memory");

		ltq_eiu_membase = ioremap_nocache(res.start,
							resource_size(&res));
		if (!ltq_eiu_membase)
			panic("Failed to remap eiu memory");
	}

	/* turn off all irqs by default */
	for (i = 0; i < MAX_IM; i++) {
		/* make sure all irqs are turned off by default */
		ltq_icu_w32(i, 0, LTQ_ICU_IM0_IER);
		/* clear all possibly pending interrupts */
		ltq_icu_w32(i, ~0, LTQ_ICU_IM0_ISR);
	}

	mips_cpu_irq_init();

	for (i = 0; i < MAX_IM; i++)
		setup_irq(i + 2, &cascade);

	if (cpu_has_vint) {
		pr_info("Setting up vectored interrupts\n");
		set_vi_handler(2, ltq_hw0_irqdispatch);
		set_vi_handler(3, ltq_hw1_irqdispatch);
		set_vi_handler(4, ltq_hw2_irqdispatch);
		set_vi_handler(5, ltq_hw3_irqdispatch);
		set_vi_handler(6, ltq_hw4_irqdispatch);
		set_vi_handler(7, ltq_hw5_irqdispatch);
	}

	ltq_domain = irq_domain_add_linear(node,
		(MAX_IM * INT_NUM_IM_OFFSET) + MIPS_CPU_IRQ_CASCADE,
		&irq_domain_ops, 0);

#if defined(CONFIG_MIPS_MT_SMP)
	if (cpu_has_vint) {
		pr_info("Setting up IPI vectored interrupts\n");
		set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ltq_sw0_irqdispatch);
		set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ltq_sw1_irqdispatch);
	}
	arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ,
		&irq_resched);
	arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ, &irq_call);
#endif

#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
	set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
		IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
#else
	set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
		IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
#endif

	/* tell oprofile which irq to use */
	cp0_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ);

	/*
	 * if the timer irq is not one of the mips irqs we need to
	 * create a mapping
	 */
	if (MIPS_CPU_TIMER_IRQ != 7)
		irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ);

	return 0;
}
コード例 #6
0
ファイル: irq-tb10x.c プロジェクト: 03199618/linux
static int __init of_tb10x_init_irq(struct device_node *ictl,
					struct device_node *parent)
{
	int i, ret, nrirqs = of_irq_count(ictl);
	struct resource mem;
	struct irq_chip_generic *gc;
	struct irq_domain *domain;
	void __iomem *reg_base;

	if (of_address_to_resource(ictl, 0, &mem)) {
		pr_err("%s: No registers declared in DeviceTree.\n",
			ictl->name);
		return -EINVAL;
	}

	if (!request_mem_region(mem.start, resource_size(&mem),
		ictl->name)) {
		pr_err("%s: Request mem region failed.\n", ictl->name);
		return -EBUSY;
	}

	reg_base = ioremap(mem.start, resource_size(&mem));
	if (!reg_base) {
		ret = -EBUSY;
		pr_err("%s: ioremap failed.\n", ictl->name);
		goto ioremap_fail;
	}

	domain = irq_domain_add_linear(ictl, AB_IRQCTL_MAXIRQ,
					&irq_generic_chip_ops, NULL);
	if (!domain) {
		ret = -ENOMEM;
		pr_err("%s: Could not register interrupt domain.\n",
			ictl->name);
		goto irq_domain_add_fail;
	}

	ret = irq_alloc_domain_generic_chips(domain, AB_IRQCTL_MAXIRQ,
				2, ictl->name, handle_level_irq,
				IRQ_NOREQUEST, IRQ_NOPROBE,
				IRQ_GC_INIT_MASK_CACHE);
	if (ret) {
		pr_err("%s: Could not allocate generic interrupt chip.\n",
			ictl->name);
		goto gc_alloc_fail;
	}

	gc = domain->gc->gc[0];
	gc->reg_base                         = reg_base;

	gc->chip_types[0].type               = IRQ_TYPE_LEVEL_MASK;
	gc->chip_types[0].chip.irq_mask      = irq_gc_mask_clr_bit;
	gc->chip_types[0].chip.irq_unmask    = irq_gc_mask_set_bit;
	gc->chip_types[0].chip.irq_set_type  = tb10x_irq_set_type;
	gc->chip_types[0].regs.mask          = AB_IRQCTL_INT_ENABLE;

	gc->chip_types[1].type               = IRQ_TYPE_EDGE_BOTH;
	gc->chip_types[1].chip.name          = gc->chip_types[0].chip.name;
	gc->chip_types[1].chip.irq_ack       = irq_gc_ack_set_bit;
	gc->chip_types[1].chip.irq_mask      = irq_gc_mask_clr_bit;
	gc->chip_types[1].chip.irq_unmask    = irq_gc_mask_set_bit;
	gc->chip_types[1].chip.irq_set_type  = tb10x_irq_set_type;
	gc->chip_types[1].regs.ack           = AB_IRQCTL_INT_STATUS;
	gc->chip_types[1].regs.mask          = AB_IRQCTL_INT_ENABLE;
	gc->chip_types[1].handler            = handle_edge_irq;

	for (i = 0; i < nrirqs; i++) {
		unsigned int irq = irq_of_parse_and_map(ictl, i);

		irq_set_handler_data(irq, domain);
		irq_set_chained_handler(irq, tb10x_irq_cascade);
	}

	ab_irqctl_writereg(gc, AB_IRQCTL_INT_ENABLE, 0);
	ab_irqctl_writereg(gc, AB_IRQCTL_INT_MODE, 0);
	ab_irqctl_writereg(gc, AB_IRQCTL_INT_POLARITY, 0);
	ab_irqctl_writereg(gc, AB_IRQCTL_INT_STATUS, ~0UL);

	return 0;

gc_alloc_fail:
	irq_domain_remove(domain);
irq_domain_add_fail:
	iounmap(reg_base);
ioremap_fail:
	release_mem_region(mem.start, resource_size(&mem));
	return ret;
}