Example #1
0
static void __init mpic_init_IRQ(void)
{
	struct device_node *dn;
	struct mpic *mpic;
	unsigned int virq;

	for (dn = NULL;
	     (dn = of_find_node_by_name(dn, "interrupt-controller"));) {
		if (!device_is_compatible(dn, "CBEA,platform-open-pic"))
			continue;

		/* The MPIC driver will get everything it needs from the
		 * device-tree, just pass 0 to all arguments
		 */
		mpic = mpic_alloc(dn, 0, 0, 0, 0, " MPIC     ");
		if (mpic == NULL)
			continue;
		mpic_init(mpic);

		virq = irq_of_parse_and_map(dn, 0);
		if (virq == NO_IRQ)
			continue;

		printk(KERN_INFO "%s : hooking up to IRQ %d\n",
		       dn->full_name, virq);
		set_irq_data(virq, mpic);
		set_irq_chained_handler(virq, cell_mpic_cascade);
	}
}
Example #2
0
/* call this from board-specific init_irq */
void __init at91_gpio_irq_setup(unsigned banks)
{
	unsigned	pioc, pin, id;

	if (banks > 4)
		banks = 4;
	for (pioc = 0, pin = PIN_BASE, id = AT91C_ID_PIOA;
			pioc < banks;
			pioc++, id++) {
		struct pio_controller __iomem	*controller;
		unsigned			i;

		controller = (void __force __iomem *) pio_virt[pioc];
		__raw_writel(~0, &controller->idr);

		set_irq_data(id, (void *) pin);
		set_irq_chipdata(id, (void __force *) controller);

		for (i = 0; i < 32; i++, pin++) {
			set_irq_chip(pin, &gpio_irqchip);
			set_irq_handler(pin, do_simple_IRQ);
			set_irq_flags(pin, IRQF_VALID);
		}

		set_irq_chained_handler(id, gpio_irq_handler);

		/* enable the PIO peripheral clock */
		AT91_SYS->PMC_PCER = 1 << id;
	}
	pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, banks);
}
Example #3
0
static void __init ilc_demux_init(struct platform_device *pdev)
{
	struct ilc *ilc = platform_get_drvdata(pdev);
	int irq;
	int i;

	/* Default all interrupts to active high. */
	for (i = 0, irq = ilc->first_irq; i < ilc->inputs_num; i++, irq++) {
		ILC_SET_TRIGMODE(ilc->base, i, ILC_TRIGGERMODE_HIGH);

		/* SIM: Should we do the masking etc in ilc_irq_demux and
		 * then change this to handle_simple_irq? */
		set_irq_chip_and_handler_name(irq, &ilc_chip,
				handle_level_irq, ilc->name);
		set_irq_chip_data(irq, ilc);
	}

	i = 0;
	irq = platform_get_irq(pdev, i++);
	while (irq >= 0) {
		set_irq_chip_and_handler(irq, &dummy_irq_chip, ilc_irq_demux);
		set_irq_data(irq, ilc);
		irq = platform_get_irq(pdev, i++);
	}

	return;
}
Example #4
0
void __init syncpt_init_irq(void)
{
	void __iomem *sync_regs;
	unsigned int i;

	sync_regs = ioremap(TEGRA_HOST1X_BASE + HOST1X_SYNC_OFFSET,
			HOST1X_SYNC_SIZE);
	BUG_ON(!sync_regs);

	writel(0xffffffffUL,
		sync_regs + HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE);
	writel(0xffffffffUL,
		sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS);

	for (i = INT_SYNCPT_THRESH_BASE; i < INT_GPIO_BASE; i++) {
		set_irq_chip(i, &syncpt_thresh_irq);
		set_irq_chip_data(i, sync_regs);
		set_irq_handler(i, handle_simple_irq);
		set_irq_flags(i, IRQF_VALID);
	}
	if (set_irq_data(INT_HOST1X_MPCORE_SYNCPT, sync_regs))
		BUG();
	set_irq_chained_handler(INT_HOST1X_MPCORE_SYNCPT,
				syncpt_thresh_cascade);
}
Example #5
0
File: gpio.c Project: ivucica/linux
/*
 * Called from the processor-specific init to enable GPIO interrupt support.
 */
void __init at91_gpio_irq_setup(void)
{
	unsigned	pioc, pin;

	for (pioc = 0, pin = PIN_BASE;
			pioc < gpio_banks;
			pioc++) {
		void __iomem	*controller;
		unsigned	id = gpio[pioc].id;
		unsigned	i;

		clk_enable(gpio[pioc].clock);	/* enable PIO controller's clock */

		controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset;
		__raw_writel(~0, controller + PIO_IDR);

		set_irq_data(id, (void *) pin);
		set_irq_chip_data(id, controller);

		for (i = 0; i < 32; i++, pin++) {
			/*
			 * Can use the "simple" and not "edge" handler since it's
			 * shorter, and the AIC handles interupts sanely.
			 */
			set_irq_chip(pin, &gpio_irqchip);
			set_irq_handler(pin, handle_simple_irq);
			set_irq_flags(pin, IRQF_VALID);
		}

		set_irq_chained_handler(id, gpio_irq_handler);
	}
	pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks);
}
Example #6
0
File: gpio.c Project: E-LLP/n900
int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
{
	int i, j;

	/* save for local usage */
	mxc_gpio_ports = port;
	gpio_table_size = cnt;

	printk(KERN_INFO "MXC GPIO hardware\n");

	for (i = 0; i < cnt; i++) {
		/* disable the interrupt and clear the status */
		__raw_writel(0, port[i].base + GPIO_IMR);
		__raw_writel(~0, port[i].base + GPIO_ISR);
		for (j = port[i].virtual_irq_start;
			j < port[i].virtual_irq_start + 32; j++) {
			set_irq_chip(j, &gpio_irq_chip);
			set_irq_handler(j, handle_edge_irq);
			set_irq_flags(j, IRQF_VALID);
		}

		/* register gpio chip */
		port[i].chip.direction_input = mxc_gpio_direction_input;
		port[i].chip.direction_output = mxc_gpio_direction_output;
		port[i].chip.get = mxc_gpio_get;
		port[i].chip.set = mxc_gpio_set;
		port[i].chip.base = i * 32;
		port[i].chip.ngpio = 32;

		/* its a serious configuration bug when it fails */
		BUG_ON( gpiochip_add(&port[i].chip) < 0 );

#ifdef CONFIG_ARCH_MX3
		/* setup one handler for each entry */
		set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler);
		set_irq_data(port[i].irq, &port[i]);
#endif
	}

#ifdef CONFIG_ARCH_MX2
	/* setup one handler for all GPIO interrupts */
	set_irq_chained_handler(port[0].irq, mx2_gpio_irq_handler);
	set_irq_data(port[0].irq, port);
#endif
	return 0;
}
Example #7
0
void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
{
    if (gic_nr >= MAX_GIC_NR)
        BUG();
    if (set_irq_data(irq, &gic_data[gic_nr]) != 0)
        BUG();
    set_irq_chained_handler(irq, gic_handle_cascade_irq);
}
Example #8
0
static int __init _mxc_gpio_init(void)
{
	int i;
	struct gpio_port *port;

	initialized = 1;

	printk(KERN_INFO "MXC GPIO hardware\n");

	for (i = 0; i < GPIO_PORT_NUM; i++) {
		int j, gpio_count = GPIO_NUM_PIN;

		port = &gpio_port[i];
		port->base = mxc_gpio_ports[i].base;
		port->num = mxc_gpio_ports[i].num;
		port->irq = mxc_gpio_ports[i].irq;
		port->virtual_irq_start = mxc_gpio_ports[i].virtual_irq_start;

		port->reserved_map = 0;
		spin_lock_init(&port->lock);

		/* disable the interrupt and clear the status */
		__raw_writel(0, port->base + GPIO_IMR);
		__raw_writel(0xFFFFFFFF, port->base + GPIO_ISR);
		for (j = port->virtual_irq_start;
		     j < port->virtual_irq_start + gpio_count; j++) {
			set_irq_chip(j, &gpio_irq_chip);
			set_irq_handler(j, do_edge_IRQ);
			set_irq_flags(j, IRQF_VALID);
		}
#ifndef MXC_MUX_GPIO_INTERRUPTS
		set_irq_chained_handler(port->irq, mxc_gpio_irq_handler);
		set_irq_data(port->irq, port);
#endif
	}

#ifdef MXC_MUX_GPIO_INTERRUPTS
	set_irq_chained_handler(port->irq, mxc_gpio_mux_irq_handler);
	set_irq_data(mxc_gpio_ports[0].irq, gpio_port);
#endif

	return 0;
}
Example #9
0
void __init sh7372_init_irq(void)
{
	void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);

	register_intc_controller(&intca_desc);
	register_intc_controller(&intcs_desc);

	/* demux using INTEVTSA */
	set_irq_data(evt2irq(0xf80), (void *)intevtsa);
	set_irq_chained_handler(evt2irq(0xf80), intcs_demux);
}
Example #10
0
static int __devinit stm_gpio_probe(struct platform_device *pdev)
{
	int port_no = pdev->id;
	struct stm_gpio_port *port = &stm_gpio_ports[port_no];
	struct resource *memory;
	int irq;

	BUG_ON(port_no < 0);
	BUG_ON(port_no >= stm_gpio_num);

	memory = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!memory)
		return -EINVAL;

	if (!request_mem_region(memory->start,
			memory->end - memory->start + 1, pdev->name))
		return -EBUSY;

	irq = platform_get_irq(pdev, 0);
	if (irq >= 0) {
		set_irq_chained_handler(irq, stm_gpio_irq_handler);
		set_irq_data(irq, &stm_gpio_ports[port_no]);

		if (stm_gpio_irq_init(port_no) != 0) {
			printk(KERN_ERR "stm_gpio: Failed to init gpio "
					"interrupt!\n");
			return -EINVAL;
		}
	}

	port->gpio_chip.label = dev_name(&pdev->dev);
	dev_set_drvdata(&pdev->dev, port);

	return 0;

	/* This is a good time to check consistency of linux/stm/gpio.h
	 * declarations with the proper source... */
	BUG_ON(STM_GPIO_REG_SET_POUT != offset__PIO_SET_POUT());
	BUG_ON(STM_GPIO_REG_CLR_POUT != offset__PIO_CLR_POUT());
	BUG_ON(STM_GPIO_REG_PIN != offset__PIO_PIN());
	BUG_ON(STM_GPIO_DIRECTION_BIDIR != value__PIO_PCx__BIDIR_OPEN_DRAIN());
	BUG_ON(STM_GPIO_DIRECTION_OUT != value__PIO_PCx__OUTPUT_PUSH_PULL());
	BUG_ON(STM_GPIO_DIRECTION_IN != value__PIO_PCx__INPUT_HIGH_IMPEDANCE());
	BUG_ON(STM_GPIO_DIRECTION_ALT_OUT !=
			value__PIO_PCx__ALTERNATIVE_OUTPUT_PUSH_PULL());
	BUG_ON(STM_GPIO_DIRECTION_ALT_BIDIR !=
			value__PIO_PCx__ALTERNATIVE_BIDIR_OPEN_DRAIN());

	return 0;
}
Example #11
0
static int __devinit stm_gpio_irqmux_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct stm_plat_pio_irqmux_data *plat_data = dev->platform_data;
	struct stm_gpio_irqmux *irqmux;
	struct resource *memory;
	int irq;
	int port_no;

	BUG_ON(!plat_data);

	irqmux = devm_kzalloc(dev, sizeof(*irqmux), GFP_KERNEL);
	if (!irqmux)
		return -ENOMEM;

	memory = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(pdev, 0);
	if (!memory || irq < 0)
		return -EINVAL;

	if (!devm_request_mem_region(dev, memory->start,
			memory->end - memory->start + 1, pdev->name))
		return -EBUSY;

	irqmux->base = devm_ioremap_nocache(dev, memory->start,
			memory->end - memory->start + 1);
	if (!irqmux->base)
		return -ENOMEM;

	irqmux->port_first = plat_data->port_first;

	set_irq_chained_handler(irq, stm_gpio_irqmux_handler);
	set_irq_data(irq, irqmux);

	for (port_no = irqmux->port_first;
			port_no < irqmux->port_first + plat_data->ports_num;
			port_no++) {
		BUG_ON(port_no >= stm_gpio_num);

		if (stm_gpio_irq_init(port_no) != 0) {
			printk(KERN_ERR "stm_gpio: Failed to init gpio "
					"interrupt for port %d!\n", port_no);
			return -EINVAL;
		}
	}

	return 0;
}
static void tc6393xb_detach_irq(struct platform_device *dev)
{
	struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
	unsigned int irq, irq_base;

	set_irq_chained_handler(tc6393xb->irq, NULL);
	set_irq_data(tc6393xb->irq, NULL);

	irq_base = tc6393xb->irq_base;

	for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
		set_irq_flags(irq, 0);
		set_irq_chip(irq, NULL);
		set_irq_chip_data(irq, NULL);
	}
}
Example #13
0
static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
{
	unsigned int first_irq;
	int i;

	first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
	for (i = first_irq; i < first_irq + NMK_GPIO_PER_CHIP; i++) {
		set_irq_chip(i, &nmk_gpio_irq_chip);
		set_irq_handler(i, handle_edge_irq);
		set_irq_flags(i, IRQF_VALID);
		set_irq_chip_data(i, nmk_chip);
	}
	set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
	set_irq_data(nmk_chip->parent_irq, nmk_chip);
	return 0;
}
Example #14
0
/*
 * Setup Media5200 IRQ mapping
 */
static void __init media5200_init_irq(void)
{
	struct device_node *fpga_np;
	int cascade_virq;

	/* First setup the regular MPC5200 interrupt controller */
	mpc52xx_init_irq();

	/* Now find the FPGA IRQ */
	fpga_np = of_find_compatible_node(NULL, NULL, "fsl,media5200-fpga");
	if (!fpga_np)
		goto out;
	pr_debug("%s: found fpga node: %s\n", __func__, fpga_np->full_name);

	media5200_irq.regs = of_iomap(fpga_np, 0);
	if (!media5200_irq.regs)
		goto out;
	pr_debug("%s: mapped to %p\n", __func__, media5200_irq.regs);

	cascade_virq = irq_of_parse_and_map(fpga_np, 0);
	if (!cascade_virq)
		goto out;
	pr_debug("%s: cascaded on virq=%i\n", __func__, cascade_virq);

	/* Disable all FPGA IRQs */
	out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, 0);

	spin_lock_init(&media5200_irq.lock);

	media5200_irq.irqhost = irq_alloc_host(fpga_np, IRQ_HOST_MAP_LINEAR,
					       MEDIA5200_NUM_IRQS,
					       &media5200_irq_ops, -1);
	if (!media5200_irq.irqhost)
		goto out;
	pr_debug("%s: allocated irqhost\n", __func__);

	media5200_irq.irqhost->host_data = &media5200_irq;

	set_irq_data(cascade_virq, &media5200_irq);
	set_irq_chained_handler(cascade_virq, media5200_irq_cascade);

	return;

 out:
	pr_err("Could not find Media5200 FPGA; PCI interrupts will not work\n");
}
static void tc6393xb_attach_irq(struct platform_device *dev)
{
	struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
	unsigned int irq, irq_base;

	irq_base = tc6393xb->irq_base;

	for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
		set_irq_chip(irq, &tc6393xb_chip);
		set_irq_chip_data(irq, tc6393xb);
		set_irq_handler(irq, handle_edge_irq);
		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
	}

	set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING);
	set_irq_data(tc6393xb->irq, tc6393xb);
	set_irq_chained_handler(tc6393xb->irq, tc6393xb_irq);
}
Example #16
0
static void t7l66xb_detach_irq(struct platform_device *dev)
{
	struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
	unsigned int irq, irq_base;

	irq_base = t7l66xb->irq_base;

	set_irq_chained_handler(t7l66xb->irq, NULL);
	set_irq_data(t7l66xb->irq, NULL);

	for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) {
#ifdef CONFIG_ARM
		set_irq_flags(irq, 0);
#endif
		set_irq_chip(irq, NULL);
		set_irq_chip_data(irq, NULL);
	}
}
int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
{
    int i, j;

    /* save for local usage */
    mxs_gpio_ports = port;
    gpio_table_size = cnt;

    pr_info("MXS GPIO hardware\n");

    for (i = 0; i < cnt; i++) {
        /* disable the interrupt and clear the status */
        __raw_writel(0, port[i].base + PINCTRL_PIN2IRQ(i));
        __raw_writel(0, port[i].base + PINCTRL_IRQEN(i));

        /* clear address has to be used to clear IRQSTAT bits */
        __mxs_clrl(~0U, port[i].base + PINCTRL_IRQSTAT(i));

        for (j = port[i].virtual_irq_start;
                j < port[i].virtual_irq_start + 32; j++) {
            set_irq_chip(j, &gpio_irq_chip);
            set_irq_handler(j, handle_level_irq);
            set_irq_flags(j, IRQF_VALID);
        }

        /* setup one handler for each entry */
        set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler);
        set_irq_data(port[i].irq, &port[i]);

        /* register gpio chip */
        port[i].chip.direction_input = mxs_gpio_direction_input;
        port[i].chip.direction_output = mxs_gpio_direction_output;
        port[i].chip.get = mxs_gpio_get;
        port[i].chip.set = mxs_gpio_set;
        port[i].chip.to_irq = mxs_gpio_to_irq;
        port[i].chip.base = i * 32;
        port[i].chip.ngpio = 32;

        /* its a serious configuration bug when it fails */
        BUG_ON(gpiochip_add(&port[i].chip) < 0);
    }

    return 0;
}
Example #18
0
int __init mxs_add_gpio_port(struct mxs_gpio_port *port)
{
	int i, ret;
	if (!(port && port->chip))
		return -EINVAL;

	if (mxs_valid_gpio(port))
		return -EINVAL;

	if (mxs_gpios[port->id])
		return -EBUSY;

	mxs_gpios[port->id] = port;

	port->port.base = port->id * PINS_PER_BANK;
	port->port.ngpio = PINS_PER_BANK;
	port->port.can_sleep = 1;
	port->port.exported = 1;
	port->port.to_irq = mxs_gpio_to_irq;
	port->port.direction_input = mxs_gpio_input;
	port->port.direction_output = mxs_gpio_output;
	port->port.get = mxs_gpio_get;
	port->port.set = mxs_gpio_set;
	port->port.request = mxs_gpio_request;
	port->port.free = mxs_gpio_free;
	port->port.owner = THIS_MODULE;
	ret = gpiochip_add(&port->port);
	if (ret < 0)
		return ret;

	if (port->child_irq < 0)
		return 0;

	for (i = 0; i < PINS_PER_BANK; i++) {
		gpio_irq_chip.mask(port->child_irq + i);
		set_irq_chip(port->child_irq + i, &gpio_irq_chip);
		set_irq_handler(port->child_irq + i, handle_level_irq);
		set_irq_flags(port->child_irq + i, IRQF_VALID);
	}
	set_irq_chained_handler(port->irq, mxs_gpio_irq_handler);
	set_irq_data(port->irq, port);
	return ret;
};
Example #19
0
static __init void s5pc100_gpiolib_link(struct s3c_gpio_chip *chip)
{
	/* Interrupt */
	if (chip->config == &gpio_cfg) {
		int i, irq;

		chip->chip.to_irq = s5pc100_gpiolib_to_irq;

		for (i = 0;  i < chip->chip.ngpio; i++) {
			irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i;
			set_irq_chip(irq, &s5pc100_gpioint);
			set_irq_data(irq, &chip->chip);
			set_irq_handler(irq, handle_level_irq);
			set_irq_flags(irq, IRQF_VALID);
		}
	} else if (chip->config == &gpio_cfg_eint) {
		chip->chip.to_irq = s5pc100_gpiolib_to_eint;
	}
}
Example #20
0
void __init samsung_irq_gpio_register(struct samsung_irq_gpio_info *gpios, int num)
{
	struct samsung_irq_gpio_info *gpio = gpios;
	struct samsung_irq_gpio *sig;
	int i;

	for (i = 0; i < num; i++, gpio++) {
		sig = kmemdup(&gpio->sig, sizeof(gpio->sig), GFP_KERNEL);
		if (!sig)
			continue;

		sig->valid_groups = 0;
		/* Use the default irq gpio handler, if no handler is defined */
		if (!gpio->handler)
			gpio->handler = samsung_irq_gpio_handler;

		set_irq_chained_handler(gpio->irq, gpio->handler);
		set_irq_data(gpio->irq, sig);
	}
}
Example #21
0
/* Install the IRQ handler */
static void t7l66xb_attach_irq(struct platform_device *dev)
{
	struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
	unsigned int irq, irq_base;

	irq_base = t7l66xb->irq_base;

	for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) {
		set_irq_chip(irq, &t7l66xb_chip);
		set_irq_chip_data(irq, t7l66xb);
		set_irq_handler(irq, handle_level_irq);
#ifdef CONFIG_ARM
		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
#endif
	}

	set_irq_type(t7l66xb->irq, IRQ_TYPE_EDGE_FALLING);
	set_irq_data(t7l66xb->irq, t7l66xb);
	set_irq_chained_handler(t7l66xb->irq, t7l66xb_irq);
}
Example #22
0
static void mxc_gpio_mux_irq_handler(u32 irq, struct irq_desc *desc,
		struct pt_regs *regs)
{
	int i;
	u32 isr_reg = 0, imr_reg = 0, imr_val;
	u32 int_valid;
	struct gpio_port *port;

	for (i = 0; i < GPIO_PORT_NUM; i++) {
		port = &gpio_port[i];
		isr_reg = port->base + GPIO_ISR;
		imr_reg = port->base + GPIO_IMR;

		imr_val = __raw_readl(imr_reg);
		int_valid = __raw_readl(isr_reg) & imr_val;

		if (int_valid) {
			set_irq_data(irq, (void *)port);
			mxc_gpio_irq_handler(irq, desc, regs);
		}
	}
}
Example #23
0
void __init gemini_gpio_init(void)
{
	int i, j;

	for (i = 0; i < GPIO_PORT_NUM; i++) {
		/* disable, unmask and clear all interrupts */
		__raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_EN);
		__raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_MASK);
		__raw_writel(~0x0, GPIO_BASE(i) + GPIO_INT_CLR);

		for (j = GPIO_IRQ_BASE + i * 32;
		     j < GPIO_IRQ_BASE + (i + 1) * 32; j++) {
			set_irq_chip(j, &gpio_irq_chip);
			set_irq_handler(j, handle_edge_irq);
			set_irq_flags(j, IRQF_VALID);
		}

		set_irq_chained_handler(IRQ_GPIO(i), gpio_irq_handler);
		set_irq_data(IRQ_GPIO(i), (void *)i);
	}

	BUG_ON(gpiochip_add(&gemini_gpio_chip));
}
int __init stmp3xxx_pinmux_init(int virtual_irq_start)
{
	int b, r = 0;
	struct stmp3xxx_pinmux_bank *pm;
	int virq;

	for (b = 0; b < 3; b++) {
		/* only banks 0,1,2 are allowed to GPIO */
		pm = pinmux_banks + b;
		pm->chip.base = 32 * b;
		pm->chip.ngpio = 32;
		pm->chip.owner = THIS_MODULE;
		pm->chip.can_sleep = 1;
		pm->chip.exported = 1;
		pm->chip.to_irq = stmp3xxx_gpio_to_irq;
		pm->chip.direction_input = stmp3xxx_gpio_input;
		pm->chip.direction_output = stmp3xxx_gpio_output;
		pm->chip.get = stmp3xxx_gpio_get;
		pm->chip.set = stmp3xxx_gpio_set;
		pm->chip.request = stmp3xxx_gpio_request;
		pm->chip.free = stmp3xxx_gpio_free;
		pm->virq = virtual_irq_start + b * 32;

		for (virq = pm->virq; virq < pm->virq; virq++) {
			gpio_irq_chip.mask(virq);
			set_irq_chip(virq, &gpio_irq_chip);
			set_irq_handler(virq, handle_level_irq);
			set_irq_flags(virq, IRQF_VALID);
		}
		r = gpiochip_add(&pm->chip);
		if (r < 0)
			break;
		set_irq_chained_handler(pm->irq, stmp3xxx_gpio_irq);
		set_irq_data(pm->irq, pm);
	}
	return r;
}
Example #25
0
/*
 * Interrupt setup and service.  Interrupts on the mpc7448_hpc2 come
 * from the four external INT pins, PCI interrupts are routed via
 * PCI interrupt control registers, it generates internal IRQ23
 *
 * Interrupt routing on the Taiga Board:
 * TSI108:PB_INT[0] -> CPU0:INT#
 * TSI108:PB_INT[1] -> CPU0:MCP#
 * TSI108:PB_INT[2] -> N/C
 * TSI108:PB_INT[3] -> N/C
 */
static void __init mpc7448_hpc2_init_IRQ(void)
{
	struct mpic *mpic;
	phys_addr_t mpic_paddr = 0;
	struct device_node *tsi_pic;
#ifdef CONFIG_PCI
	unsigned int cascade_pci_irq;
	struct device_node *tsi_pci;
	struct device_node *cascade_node = NULL;
#endif

	tsi_pic = of_find_node_by_type(NULL, "open-pic");
	if (tsi_pic) {
		unsigned int size;
		const void *prop = of_get_property(tsi_pic, "reg", &size);
		mpic_paddr = of_translate_address(tsi_pic, prop);
	}

	if (mpic_paddr == 0) {
		printk("%s: No tsi108 PIC found !\n", __func__);
		return;
	}

	DBG("%s: tsi108 pic phys_addr = 0x%x\n", __func__,
	    (u32) mpic_paddr);

	mpic = mpic_alloc(tsi_pic, mpic_paddr,
			MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET |
			MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108,
			24,
			NR_IRQS-4, /* num_sources used */
			"Tsi108_PIC");

	BUG_ON(mpic == NULL);

	mpic_assign_isu(mpic, 0, mpic_paddr + 0x100);

	mpic_init(mpic);

#ifdef CONFIG_PCI
	tsi_pci = of_find_node_by_type(NULL, "pci");
	if (tsi_pci == NULL) {
		printk("%s: No tsi108 pci node found !\n", __func__);
		return;
	}
	cascade_node = of_find_node_by_type(NULL, "pic-router");
	if (cascade_node == NULL) {
		printk("%s: No tsi108 pci cascade node found !\n", __func__);
		return;
	}

	cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0);
	DBG("%s: tsi108 cascade_pci_irq = 0x%x\n", __func__,
	    (u32) cascade_pci_irq);
	tsi108_pci_int_init(cascade_node);
	set_irq_data(cascade_pci_irq, mpic);
	set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
#endif
	/* Configure MPIC outputs to CPU0 */
	tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
	of_node_put(tsi_pic);
}
Example #26
0
static int asic2_probe(struct platform_device *pdev)
{
	int rc;
	struct asic2_platform_data *pdata = pdev->dev.platform_data;
	struct asic2_data *asic;

	asic = kmalloc(sizeof (struct asic2_data), GFP_KERNEL);
	if (!asic)
		goto enomem3;

	memset(asic, 0, sizeof (*asic));
	pdev->dev.driver_data = asic;

	asic->irq_base = pdata->irq_base;
	if (!asic->irq_base) {
		printk ("asic2: uninitialized irq_base!\n");
		goto enomem1;
	}

	asic->mapping = ioremap((unsigned long)pdev->resource[0].start, IPAQ_ASIC2_MAP_SIZE);
	if (!asic->mapping) {
		printk ("asic2: couldn't ioremap\n");
		goto enomem1;
	}
	spin_lock_init(&asic->gpio_lock);
	spin_lock_init(&asic->clock_lock);
	asic->clock_ex1 = asic->clock_ex2 = 0;
	asic2_irq_init(asic);

	asic->irq_nr = pdev->resource[1].start;

	printk ("%s: using irq %d-%d on irq %d\n", pdev->name, asic->irq_base,
		asic->irq_base + ASIC2_NR_IRQS - 1, asic->irq_nr);

	set_irq_chained_handler(asic->irq_nr, asic2_irq_demux);
	set_irq_type(asic->irq_nr, IRQT_RISING);
	set_irq_data(asic->irq_nr, asic);

	__asic2_write_register(asic, IPAQ_ASIC2_CLOCK_Enable, ASIC2_CLOCK_EX0);	/* 32 kHz crystal on */
	__asic2_write_register(asic, IPAQ_ASIC2_INTR_ClockPrescale, ASIC2_INTCPS_SET);
	__asic2_write_register(asic, IPAQ_ASIC2_INTR_ClockPrescale,
			       ASIC2_INTCPS_CPS(0x0e) | ASIC2_INTCPS_SET);
	__asic2_write_register(asic, IPAQ_ASIC2_INTR_TimerSet, 1);
	__asic2_write_register(asic, IPAQ_ASIC2_INTR_MaskAndFlag, ASIC2_INTMASK_GLOBAL
				| ASIC2_INTMASK_UART_0 | ASIC2_INTMASK_UART_1 | ASIC2_INTMASK_TIMER);

	/* Set up GPIO */
	__asic2_write_register(asic, IPAQ_ASIC2_GPIOPIOD, GPIO2_IN_Y1_N | GPIO2_IN_X1_N);
	__asic2_write_register(asic, IPAQ_ASIC2_GPOBFSTAT, GPIO2_IN_Y1_N | GPIO2_IN_X1_N);
	__asic2_write_register(asic, IPAQ_ASIC2_GPIODIR, GPIO2_PEN_IRQ | GPIO2_SD_DETECT
				| GPIO2_EAR_IN_N | GPIO2_USB_DETECT_N | GPIO2_SD_CON_SLT);

	asic->ndevices = ARRAY_SIZE(asic2_blocks);
	asic->devices = soc_add_devices(pdev, asic2_blocks,
					ARRAY_SIZE(asic2_blocks),
					&pdev->resource[0], 0, asic->irq_base);
	if (!asic->devices)
		goto enomem;

	if (pdata && pdata->num_child_devs != 0) {
		int i;
		for (i = 0; i < pdata->num_child_devs; i++) {
			pdata->child_devs[i]->dev.parent = &pdev->dev;
			platform_device_register(pdata->child_devs[i]);
		}
	}

	return 0;

 enomem:
	rc = -ENOMEM;
 error:
	asic2_remove(pdev);
	return rc;
 enomem1:
	kfree(asic);
 enomem3:
	return -ENOMEM;
}
Example #27
0
static int pm8901_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int	i, rc;
	struct	pm8901_platform_data *pdata = client->dev.platform_data;
	struct	pm8901_chip *chip;

	if (pdata == NULL || !client->irq) {
		pr_err("%s: No platform_data or IRQ.\n", __func__);
		return -ENODEV;
	}

	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
		pr_err("%s: i2c_check_functionality failed.\n", __func__);
		return -ENODEV;
	}

	chip = kzalloc(sizeof *chip, GFP_KERNEL);
	if (chip == NULL) {
		pr_err("%s: kzalloc() failed.\n", __func__);
		return -ENOMEM;
	}

	chip->dev = client;

	/* Read PMIC chip revision */
	rc = ssbi_read(chip->dev, SSBI_REG_REV, &chip->revision, 1);
	if (rc)
		pr_err("%s: Failed on ssbi_read for revision: rc=%d.\n",
			__func__, rc);
	pr_info("%s: PMIC revision: %X\n", __func__, chip->revision);

	(void) memcpy((void *)&chip->pdata, (const void *)pdata,
		      sizeof(chip->pdata));

	set_irq_data(chip->dev->irq, (void *)chip);
	set_irq_wake(chip->dev->irq, 1);

	chip->pm_max_irq = 0;
	chip->pm_max_blocks = 0;
	chip->pm_max_masters = 0;

	i2c_set_clientdata(client, chip);

	pmic_chip = chip;
	spin_lock_init(&chip->pm_lock);

        // kmj_el15.pm8901_patch
        // This api is s/w workaround for PM8901's abnormal spike which could
        // cause DDR problem on PCB. Because of the spike SS made new PCB for
        // h/w workaround. This s/w workaround is for old PCBs. And If a target
        // is new PCB,  you should call a api to drop bypass voltage
        // to 1.725 originally. But you don't need that here, bacause you've done
        // that already at SBL3. So instead of calling api to drop bypass voltage 
        // here you just need to check if SBL3 bootloader includes the api.
        // In other words this api has dependency with SBL3 change
        if( pm8901_is_old_PCB_with_PM8901()==1 )
                pm8901_preload_dVdd();
	

	/* Register for all reserved IRQs */
	for (i = pdata->irq_base; i < (pdata->irq_base + MAX_PM_IRQ); i++) {
		set_irq_chip(i, &pm8901_irq_chip);
		set_irq_handler(i, handle_edge_irq);
		set_irq_flags(i, IRQF_VALID);
		set_irq_data(i, (void *)chip);
	}

	/* Add sub devices with the chip parameter as driver data */
	for (i = 0; i < pdata->num_subdevs; i++)
		pdata->sub_devices[i].driver_data = chip;
	rc = mfd_add_devices(&chip->dev->dev, 0, pdata->sub_devices,
			     pdata->num_subdevs, NULL, 0);
	if (rc) {
		pr_err("%s: could not add devices %d\n", __func__, rc);
		return rc;
	}

	rc = request_threaded_irq(chip->dev->irq, NULL, pm8901_isr_thread,
			IRQF_ONESHOT | IRQF_DISABLED | pdata->irq_trigger_flags,
			"pm8901-irq", chip);
	if (rc)
		pr_err("%s: could not request irq %d: %d\n", __func__,
				chip->dev->irq, rc);

	rc = pmic8901_dbg_probe(chip);
	if (rc < 0)
		pr_err("%s: could not set up debugfs: %d\n", __func__, rc);

	return rc;
}
Example #28
0
static int pm8058_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int	i, rc;
	struct	pm8058_platform_data *pdata = client->dev.platform_data;
	struct	pm8058_chip *chip;

	if (pdata == NULL || !client->irq) {
		pr_err("%s: No platform_data or IRQ.\n", __func__);
		return -ENODEV;
	}

	if (pdata->num_subdevs == 0) {
		pr_err("%s: No sub devices to support.\n", __func__);
		return -ENODEV;
	}

	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
		pr_err("%s: i2c_check_functionality failed.\n", __func__);
		return -ENODEV;
	}

	chip = kzalloc(sizeof *chip, GFP_KERNEL);
	if (chip == NULL) {
		pr_err("%s: kzalloc() failed.\n", __func__);
		return -ENOMEM;
	}

	chip->dev = client;

	/* Read PMIC chip revision */
	rc = ssbi_read(chip->dev, SSBI_REG_REV, &chip->revision, 1);
	if (rc)
		pr_err("%s: Failed on ssbi_read for revision: rc=%d.\n",
			__func__, rc);
	pr_info("%s: PMIC revision: %X\n", __func__, chip->revision);

	(void) memcpy((void *)&chip->pdata, (const void *)pdata,
		      sizeof(chip->pdata));

	mutex_init(&chip->pm_lock);
	set_irq_data(chip->dev->irq, (void *)chip);
	set_irq_wake(chip->dev->irq, 1);

	chip->pm_max_irq = 0;
	chip->pm_max_blocks = 0;
	chip->pm_max_masters = 0;

	i2c_set_clientdata(client, chip);

	pmic_chip = chip;

	/* Register for all reserved IRQs */
	for (i = pdata->irq_base; i < (pdata->irq_base + MAX_PM_IRQ); i++) {
		set_irq_chip(i, &pm8058_irq_chip);
		set_irq_data(i, (void *)chip);
		set_irq_handler(i, handle_edge_irq);
		set_irq_flags(i, IRQF_VALID);
		set_irq_nested_thread(i, 1);
	}

	/* Add sub devices with the chip parameter as driver data */
	for (i = 0; i < pdata->num_subdevs; i++)
		pdata->sub_devices[i].driver_data = chip;
	rc = mfd_add_devices(&chip->dev->dev, 0, pdata->sub_devices,
			     pdata->num_subdevs, NULL, 0);

	if (pdata->init) {
		rc = pdata->init(chip);
		if (rc != 0) {
			pr_err("%s: board init failed\n", __func__);
			chip->dev = NULL;
			kfree(chip);
			return -ENODEV;
		}
	}

	rc = request_threaded_irq(chip->dev->irq, NULL, pm8058_isr_thread,
			IRQF_ONESHOT | IRQF_DISABLED | pdata->irq_trigger_flags,
			"pm8058-irq", chip);
	if (rc < 0)
		pr_err("%s: could not request irq %d: %d\n", __func__,
				chip->dev->irq, rc);

	rc = pmic8058_dbg_probe(chip);
	if (rc < 0)
		pr_err("%s: could not set up debugfs: %d\n", __func__, rc);

	return 0;
}
Example #29
0
static int __devinit ezx_pcap_probe(struct spi_device *spi)
{
	struct pcap_platform_data *pdata = spi->dev.platform_data;
	struct pcap_chip *pcap;
	int i, adc_irq;
	int ret = -ENODEV;

	/* platform data is required */
	if (!pdata)
		goto ret;

	pcap = kzalloc(sizeof(*pcap), GFP_KERNEL);
	if (!pcap) {
		ret = -ENOMEM;
		goto ret;
	}

	mutex_init(&pcap->io_mutex);
	mutex_init(&pcap->adc_mutex);
	INIT_WORK(&pcap->isr_work, pcap_isr_work);
	INIT_WORK(&pcap->msr_work, pcap_msr_work);
	dev_set_drvdata(&spi->dev, pcap);

	/* setup spi */
	spi->bits_per_word = 32;
	spi->mode = SPI_MODE_0 | (pdata->config & PCAP_CS_AH ? SPI_CS_HIGH : 0);
	ret = spi_setup(spi);
	if (ret)
		goto free_pcap;

	pcap->spi = spi;

	/* setup irq */
	pcap->irq_base = pdata->irq_base;
	pcap->workqueue = create_singlethread_workqueue("pcapd");
	if (!pcap->workqueue) {
		dev_err(&spi->dev, "cant create pcap thread\n");
		goto free_pcap;
	}

	/* redirect interrupts to AP, except adcdone2 */
	if (!(pdata->config & PCAP_SECOND_PORT))
		ezx_pcap_write(pcap, PCAP_REG_INT_SEL,
					(1 << PCAP_IRQ_ADCDONE2));

	/* setup irq chip */
	for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) {
		set_irq_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq);
		set_irq_chip_data(i, pcap);
#ifdef CONFIG_ARM
		set_irq_flags(i, IRQF_VALID);
#else
		set_irq_noprobe(i);
#endif
	}

	/* mask/ack all PCAP interrupts */
	ezx_pcap_write(pcap, PCAP_REG_MSR, PCAP_MASK_ALL_INTERRUPT);
	ezx_pcap_write(pcap, PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER);
	pcap->msr = PCAP_MASK_ALL_INTERRUPT;

	set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING);
	set_irq_data(spi->irq, pcap);
	set_irq_chained_handler(spi->irq, pcap_irq_handler);
	set_irq_wake(spi->irq, 1);

	/* ADC */
	adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ?
					PCAP_IRQ_ADCDONE2 : PCAP_IRQ_ADCDONE);

	ret = request_irq(adc_irq, pcap_adc_irq, 0, "ADC", pcap);
	if (ret)
		goto free_irqchip;

	/* setup subdevs */
	for (i = 0; i < pdata->num_subdevs; i++) {
		ret = pcap_add_subdev(pcap, &pdata->subdevs[i]);
		if (ret)
			goto remove_subdevs;
	}

	/* board specific quirks */
	if (pdata->init)
		pdata->init(pcap);

	return 0;

remove_subdevs:
	device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
/* free_adc: */
	free_irq(adc_irq, pcap);
free_irqchip:
	for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
		set_irq_chip_and_handler(i, NULL, NULL);
/* destroy_workqueue: */
	destroy_workqueue(pcap->workqueue);
free_pcap:
	kfree(pcap);
ret:
	return ret;
}
int __init pq2ads_pci_init_irq(void)
{
	struct pq2ads_pci_pic *priv;
	struct irq_host *host;
	struct device_node *np;
	int ret = -ENODEV;
	int irq;

	np = of_find_compatible_node(NULL, NULL, "fsl,pq2ads-pci-pic");
	if (!np) {
		printk(KERN_ERR "No pci pic node in device tree.\n");
		of_node_put(np);
		goto out;
	}

	irq = irq_of_parse_and_map(np, 0);
	if (irq == NO_IRQ) {
		printk(KERN_ERR "No interrupt in pci pic node.\n");
		of_node_put(np);
		goto out;
	}

	priv = alloc_bootmem(sizeof(struct pq2ads_pci_pic));
	if (!priv) {
		of_node_put(np);
		ret = -ENOMEM;
		goto out_unmap_irq;
	}

	/* PCI interrupt controller registers: status and mask */
	priv->regs = of_iomap(np, 0);
	if (!priv->regs) {
		printk(KERN_ERR "Cannot map PCI PIC registers.\n");
		goto out_free_bootmem;
	}

	/* mask all PCI interrupts */
	out_be32(&priv->regs->mask, ~0);
	mb();

	host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, NUM_IRQS,
	                      &pci_pic_host_ops, NUM_IRQS);
	if (!host) {
		ret = -ENOMEM;
		goto out_unmap_regs;
	}

	host->host_data = priv;

	priv->host = host;
	host->host_data = priv;
	set_irq_data(irq, priv);
	set_irq_chained_handler(irq, pq2ads_pci_irq_demux);

	of_node_put(np);
	return 0;

out_unmap_regs:
	iounmap(priv->regs);
out_free_bootmem:
	free_bootmem((unsigned long)priv,
	             sizeof(struct pq2ads_pci_pic));
	of_node_put(np);
out_unmap_irq:
	irq_dispose_mapping(irq);
out:
	return ret;
}