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); } }
/* 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); }
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; }
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); }
/* * 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); }
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; }
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); }
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; }
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); }
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; }
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); } }
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; }
/* * 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); }
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; }
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; };
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; } }
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); } }
/* 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); }
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); } } }
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; }
/* * 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); }
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; }
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; }
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; }
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; }