static int trout_h2w_probe(struct platform_device *pdev) { int ret; struct h2w_platform_data *pdata = pdev->dev.platform_data; /* FIH-SW2-MM-AY-TAP_headset_00 */ printk(KERN_INFO "[AUD_HS]: Registering H2W (headset) driver\n"); H2W_DBG(""); hi = kzalloc(sizeof(struct h2w_info), GFP_KERNEL); if (!hi) return -ENOMEM; /* * 1. Headset insertion/removal causes UEvent's to be sent * 2. /sys/class/switch/headset_sensor/state to be updated * 3. debounce time too short will affect the behavior of headset plugin/out in phone call */ atomic_set(&hi->hs_state, 0); atomic_set(&hi->btn_state, 0); hi->ignore_btn = 0; /* FIH-SW2-MM-AY-TAP_headset_00 [ */ hi->cable_in1 = pdata->cable_in1; hi->cable_in2 = pdata->cable_in2; /* FIH-SW2-MM-AY-TAP_headset_00 ] */ /* MM-RC-TAP reduce delay time after removing headset 1206 */ hi->debounce_time = ktime_set(0, 200000000); /* 200 ms */ hi->btn_debounce_time = ktime_set(0, 80000000); /* 80 ms */ hi->sdev.name = "headset_sensor"; hi->sdev.print_name = trout_h2w_print_name; hi->hs_input = input_allocate_device(); if (!hi->hs_input) { ret = -ENOMEM; goto err_request_input_dev; } hi->hs_input->name = "fih_ringswitch"; set_bit(EV_KEY, hi->hs_input->evbit); //set_bit(KEY_RINGSWITCH, hi->hs_input->keybit); ret = input_register_device(hi->hs_input); if (ret < 0) goto err_register_hs_input_dev; ret = switch_dev_register(&hi->sdev); if (ret < 0) goto err_switch_dev_register; g_detection_work_queue = create_workqueue("detection"); if (g_detection_work_queue == NULL) { ret = -ENOMEM; goto err_create_work_queue; } ret = gpio_request(hi->cable_in1, "h2w_detect"); /* FIH-SW2-MM-AY-TAP_headset_00 */ if (ret < 0) goto err_request_detect_gpio; ret = gpio_direction_input(hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */ if (ret < 0) goto err_set_detect_gpio; else H2W_DBG(" set aid gpio(%d) as input pin : success.\r\n", hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */ hi->irq = gpio_to_irq(hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */ if (hi->irq < 0) { /* FIH-SW3-MM-AY-GUA Coverity 1108 */ ret = hi->irq; goto err_get_h2w_detect_irq_num_failed; } else H2W_DBG(" hs_det gpio_to_irq(%d): success.\r\n", hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */ hrtimer_init(&hi->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hi->timer.function = detect_event_timer_func; #ifdef FEATURE_AUD_HOOK_BTN ret = gpio_request(hi->cable_in2, "h2w_button"); /* FIH-SW2-MM-AY-TAP_headset_00 */ if (ret < 0) goto err_request_button_gpio; ret = gpio_direction_input(hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */ if (ret < 0) goto err_set_button_gpio; else H2W_DBG(" set ptt gpio(%d) as input pin : success.\r\n", hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */ hi->irq_btn = gpio_to_irq(hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */ if (hi->irq_btn < 0) { /* FIH-SW3-MM-AY-GUA Coverity 1108 */ ret = hi->irq_btn; goto err_get_button_irq_num_failed; } else H2W_DBG(" hook_btn gpio_to_irq(%d): success.\r\n", hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */ hrtimer_init(&hi->btn_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hi->btn_timer.function = button_event_timer_func; #endif aud_hs_print_gpio(); //headset inserted : gpio H->L(detect LOW level) ret = request_irq(hi->irq, detect_irq_handler, IRQF_TRIGGER_HS_INSERTED, "h2w_detect", NULL); if (ret < 0) goto err_request_detect_irq; else H2W_DBG(" request_irq (gpio %d, IRQF_TRIGGER_LOW) success\n", hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */ // Set headset_detect pin as wake up pin ret = irq_set_irq_wake(hi->irq, 1); if (ret < 0) goto err_request_input_dev; #ifdef FEATURE_AUD_HOOK_BTN // Disable button until plugged in set_irq_flags(hi->irq_btn, IRQF_VALID | IRQF_NOAUTOEN); ret = request_irq(hi->irq_btn, button_irq_handler, IRQF_TRIGGER_BTN_PRESSED, "h2w_button", NULL); if (ret < 0) goto err_request_h2w_headset_button_irq; else H2W_DBG("request_irq (gpio %d, IRQF_TRIGGER_HIGH) success\n", hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */ #endif hi->input = input_allocate_device(); if (!hi->input) { ret = -ENOMEM; goto err_request_input_dev; } hi->input->name = "simple_remote_appkey";/* MM-SC-LIVEKEY-DETECT //"fih_headsethook";*/ /* MM-RC-HEADSET-MULTIBUTTON-DETECT[* */ //hi->input->evbit[0] = BIT_MASK(EV_KEY); //hi->input->keybit[BIT_WORD(KEY_MEDIA)] = BIT_MASK(KEY_MEDIA); if (isCTIAheadset) { /* FIH-SW2-MM-AY-hsed_type-03 */ input_set_capability(hi->input, EV_KEY, KEY_VOLUMEDOWN); input_set_capability(hi->input, EV_KEY, KEY_VOLUMEUP); input_set_capability(hi->input, EV_KEY, BTN_3); /* MM-RC-HEADSET-LiveKEY-DETECT+ */ } input_set_capability(hi->input, EV_KEY, KEY_MEDIA); /* MM-RC-HEADSET-MULTIBUTTON-DETECT]* */ ret = input_register_device(hi->input); if (ret < 0) goto err_register_input_dev; return 0; // Error Messages err_register_input_dev: printk(KERN_ERR "aud_hs: err_register_input_dev\n"); input_free_device(hi->input); err_register_hs_input_dev: printk(KERN_ERR "aud_hs: err_register_hs_input_dev\n"); input_free_device(hi->hs_input); err_request_input_dev: #ifdef FEATURE_AUD_HOOK_BTN printk(KERN_ERR "aud_hs: err_request_input_dev\n"); free_irq(hi->irq_btn, 0); #endif #ifdef FEATURE_AUD_HOOK_BTN err_request_h2w_headset_button_irq: printk(KERN_ERR "aud_hs: request_h2w_headset_button_irq\n"); free_irq(hi->irq, 0); #endif err_request_detect_irq: #ifdef FEATURE_AUD_HOOK_BTN err_get_button_irq_num_failed: #endif err_get_h2w_detect_irq_num_failed: #ifdef FEATURE_AUD_HOOK_BTN err_set_button_gpio: #endif err_set_detect_gpio: printk(KERN_ERR "aud_hs: AUD_PIN_HOOK_BTN, gpio/irq error\n"); #ifdef FEATURE_AUD_HOOK_BTN gpio_free(hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */ #endif #ifdef FEATURE_AUD_HOOK_BTN err_request_button_gpio: printk(KERN_ERR "aud_hs: err_request_button_gpio\n"); gpio_free(hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */ #endif err_request_detect_gpio: printk(KERN_ERR "aud_hs: err_request_detect_gpio\n"); destroy_workqueue(g_detection_work_queue); err_create_work_queue: printk(KERN_ERR "aud_hs: err_create_work_queue\n"); switch_dev_unregister(&hi->sdev); err_switch_dev_register: printk(KERN_ERR "aud_hs: Failed to register driver\n"); return ret; }
int sec_irq_init(struct sec_pmic_dev *sec_pmic) { int i, reg_int1m, reg_irq_nr; int cur_irq; int ret = 0; int type = sec_pmic->device_type; if (!sec_pmic->irq) { dev_warn(sec_pmic->dev, "No interrupt specified, no interrupts\n"); sec_pmic->irq_base = 0; return 0; } if (!sec_pmic->irq_base) { dev_err(sec_pmic->dev, "No interrupt base specified, no interrupts\n"); return 0; } mutex_init(&sec_pmic->irqlock); switch (type) { case S5M8763X: reg_int1m = S5M8763_REG_IRQM1; reg_irq_nr = S5M8763_IRQ_NR; break; case S5M8767X: reg_int1m = S5M8767_REG_INT1M; reg_irq_nr = S5M8767_IRQ_NR; break; case S2MPS11X: reg_int1m = S2MPS11_REG_INT1M; reg_irq_nr = S2MPS11_IRQ_NR; break; default: dev_err(sec_pmic->dev, "Unknown device type %d\n", sec_pmic->device_type); return -EINVAL; } for (i = 0; i < NUM_IRQ_REGS - 1; i++) { sec_pmic->irq_masks_cur[i] = 0xff; sec_pmic->irq_masks_cache[i] = 0xff; sec_reg_write(sec_pmic, reg_int1m + i, 0xff); } for (i = 0; i < reg_irq_nr; i++) { cur_irq = i + sec_pmic->irq_base; ret = irq_set_chip_data(cur_irq, sec_pmic); if (ret) { dev_err(sec_pmic->dev, "Failed to irq_set_chip_data %d: %d\n", sec_pmic->irq, ret); return ret; } irq_set_chip_and_handler(cur_irq, &sec_pmic_irq_chip, handle_edge_irq); irq_set_nested_thread(cur_irq, 1); #ifdef CONFIG_ARM set_irq_flags(cur_irq, IRQF_VALID); #else irq_set_noprobe(cur_irq); #endif } ret = request_threaded_irq(sec_pmic->irq, NULL, sec_pmic_irq_thread, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "sec-pmic-irq", sec_pmic); if (ret) { dev_err(sec_pmic->dev, "Failed to request IRQ %d: %d\n", sec_pmic->irq, ret); return ret; } if (!sec_pmic->ono) return 0; ret = request_threaded_irq(sec_pmic->ono, NULL, sec_pmic_irq_thread, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "sec-pmic-ono", sec_pmic); if (ret) { dev_err(sec_pmic->dev, "Failed to request IRQ %d: %d\n", sec_pmic->ono, ret); return ret; } return 0; }
static void __init gic_dist_init(struct gic_chip_data *gic, unsigned int irq_start) { unsigned int gic_irqs, irq_limit, i; u32 cpumask; void __iomem *base = gic->dist_base; u32 cpu = 0; u32 nrppis = 0, ppi_base = 0; #ifdef CONFIG_SMP cpu = cpu_logical_map(smp_processor_id()); #endif cpumask = 1 << cpu; cpumask |= cpumask << 8; cpumask |= cpumask << 16; writel_relaxed(0, base + GIC_DIST_CTRL); /* * Find out how many interrupts are supported. * The GIC only supports up to 1020 interrupt sources. */ gic_irqs = readl_relaxed(base + GIC_DIST_CTR) & 0x1f; gic_irqs = (gic_irqs + 1) * 32; if (gic_irqs > 1020) gic_irqs = 1020; gic->gic_irqs = gic_irqs; /* * Nobody would be insane enough to use PPIs on a secondary * GIC, right? */ if (gic == &gic_data[0]) { nrppis = (32 - irq_start) & 31; /* The GIC only supports up to 16 PPIs. */ if (nrppis > 16) BUG(); ppi_base = gic->irq_offset + 32 - nrppis; } pr_info("Configuring GIC with %d sources (%d PPIs)\n", gic_irqs, (gic == &gic_data[0]) ? nrppis : 0); /* * Set all global interrupts to be level triggered, active low. */ for (i = 32; i < gic_irqs; i += 16) writel_relaxed(0, base + GIC_DIST_CONFIG + i * 4 / 16); /* * Set all global interrupts to this CPU only. */ for (i = 32; i < gic_irqs; i += 4) writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); /* * Set priority on all global interrupts. */ for (i = 32; i < gic_irqs; i += 4) writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); /* * Disable all interrupts. Leave the PPI and SGIs alone * as these enables are banked registers. */ for (i = 32; i < gic_irqs; i += 32) writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); /* * Limit number of interrupts registered to the platform maximum */ irq_limit = gic->irq_offset + gic_irqs; if (WARN_ON(irq_limit > NR_IRQS)) irq_limit = NR_IRQS; /* * Setup the Linux IRQ subsystem. */ for (i = 0; i < nrppis; i++) { int ppi = i + ppi_base; irq_set_percpu_devid(ppi); irq_set_chip_and_handler(ppi, &gic_chip, handle_percpu_devid_irq); irq_set_chip_data(ppi, gic); set_irq_flags(ppi, IRQF_VALID | IRQF_NOAUTOEN); } for (i = irq_start + nrppis; i < irq_limit; i++) { irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq); irq_set_chip_data(i, gic); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } writel_relaxed(1, base + GIC_DIST_CTRL); }
void __init lh7a40x_init_board_irq (void) { int irq; /* Rev A (v2.8): PF0, PF1, PF2, and PF3 are available IRQs. PF7 supports the CPLD. Rev B (v3.4): PF0, PF1, and PF2 are available IRQs. PF3 supports the CPLD. (Some) LPD7A404 prerelease boards report a version number of 0x16, but we force an override since the hardware is of the newer variety. */ unsigned char cpld_version = CPLD_REVISION; int pinCPLD = (cpld_version == 0x28) ? 7 : 3; #if defined CONFIG_MACH_LPD7A404 cpld_version = 0x34; /* Coerce LPD7A404 to RevB */ #endif /* First, configure user controlled GPIOF interrupts */ GPIO_PFDD &= ~0x0f; /* PF0-3 are inputs */ GPIO_INTTYPE1 &= ~0x0f; /* PF0-3 are level triggered */ GPIO_INTTYPE2 &= ~0x0f; /* PF0-3 are active low */ barrier (); GPIO_GPIOFINTEN |= 0x0f; /* Enable PF0, PF1, PF2, and PF3 IRQs */ /* Then, configure CPLD interrupt */ /* Disable all CPLD interrupts */ #if defined (CONFIG_MACH_LPD7A400) CPLD_INTERRUPTS = CPLD_INTMASK_TOUCH | CPLD_INTMASK_PEN | CPLD_INTMASK_ETHERNET; /* *** FIXME: don't know why we need 7 and 4. 7 is way wrong and 4 is uncefined. */ // (1<<7)|(1<<4)|(1<<3)|(1<<2); #endif #if defined (CONFIG_MACH_LPD7A404) CPLD_INTERRUPTS = CPLD_INTMASK_ETHERNET; /* *** FIXME: don't know why we need 6 and 5, neither is defined. */ // (1<<6)|(1<<5)|(1<<3); #endif GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */ GPIO_INTTYPE1 &= ~(1 << pinCPLD); /* Level triggered */ GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */ barrier (); GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */ /* Cascade CPLD interrupts */ for (irq = IRQ_BOARD_START; irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) { set_irq_chip (irq, &lpd7a40x_cpld_chip); set_irq_handler (irq, handle_level_irq); set_irq_flags (irq, IRQF_VALID); } set_irq_chained_handler ((cpld_version == 0x28) ? IRQ_CPLD_V28 : IRQ_CPLD_V34, lpd7a40x_cpld_handler); }
int max77888_irq_init(struct max77888_dev *max77888) { int i; int cur_irq; int ret; u8 i2c_data; pr_info("func: %s, irq_gpio: %d, irq_base: %d\n", __func__, max77888->irq_gpio, max77888->irq_base); if (!max77888->irq_gpio) { dev_warn(max77888->dev, "No interrupt specified.\n"); max77888->irq_base = 0; return 0; } if (!max77888->irq_base) { dev_err(max77888->dev, "No interrupt base specified.\n"); return 0; } mutex_init(&max77888->irqlock); max77888->irq = gpio_to_irq(max77888->irq_gpio); ret = gpio_request(max77888->irq_gpio, "if_pmic_irq"); if (ret) { dev_err(max77888->dev, "%s: failed requesting gpio %d\n", __func__, max77888->irq_gpio); return ret; } gpio_direction_input(max77888->irq_gpio); gpio_free(max77888->irq_gpio); /* Mask individual interrupt sources */ for (i = 0; i < MAX77888_IRQ_GROUP_NR; i++) { struct i2c_client *i2c; /* MUIC IRQ 0:MASK 1:NOT MASK */ /* Other IRQ 1:MASK 0:NOT MASK */ if (i >= MUIC_INT1 && i <= MUIC_INT3) { max77888->irq_masks_cur[i] = 0x00; max77888->irq_masks_cache[i] = 0x00; } else { max77888->irq_masks_cur[i] = 0xff; max77888->irq_masks_cache[i] = 0xff; } i2c = get_i2c(max77888, i); if (IS_ERR_OR_NULL(i2c)) continue; if (max77888_mask_reg[i] == MAX77888_REG_INVALID) continue; if (i >= MUIC_INT1 && i <= MUIC_INT3) max77888_write_reg(i2c, max77888_mask_reg[i], 0x00); else max77888_write_reg(i2c, max77888_mask_reg[i], 0xff); } /* Register with genirq */ for (i = 0; i < MAX77888_IRQ_NR; i++) { cur_irq = i + max77888->irq_base; irq_set_chip_data(cur_irq, max77888); irq_set_chip_and_handler(cur_irq, &max77888_irq_chip, handle_edge_irq); irq_set_nested_thread(cur_irq, 1); #ifdef CONFIG_ARM set_irq_flags(cur_irq, IRQF_VALID); #else irq_set_noprobe(cur_irq); #endif } /* Unmask max77888 interrupt */ ret = max77888_read_reg(max77888->i2c, MAX77888_PMIC_REG_INTSRC_MASK, &i2c_data); if (ret) { dev_err(max77888->dev, "%s: fail to read muic reg\n", __func__); return ret; } i2c_data &= ~(MAX77888_IRQSRC_CHG); /* Unmask charger interrupt */ i2c_data &= ~(MAX77888_IRQSRC_MUIC); /* Unmask muic interrupt */ max77888_write_reg(max77888->i2c, MAX77888_PMIC_REG_INTSRC_MASK, i2c_data); ret = request_threaded_irq(max77888->irq, NULL, max77888_irq_thread, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "max77888-irq", max77888); if (ret) { dev_err(max77888->dev, "Failed to request IRQ %d: %d\n", max77888->irq, ret); return ret; } return 0; }
void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start) { unsigned int max_irq, i; u32 cpumask = 1 << smp_processor_id(); if (gic_nr >= MAX_GIC_NR) BUG(); cpumask |= cpumask << 8; cpumask |= cpumask << 16; gic_data[gic_nr].dist_base = base; gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31; writel(0, base + GIC_DIST_CTRL); /* * Find out how many interrupts are supported. */ max_irq = readl(base + GIC_DIST_CTR) & 0x1f; max_irq = (max_irq + 1) * 32; /* * The GIC only supports up to 1020 interrupt sources. * Limit this to either the architected maximum, or the * platform maximum. */ if (max_irq > max(1020, NR_IRQS)) max_irq = max(1020, NR_IRQS); gic_data[gic_nr].max_irq = max_irq; /* * Set all global interrupts to be level triggered, active low. */ for (i = 32; i < max_irq; i += 16) writel(0, base + GIC_DIST_CONFIG + i * 4 / 16); /* * Set all global interrupts to this CPU only. */ for (i = 32; i < max_irq; i += 4) writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); /* * Set priority on all interrupts. */ for (i = 0; i < max_irq; i += 4) writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); /* * Disable all interrupts. */ for (i = 0; i < max_irq; i += 32) writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); /* * Setup the Linux IRQ subsystem. */ for (i = irq_start; i < gic_data[gic_nr].irq_offset + max_irq; i++) { set_irq_chip(i, &gic_chip); set_irq_chip_data(i, &gic_data[gic_nr]); set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } writel(1, base + GIC_DIST_CTRL); mb(); }
void __init pxa_init_irq(void) { int irq; /* disable all IRQs */ ICMR = 0; /* all IRQs are IRQ, not FIQ */ ICLR = 0; /* clear all GPIO edge detects */ GFER0 = 0; GFER1 = 0; GFER2 = 0; GRER0 = 0; GRER1 = 0; GRER2 = 0; GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; #ifdef CONFIG_PXA27x /* And similarly for the extra regs on the PXA27x */ ICMR2 = 0; ICLR2 = 0; GFER3 = 0; GRER3 = 0; GEDR3 = GEDR3; #endif /* only unmasked interrupts kick us out of idle */ ICCR = 1; /* GPIO 0 and 1 must have their mask bit always set */ GPIO_IRQ_mask[0] = 3; for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) { set_irq_chip(irq, &pxa_internal_chip_low); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } #if PXA_INTERNAL_IRQS > 32 for (irq = PXA_IRQ(32); irq < PXA_IRQ(PXA_INTERNAL_IRQS); irq++) { set_irq_chip(irq, &pxa_internal_chip_high); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } #endif for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) { set_irq_chip(irq, &pxa_low_gpio_chip); set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(PXA_LAST_GPIO); irq++) { set_irq_chip(irq, &pxa_muxed_gpio_chip); set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } /* Install handler for GPIO>=2 edge detect interrupts */ set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low); set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler); }
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) { ret = -ENOMEM; dev_err(&spi->dev, "can't 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++) { irq_set_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq); irq_set_chip_data(i, pcap); #ifdef CONFIG_ARM set_irq_flags(i, IRQF_VALID); #else irq_set_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; irq_set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING); irq_set_handler_data(spi->irq, pcap); irq_set_chained_handler(spi->irq, pcap_irq_handler); irq_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++) irq_set_chip_and_handler(i, NULL, NULL); /* destroy_workqueue: */ destroy_workqueue(pcap->workqueue); free_pcap: kfree(pcap); ret: return ret; }
static int hds_probe(struct platform_device *pdev) { int ret; struct htc_headset_35mm_pdata *pdata = pdev->dev.platform_data; HDSI("Registering 3.5mm headset driver\n"); hi = kzalloc(sizeof(struct hds_info), GFP_KERNEL); if (!hi) return -ENOMEM; atomic_set(&hi->btn_state, 0); hi->debounce_time = ktime_set(0, 100000000); /* 100 ms */ hi->btn35mm_debounce_time = ktime_set(0, 500000000); /* 50 ms */ hi->btn_11pin_35mm_flag = 0; hi->gpio_detect = pdata->gpio_detect; hi->gpio_headset_mic = pdata->gpio_headset_mic; hi->jack_inverted = pdata->jack_inverted; hi->sdev.name = "h2w"; mutex_init(&hi->mutex_lock); ret = switch_dev_register(&hi->sdev); if (ret < 0) goto err_switch_dev_register; g_detection_work_queue = create_workqueue("detection"); if (g_detection_work_queue == NULL) { ret = -ENOMEM; goto err_create_work_queue; } if (hi->gpio_headset_mic) { ret = gpio_request(hi->gpio_headset_mic, "3.5mm mic detect"); if (ret < 0) goto err_request_35mm_mic_detect_gpio; ret = gpio_direction_input(hi->gpio_headset_mic); if (ret < 0) goto err_set_35mm_mic_detect_gpio; hi->irq_btn_35mm = gpio_to_irq(hi->gpio_headset_mic); if (hi->irq_btn_35mm < 0) { ret = hi->irq_btn_35mm; goto err_request_btn_35mm_irq; } set_irq_flags(hi->irq_btn_35mm, IRQF_VALID | IRQF_NOAUTOEN); ret = request_irq(hi->irq_btn_35mm, button_35mm_irq_handler, IRQF_TRIGGER_HIGH, "35mm_button", NULL); if (ret < 0) goto err_request_btn_35mm_irq; } ret = gpio_request(hi->gpio_detect, "3.5mm jack"); if (ret < 0) goto err_request_detect_gpio; ret = gpio_direction_input(hi->gpio_detect); if (ret < 0) goto err_set_detect_gpio; hi->irq = gpio_to_irq(hi->gpio_detect); if (hi->irq < 0) { ret = hi->irq; goto err_get_hds_detect_irq_num_failed; } hrtimer_init(&hi->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hi->timer.function = detect_event_timer_func; hrtimer_init(&hi->btn35mm_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hi->btn35mm_timer.function = button_35mm_event_timer_func; ret = request_irq(hi->irq, detect_irq_handler, IRQF_TRIGGER_LOW, "3.5mm headset detection", NULL); if (ret < 0) goto err_request_detect_irq; ret = set_irq_wake(hi->irq, 1); if (ret < 0) goto err_request_input_dev; hi->input = input_allocate_device(); if (!hi->input) { ret = -ENOMEM; goto err_request_input_dev; } hi->input->name = "3.5mm headset"; set_bit(EV_SYN, hi->input->evbit); set_bit(EV_KEY, hi->input->evbit); set_bit(KEY_MEDIA, hi->input->keybit); ret = input_register_device(hi->input); if (ret < 0) goto err_register_input_dev; return 0; err_register_input_dev: input_free_device(hi->input); err_request_input_dev: free_irq(hi->irq, 0); err_request_detect_irq: err_get_hds_detect_irq_num_failed: err_set_detect_gpio: gpio_free(hi->gpio_detect); err_request_detect_gpio: if (hi->gpio_headset_mic) free_irq(hi->irq_btn_35mm, 0); err_request_btn_35mm_irq: err_set_35mm_mic_detect_gpio: if (hi->gpio_headset_mic) gpio_free(hi->gpio_headset_mic); err_request_35mm_mic_detect_gpio: destroy_workqueue(g_detection_work_queue); err_create_work_queue: switch_dev_unregister(&hi->sdev); err_switch_dev_register: HDSE("Failed to register driver\n"); return ret; }
static int egpio_probe(struct platform_device *pdev) { struct htc_egpio_platform_data *pdata = pdev->dev.platform_data; struct resource *res; struct egpio_info *ei; int irq, i, ret; struct gpio_ops ops; /* Initialize ei data structure. */ //obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o ei = kzalloc(sizeof(*ei), GFP_KERNEL); if (!ei) return -ENOMEM; spin_lock_init(&ei->lock); /* Find chained irq */ ret = -EINVAL; res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res) ei->chainedirq = res->start; /* Map egpio chip into virtual address space. */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) goto fail; ei->addrBase = (u16 *)ioremap_nocache(res->start, res->end - res->start); if (!ei->addrBase) goto fail; printk(KERN_NOTICE "EGPIO phys=%08x virt=%p\n" , res->start, ei->addrBase); ei->bus_shift = pdata->bus_shift; platform_set_drvdata(pdev, ei); ops.get_value = egpio_get; ops.set_value = egpio_set; ops.to_irq = egpio_to_irq; gpiodev_register(pdata->gpio_base, &pdev->dev, &ops); /* Go through list of pins. */ ei->irqStart = pdata->irq_base; ei->maxRegs = pdata->nrRegs - 1; ei->ackRegister = pdata->ackRegister; for (i = 0; i < pdata->nr_pins; i++) setup_pin(ei, &pdata->pins[i]); if (ei->chainedirq) { /* Setup irq handlers */ ei->ackWrite = 0xFFFF; if (pdata->invertAcks) ei->ackWrite = 0; for (irq = ei->irqStart; irq < ei->irqStart+MAX_EGPIO_IRQS; irq++) { set_irq_chip(irq, &egpio_muxed_chip); set_irq_chip_data(irq, ei); set_irq_handler(irq, handle_simple_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } set_irq_type(ei->chainedirq, IRQT_RISING); set_irq_data(ei->chainedirq, ei); set_irq_chained_handler(ei->chainedirq, egpio_handler); ackirqs(ei); device_init_wakeup(&pdev->dev, 1); } /* Setup initial output pin values. */ for (i = 0; i<=ei->maxRegs; i++) if (i != ei->ackRegister) writew(ei->cached_values[i], &ei->addrBase[i << ei->bus_shift]); return 0; fail: printk(KERN_NOTICE "EGPIO failed to setup\n"); kfree(ei); return ret; }
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; }
int max77665_irq_init(struct max77665_dev *max77665) { int i; int cur_irq; int ret; u8 i2c_data; if (!max77665->irq) { dev_warn(max77665->dev, "No interrupt specified.\n"); max77665->irq_base = 0; return 0; } if (!max77665->irq_base) { dev_err(max77665->dev, "No interrupt base specified.\n"); return 0; } mutex_init(&max77665->irqlock); /* Mask individual interrupt sources */ for (i = 0; i < MAX77665_IRQ_GROUP_NR; i++) { struct i2c_client *i2c; if(i == MUIC_INT1) { max77665->irq_masks_cur[i] = 0x00; max77665->irq_masks_cache[i] = 0x00; } else { max77665->irq_masks_cur[i] = 0xff; max77665->irq_masks_cache[i] = 0xff; } i2c = get_i2c(max77665, i); if (IS_ERR_OR_NULL(i2c)) continue; if (max77665_mask_reg[i] == MAX77665_REG_INVALID) continue; if(i == MUIC_INT1) { max77665_write_reg(i2c, max77665_mask_reg[i], 0x00); } else { max77665_write_reg(i2c, max77665_mask_reg[i], 0xff); } } /* Register with genirq */ for (i = 0; i < MAX77665_IRQ_NR; i++) { cur_irq = i + max77665->irq_base; irq_set_chip_data(cur_irq, max77665); irq_set_chip_and_handler(cur_irq, &max77665_irq_chip, handle_edge_irq); irq_set_nested_thread(cur_irq, 1); #ifdef CONFIG_ARM set_irq_flags(cur_irq, IRQF_VALID); #else irq_set_noprobe(cur_irq); #endif } /* Unmask max77665 interrupt */ ret = max77665_read_reg(max77665->i2c, MAX77665_PMIC_REG_INTSRC_MASK, &i2c_data); if (ret) { dev_err(max77665->dev, "%s: fail to read muic reg\n", __func__); return ret; } i2c_data &= ~(MAX77665_IRQSRC_CHG); /* Unmask charger interrupt */ i2c_data &= ~(MAX77665_IRQSRC_MUIC); /* Unmask muic interrupt */ max77665_write_reg(max77665->i2c, MAX77665_PMIC_REG_INTSRC_MASK, i2c_data); ret = request_threaded_irq(max77665->irq, NULL, max77665_irq_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "max77665-irq", max77665); if (ret) { dev_err(max77665->dev, "Failed to request IRQ %d: %d\n", max77665->irq, ret); return ret; } return 0; }
void __init ixp2000_init_irq(void) { int irq; /* * Mask all sources */ ixp2000_reg_write(IXP2000_IRQ_ENABLE_CLR, 0xffffffff); ixp2000_reg_write(IXP2000_FIQ_ENABLE_CLR, 0xffffffff); /* clear all GPIO edge/level detects */ ixp2000_reg_write(IXP2000_GPIO_REDR, 0); ixp2000_reg_write(IXP2000_GPIO_FEDR, 0); ixp2000_reg_write(IXP2000_GPIO_LSHR, 0); ixp2000_reg_write(IXP2000_GPIO_LSLR, 0); ixp2000_reg_write(IXP2000_GPIO_INCR, -1); /* clear PCI interrupt sources */ ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, 0); /* * Certain bits in the IRQ status register of the * IXP2000 are reserved. Instead of trying to map * things non 1:1 from bit position to IRQ number, * we mark the reserved IRQs as invalid. This makes * our mask/unmask code much simpler. */ for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) { if ((1 << irq) & IXP2000_VALID_IRQ_MASK) { set_irq_chip(irq, &ixp2000_irq_chip); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } else set_irq_flags(irq, 0); } for (irq = IRQ_IXP2000_DRAM0_MIN_ERR; irq <= IRQ_IXP2000_SP_INT; irq++) { if((1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)) & IXP2000_VALID_ERR_IRQ_MASK) { set_irq_chip(irq, &ixp2000_err_irq_chip); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } else set_irq_flags(irq, 0); } set_irq_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler); for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) { set_irq_chip(irq, &ixp2000_GPIO_irq_chip); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } set_irq_chained_handler(IRQ_IXP2000_GPIO, ixp2000_GPIO_irq_handler); /* * Enable PCI irqs. The actual PCI[AB] decoding is done in * entry-macro.S, so we don't need a chained handler for the * PCI interrupt source. */ ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << IRQ_IXP2000_PCI)); for (irq = IRQ_IXP2000_PCIA; irq <= IRQ_IXP2000_PCIB; irq++) { set_irq_chip(irq, &ixp2000_pci_irq_chip); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } }
static int tegra_ehci_probe(struct platform_device *pdev) { struct resource *res; struct usb_hcd *hcd; struct tegra_ehci_hcd *tegra; int err = 0; int irq; pr_info("%s: ehci.id = %d\n", __func__, pdev->id); device_ehci_shutdown = false; tegra = devm_kzalloc(&pdev->dev, sizeof(struct tegra_ehci_hcd), GFP_KERNEL); if (!tegra) { dev_err(&pdev->dev, "memory alloc failed\n"); return -ENOMEM; } mutex_init(&tegra->sync_lock); hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "unable to create HCD\n"); return -ENOMEM; } platform_set_drvdata(pdev, tegra); //+Sophia:0608 tegra->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(tegra->clk)) { dev_err(&pdev->dev, "Can't get ehci clock\n"); err = PTR_ERR(tegra->clk); goto fail_io; } err = clk_enable(tegra->clk); if (err) goto fail_clken; tegra_periph_reset_assert(tegra->clk); udelay(2); tegra_periph_reset_deassert(tegra->clk); udelay(2); //+Sophia:0608 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "failed to get I/O memory\n"); err = -ENXIO; goto fail_io; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = ioremap(res->start, resource_size(res)); if (!hcd->regs) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); err = -ENOMEM; goto fail_io; } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "failed to get IRQ\n"); err = -ENODEV; goto fail_irq; } set_irq_flags(irq, IRQF_VALID); tegra->irq = irq; tegra->phy = tegra_usb_phy_open(pdev); if (IS_ERR(tegra->phy)) { dev_err(&pdev->dev, "failed to open USB phy\n"); err = -ENXIO; goto fail_irq; } err = tegra_usb_phy_power_on(tegra->phy); if (err) { dev_err(&pdev->dev, "failed to power on the phy\n"); goto fail_phy; } err = tegra_usb_phy_init(tegra->phy); if (err) { dev_err(&pdev->dev, "failed to init the phy\n"); goto fail_phy; } err = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_TRIGGER_HIGH); if (err) { dev_err(&pdev->dev, "Failed to add USB HCD, error=%d\n", err); goto fail_phy; } err = enable_irq_wake(tegra->irq); if (err < 0) { dev_warn(&pdev->dev, "Couldn't enable USB host mode wakeup, irq=%d, " "error=%d\n", irq, err); err = 0; tegra->irq = 0; } tegra->ehci = hcd_to_ehci(hcd); //htc++ #ifdef CONFIG_QCT_9K_MODEM if (Modem_is_QCT_MDM9K()) { extern struct platform_device tegra_ehci2_device; if (&tegra_ehci2_device == pdev) { mdm_hsic_ehci_hcd = tegra->ehci; mdm_hsic_usb_hcd = hcd; mdm_hsic_phy = tegra->phy; pr_info("%s:: mdm_hsic_ehci_hcd = %x, mdm_hsic_usb_hcd = %x, mdm_hsic_phy = %x\n", __func__, (unsigned int)mdm_hsic_ehci_hcd, (unsigned int)mdm_hsic_usb_hcd, (unsigned int)mdm_hsic_phy); } } #endif //CONFIG_QCT_9K_MODEM //htc-- #ifdef CONFIG_USB_OTG_UTILS if (tegra_usb_phy_otg_supported(tegra->phy)) { tegra->transceiver = otg_get_transceiver(); if (tegra->transceiver) otg_set_host(tegra->transceiver, &hcd->self); } #endif return err; fail_phy: tegra_usb_phy_close(tegra->phy); fail_irq: iounmap(hcd->regs); fail_clken: clk_put(tegra->clk); fail_io: usb_put_hcd(hcd); return err; }
static void imx_fpga_ack_irq(struct irq_data *data) { struct irq_mng *mng = irq_data_get_irq_chip_data(data); unsigned int irq = data->irq; #else static void imx_fpga_ack_irq(unsigned int irq) { struct irq_mng *mng = &global_mng; #endif int shadow; shadow = 1 << ((irq - IRQ_FPGA_START) % NB_IT); pr_debug("%s: irq %d ack:0x%x\n", __FUNCTION__, irq, shadow); writew(shadow, mng->membase + FPGA_ISR); } #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) static void imx_fpga_mask_irq(struct irq_data *data) { struct irq_mng *mng = irq_data_get_irq_chip_data(data); unsigned int irq = data->irq; #else static void imx_fpga_mask_irq(unsigned int irq) { struct irq_mng *mng = &global_mng; #endif int shadow; shadow = readw(mng->membase + FPGA_IMR); shadow &= ~( 1 << ((irq - IRQ_FPGA_START) % NB_IT)); pr_debug("%s: irq %d mask:0x%x\n", __FUNCTION__, irq, shadow); writew(shadow, mng->membase + FPGA_IMR); } #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) static void imx_fpga_unmask_irq(struct irq_data *data) { struct irq_mng *mng = irq_data_get_irq_chip_data(data); unsigned int irq = data->irq; #else static void imx_fpga_unmask_irq(unsigned int irq) { struct irq_mng *mng = &global_mng; #endif int shadow; shadow = readw(mng->membase + FPGA_IMR); shadow |= 1 << ((irq - IRQ_FPGA_START) % NB_IT); pr_debug("%s: irq %d mask:0x%x\n", __FUNCTION__, irq, shadow); writew(shadow, mng->membase + FPGA_IMR); } static irqreturn_t ocore_irq_mng_interrupt(int irq, void *data) { struct irq_mng *mng = data; struct irq_desc *desc; unsigned int mask; mask = readw(mng->membase + FPGA_ISR); pr_debug("%s: mask:0x%04x\n", __FUNCTION__, mask); do { irq = IRQ_FPGA_START; #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) desc = irq_to_desc(irq); #else desc = irq_desc + irq; #endif /* handle irqs */ while (mask) { if (mask & 1) { pr_debug("handling irq %d 0x%08x\n", irq, (unsigned int)desc); #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) desc->handle_irq(irq, desc); #else desc_handle_irq(irq, desc); #endif } irq++; desc++; mask >>= 1; } mask = readw(mng->membase + FPGA_ISR); } while (mask != 0); return IRQ_HANDLED; } static struct irq_chip imx_fpga_chip = { .name = "FPGA", #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) .irq_ack = imx_fpga_ack_irq, .irq_mask = imx_fpga_mask_irq, .irq_unmask = imx_fpga_unmask_irq, #else .ack = imx_fpga_ack_irq, .mask = imx_fpga_mask_irq, .unmask = imx_fpga_unmask_irq, #endif #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) .irq_set_type = imx_fpga_irq_type, #else .set_type = imx_fpga_irq_type, #endif }; #ifdef CONFIG_PM static int ocore_irq_mng_suspend(struct platform_device *pdev, pm_message_t state) { dev_dbg(&pdev->dev, "suspended\n"); return 0; } static int ocore_irq_mng_resume(struct platform_device *pdev) { dev_dbg(&pdev->dev, "resumed\n"); return 0; } #else # define ocore_irq_mng_suspend NULL # define ocore_irq_mng_resume NULL #endif /* CONFIG_PM */ #if LINUX_VERSION_CODE > KERNEL_VERSION(3,8,0) /* __dev* stuff is removed from Linux since 30/11/2012 */ #define __devinit #define __devexit #endif static int __devinit ocore_irq_mng_probe(struct platform_device *pdev) { struct ocore_irq_mng_pdata *pdata = pdev->dev.platform_data; unsigned int irq; u16 id; int ret = 0; struct resource *mem_res; struct resource *irq_res; struct irq_mng *mng; if (!pdata) { dev_err(&pdev->dev, "Platform data required !\n"); return -ENODEV; } /* get resources */ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem_res) { dev_err(&pdev->dev, "can't find mem resource\n"); return -EINVAL; } irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq_res) { dev_err(&pdev->dev, "can't find irq resource\n"); return -EINVAL; } mem_res = request_mem_region(mem_res->start, resource_size(mem_res), pdev->name); if (!mem_res) { dev_err(&pdev->dev, "iomem already in use\n"); return -EBUSY; } /* allocate memory for private structure */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) mng = kmalloc(sizeof(struct irq_mng), GFP_KERNEL); #else mng = &global_mng; #endif if (!mng) { ret = -ENOMEM; goto out_release_mem; } pdata->mng = mng; mng->membase = ioremap(mem_res->start, resource_size(mem_res)); if (!mng->membase) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; goto out_dev_free; } mng->mem_res = mem_res; mng->irq_res = irq_res; /* check if ID is correct */ id = readw(mng->membase + ID_OFFSET); if (id != pdata->idnum) { printk(KERN_WARNING "For irq_mngr id:%d doesn't match with id" "read %d,\n is device present ?\n", pdata->idnum, id); ret = -ENODEV; goto out_iounmap; } /* Mask all interrupts initially */ writew(0, mng->membase + FPGA_IMR); for (irq = IRQ_FPGA(0); irq < IRQ_FPGA(NB_IT); irq++) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) irq_set_chip_data(irq, mng); irq_set_chip_and_handler_name(irq, &imx_fpga_chip, handle_edge_irq, NULL); #else set_irq_chip_data(irq, mng); set_irq_chip_and_handler(irq, &imx_fpga_chip, handle_edge_irq); #endif set_irq_flags(irq, IRQF_VALID); } /* clear pending interrupts */ writew(0xffff, mng->membase + FPGA_ISR); ret = request_irq(mng->irq_res->start, ocore_irq_mng_interrupt, #if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) IRQF_SAMPLE_RANDOM, #else 0, #endif "ocore_irq_mng", mng); if (ret < 0) { printk(KERN_ERR "Can't register irq %d\n", mng->irq_res->start); goto request_irq_error; } pr_debug("FPGA IRQs initialized (Parent=%d)\n", mng->irq_res->start); return 0; request_irq_error: out_iounmap: iounmap(mng->membase); out_dev_free: #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) kfree(mng); #endif out_release_mem: release_mem_region(mem_res->start, resource_size(mem_res)); return ret; } static int __devexit ocore_irq_mng_remove(struct platform_device *pdev) { struct ocore_irq_mng_pdata *pdata = pdev->dev.platform_data; struct irq_mng *mng = pdata->mng; unsigned int irq; for (irq = IRQ_FPGA(0); irq < IRQ_FPGA(NB_IT); irq++) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) irq_set_chip(irq, NULL); irq_set_handler(irq, NULL); #else set_irq_chip(irq, NULL); set_irq_handler(irq, NULL); #endif set_irq_flags(irq, 0); } free_irq(mng->irq_res->start, mng); release_mem_region(mng->mem_res->start, resource_size(mng->mem_res)); iounmap(mng->membase); kfree(mng); return 0; } static struct platform_driver ocore_irq_mng_driver = { .probe = ocore_irq_mng_probe, .remove = ocore_irq_mng_remove, .suspend = ocore_irq_mng_suspend, .resume = ocore_irq_mng_resume, .driver = { .name = DRIVER_NAME, }, }; static int __init ocore_irq_mng_init(void) { return platform_driver_register(&ocore_irq_mng_driver); } static void __exit ocore_irq_mng_exit(void) { platform_driver_unregister(&ocore_irq_mng_driver); } module_init(ocore_irq_mng_init); module_exit(ocore_irq_mng_exit); MODULE_AUTHOR("Julien Boibessot, <*****@*****.**>"); MODULE_DESCRIPTION("Armadeus OpenCore IRQ manager"); MODULE_LICENSE("GPL");
/** * zynq_gpio_probe - Initialization method for a zynq_gpio device * @pdev: platform device instance * * This function allocates memory resources for the gpio device and registers * all the banks of the device. It will also set up interrupts for the gpio * pins. * Note: Interrupts are disabled for all the banks during initialization. * * Return: 0 on success, negative error otherwise. */ static int zynq_gpio_probe(struct platform_device *pdev) { int ret, pin_num, bank_num, gpio_irq; unsigned int irq_num; struct zynq_gpio *gpio; struct gpio_chip *chip; struct resource *res; gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); if (!gpio) return -ENOMEM; platform_set_drvdata(pdev, gpio); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); gpio->base_addr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(gpio->base_addr)) return PTR_ERR(gpio->base_addr); irq_num = platform_get_irq(pdev, 0); gpio->irq = irq_num; /* configure the gpio chip */ chip = &gpio->chip; chip->label = "zynq_gpio"; chip->owner = THIS_MODULE; chip->dev = &pdev->dev; chip->get = zynq_gpio_get_value; chip->set = zynq_gpio_set_value; chip->request = zynq_gpio_request; chip->free = zynq_gpio_free; chip->direction_input = zynq_gpio_dir_in; chip->direction_output = zynq_gpio_dir_out; chip->to_irq = zynq_gpio_to_irq; chip->dbg_show = NULL; chip->base = 0; /* default pin base */ chip->ngpio = ZYNQ_GPIO_NR_GPIOS; chip->can_sleep = 0; gpio->irq_base = irq_alloc_descs(-1, 0, chip->ngpio, 0); if (gpio->irq_base < 0) { dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n"); return -ENODEV; } irq_domain = irq_domain_add_legacy(pdev->dev.of_node, chip->ngpio, gpio->irq_base, 0, &irq_domain_simple_ops, NULL); /* report a bug if gpio chip registration fails */ ret = gpiochip_add(chip); if (ret < 0) return ret; /* Enable GPIO clock */ gpio->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(gpio->clk)) { dev_err(&pdev->dev, "input clock not found.\n"); if (gpiochip_remove(chip)) dev_err(&pdev->dev, "Failed to remove gpio chip\n"); return PTR_ERR(gpio->clk); } ret = clk_prepare_enable(gpio->clk); if (ret) { dev_err(&pdev->dev, "Unable to enable clock.\n"); if (gpiochip_remove(chip)) dev_err(&pdev->dev, "Failed to remove gpio chip\n"); return ret; } /* disable interrupts for all banks */ for (bank_num = 0; bank_num < ZYNQ_GPIO_MAX_BANK; bank_num++) { zynq_gpio_writereg(gpio->base_addr + ZYNQ_GPIO_INTDIS_OFFSET(bank_num), ZYNQ_GPIO_IXR_DISABLE_ALL); } /* * set the irq chip, handler and irq chip data for callbacks for * each pin */ for (pin_num = 0; pin_num < min_t(int, ZYNQ_GPIO_NR_GPIOS, (int)chip->ngpio); pin_num++) { gpio_irq = irq_find_mapping(irq_domain, pin_num); irq_set_chip_and_handler(gpio_irq, &zynq_gpio_irqchip, handle_simple_irq); irq_set_chip_data(gpio_irq, (void *)gpio); set_irq_flags(gpio_irq, IRQF_VALID); } irq_set_handler_data(irq_num, (void *)gpio); irq_set_chained_handler(irq_num, zynq_gpio_irqhandler); pm_runtime_enable(&pdev->dev); device_set_wakeup_capable(&pdev->dev, 1); return 0; }
static void mt_gic_dist_init(void) { unsigned int i; u32 cpumask = 1 << smp_processor_id(); cpumask |= cpumask << 8; cpumask |= cpumask << 16; writel(0, GIC_DIST_BASE + GIC_DIST_CTRL); /* * Set all global interrupts to be level triggered, active low. */ for (i = 32; i < (MT_NR_SPI + 32); i += 16) { writel(0, GIC_DIST_BASE + GIC_DIST_CONFIG + i * 4 / 16); } /* * Set all global interrupts to this CPU only. */ for (i = 32; i < (MT_NR_SPI + 32); i += 4) { writel(cpumask, GIC_DIST_BASE + GIC_DIST_TARGET + i * 4 / 4); } /* * Set priority on all global interrupts. */ for (i = 32; i < NR_MT_IRQ_LINE; i += 4) { writel(0xA0A0A0A0, GIC_DIST_BASE + GIC_DIST_PRI + i * 4 / 4); } /* * Disable all global interrupts. */ for (i = 32; i < NR_MT_IRQ_LINE; i += 32) { writel(0xFFFFFFFF, GIC_DIST_BASE + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); } /* * Setup the Linux IRQ subsystem. */ for (i = GIC_PPI_OFFSET; i < NR_MT_IRQ_LINE; i++) { if(i == GIC_PPI_PRIVATE_TIMER || i == GIC_PPI_WATCHDOG_TIMER) { irq_set_percpu_devid(i); irq_set_chip_and_handler(i, &mt_irq_chip, handle_percpu_devid_irq); set_irq_flags(i, IRQF_VALID | IRQF_NOAUTOEN); } else { irq_set_chip_and_handler(i, &mt_irq_chip, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } } #ifdef CONFIG_FIQ_DEBUGGER irq_set_chip_and_handler(FIQ_DBG_SGI, &mt_irq_chip, handle_level_irq); set_irq_flags(FIQ_DBG_SGI, IRQF_VALID | IRQF_PROBE); #endif /* * set all global interrupts as non-secure interrupts */ for (i = 32; i < NR_IRQS; i += 32) { writel(0xFFFFFFFF, GIC_ICDISR + 4 * (i / 32)); } /* * enable secure and non-secure interrupts on Distributor */ writel(3, GIC_DIST_BASE + GIC_DIST_CTRL); }
static int __init CoreServicesInit(void) { int ret_val = 0; int result = 0; uint32_t currentSettings = 0; struct resource* r = request_mem_region(ALLOY_RAM_BASE, ALLOY_DEDICATED_RAM_SIZE, "AlloyRAM"); if(r == NULL) { printk("request_mem_region failed.\n"); } else { printk("request_mem_region ok.\n"); } r = request_mem_region(0x40000000, 4096, "AlloyPeripherals"); if(r == NULL) { printk("request_mem_region failed.\n"); } else { printk("request_mem_region ok.\n"); } /* * Register the character device (atleast try) */ ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &Fops); /* * Negative values signify an error */ if (ret_val < 0) { printk(KERN_ALERT "%s failed with %d\n", "Sorry, registering the character device ", ret_val); return ret_val; } set_irq_flags(IRQ_ARM_LOCAL_MAILBOX2, IRQF_VALID); irq_clear_status_flags(IRQ_ARM_LOCAL_MAILBOX2, IRQ_PER_CPU); irq_clear_status_flags(IRQ_ARM_LOCAL_MAILBOX2, IRQ_LEVEL); irq_modify_status(IRQ_ARM_LOCAL_MAILBOX0,0xffffffff,0x00000000); irq_modify_status(IRQ_ARM_LOCAL_MAILBOX1,0xffffffff,0x00000000); irq_modify_status(IRQ_ARM_LOCAL_MAILBOX2,0xffffffff,0x00000000); irq_modify_status(IRQ_ARM_LOCAL_MAILBOX3,0xffffffff,0x00000000); // // Register the interrupt handler for mailbox IRQs. // set_irq_flags(IRQ_ARM_LOCAL_MAILBOX2, IRQF_VALID); result = request_threaded_irq( IRQ_ARM_LOCAL_MAILBOX0, // The interrupt number requested (irq_handler_t) MailboxIRQHandler0, // The pointer to the handler function (above) NULL, IRQF_SHARED, // Interrupt is on rising edge (button press in Fig.1) "MailboxIRQHandler", // Used in /proc/interrupts to identify the owner DEVICE_NAME); // The *dev_id for shared interrupt lines, NULL here result = request_threaded_irq( IRQ_ARM_LOCAL_MAILBOX1, // The interrupt number requested (irq_handler_t) MailboxIRQHandler1, // The pointer to the handler function (above) NULL, IRQF_SHARED, // Interrupt is on rising edge (button press in Fig.1) "MailboxIRQHandler", // Used in /proc/interrupts to identify the owner DEVICE_NAME); // The *dev_id for shared interrupt lines, NULL here result = request_threaded_irq( IRQ_ARM_LOCAL_MAILBOX2, // The interrupt number requested (irq_handler_t) MailboxIRQHandler2, // The pointer to the handler function (above) NULL, IRQF_SHARED, // Interrupt is on rising edge (button press in Fig.1) "MailboxIRQHandler", // Used in /proc/interrupts to identify the owner DEVICE_NAME); // The *dev_id for shared interrupt lines, NULL here result = request_threaded_irq( IRQ_ARM_LOCAL_MAILBOX3, // The interrupt number requested (irq_handler_t) MailboxIRQHandler3, // The pointer to the handler function (above) NULL, IRQF_SHARED, // Interrupt is on rising edge (button press in Fig.1) "MailboxIRQHandler", // Used in /proc/interrupts to identify the owner DEVICE_NAME); // The *dev_id for shared interrupt lines, NULL here if(result == 0) { printk(KERN_INFO "Mailbox ISR registered ok.\n"); } else { printk(KERN_INFO "Mailbox ISR registration failed (%d).\n", result); } // // Enable the interupt. // We're on Core0 and we want to enable the Mailbox 1 interrupt. // currentSettings = readl( __io_address(ARM_LOCAL_MAILBOX_INT_CONTROL0) ); currentSettings |= 0x0000000f; writel( currentSettings, __io_address(ARM_LOCAL_MAILBOX_INT_CONTROL0) ); // // // alloyRam = ioremap_nocache( ALLOY_RAM_BASE, ALLOY_DEDICATED_RAM_SIZE ); printk(KERN_INFO "%s The major device number is %d.\n", "Registeration is a success", MAJOR_NUM); printk(KERN_INFO "If you want to talk to the device driver,\n"); printk(KERN_INFO "you'll have to create a device file. \n"); printk(KERN_INFO "We suggest you use:\n"); printk(KERN_INFO "mknod %s c %d 0\n", DEVICE_FILE_NAME, MAJOR_NUM); printk(KERN_INFO "The device file name is important, because\n"); printk(KERN_INFO "the ioctl program assumes that's the\n"); printk(KERN_INFO "file you'll use.\n"); return 0; }
void __init l4x_setup_irq(unsigned int irq) { irq_set_chip_and_handler(irq, &l4x_irq_dev_chip, handle_simple_irq); set_irq_flags(irq, IRQF_VALID); l4x_alloc_irq_desc_data(irq); }
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); /* 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; }
void __init omap_init_irq(void) { int i, j; #ifdef CONFIG_ARCH_OMAP730 if (cpu_is_omap730()) { irq_banks = omap730_irq_banks; irq_bank_count = ARRAY_SIZE(omap730_irq_banks); } #endif #ifdef CONFIG_ARCH_OMAP1510 if (cpu_is_omap1510()) { irq_banks = omap1510_irq_banks; irq_bank_count = ARRAY_SIZE(omap1510_irq_banks); } #endif #if defined(CONFIG_ARCH_OMAP16XX) if (cpu_is_omap16xx()) { irq_banks = omap1610_irq_banks; irq_bank_count = ARRAY_SIZE(omap1610_irq_banks); } #endif printk("Total of %i interrupts in %i interrupt banks\n", irq_bank_count * 32, irq_bank_count); /* Mask and clear all interrupts */ for (i = 0; i < irq_bank_count; i++) { irq_bank_writel(~0x0, i, IRQ_MIR_REG_OFFSET); irq_bank_writel(0x0, i, IRQ_ITR_REG_OFFSET); } /* Clear any pending interrupts */ irq_bank_writel(0x03, 0, IRQ_CONTROL_REG_OFFSET); irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET); /* Enable interrupts in global mask */ if (cpu_is_omap730()) { irq_bank_writel(0x0, 0, IRQ_GMR_REG_OFFSET); } /* Install the interrupt handlers for each bank */ for (i = 0; i < irq_bank_count; i++) { for (j = i * 32; j < (i + 1) * 32; j++) { int irq_trigger; irq_trigger = irq_banks[i].trigger_map >> IRQ_BIT(j); omap_irq_set_cfg(j, 0, 0, irq_trigger); set_irq_chip(j, &omap_irq_chip); set_irq_handler(j, do_level_IRQ); set_irq_flags(j, IRQF_VALID); } } /* Unmask level 2 handler */ if (cpu_is_omap730()) { omap_unmask_irq(INT_730_IH2_IRQ); } else { omap_unmask_irq(INT_IH2_IRQ); } }
static int __init exynos_init_irq_eint(void) { int irq; #ifdef CONFIG_PINCTRL_SAMSUNG /* * The Samsung pinctrl driver provides an integrated gpio/pinmux/pinconf * functionality along with support for external gpio and wakeup * interrupts. If the samsung pinctrl driver is enabled and includes * the wakeup interrupt support, then the setting up external wakeup * interrupts here can be skipped. This check here is temporary to * allow exynos4 platforms that do not use Samsung pinctrl driver to * co-exist with platforms that do. When all of the Samsung Exynos4 * platforms switch over to using the pinctrl driver, the wakeup * interrupt support code here can be completely removed. */ struct device_node *pctrl_np, *wkup_np; const char *pctrl_compat = "samsung,pinctrl-exynos4210"; const char *wkup_compat = "samsung,exynos4210-wakeup-eint"; for_each_compatible_node(pctrl_np, NULL, pctrl_compat) { if (of_device_is_available(pctrl_np)) { wkup_np = of_find_compatible_node(pctrl_np, NULL, wkup_compat); if (wkup_np) return -ENODEV; } } #endif if (soc_is_exynos5250()) exynos_eint_base = ioremap(EXYNOS5_PA_GPIO1, SZ_4K); else exynos_eint_base = ioremap(EXYNOS4_PA_GPIO2, SZ_4K); if (exynos_eint_base == NULL) { pr_err("unable to ioremap for EINT base address\n"); return -ENOMEM; } for (irq = 0 ; irq <= 31 ; irq++) { irq_set_chip_and_handler(IRQ_EINT(irq), &exynos_irq_eint, handle_level_irq); set_irq_flags(IRQ_EINT(irq), IRQF_VALID); } irq_set_chained_handler(EXYNOS_IRQ_EINT16_31, exynos_irq_demux_eint16_31); for (irq = 0 ; irq <= 15 ; irq++) { eint0_15_data[irq] = IRQ_EINT(irq); if (soc_is_exynos5250()) { irq_set_handler_data(exynos5_eint0_15_src_int[irq], &eint0_15_data[irq]); irq_set_chained_handler(exynos5_eint0_15_src_int[irq], exynos_irq_eint0_15); } else { irq_set_handler_data(exynos4_eint0_15_src_int[irq], &eint0_15_data[irq]); irq_set_chained_handler(exynos4_eint0_15_src_int[irq], exynos_irq_eint0_15); } } return 0; }
struct pm_irq_chip * __devinit pm8xxx_irq_init(struct device *dev, const struct pm8xxx_irq_platform_data *pdata) { struct pm_irq_chip *chip; int devirq, rc; unsigned int pmirq; if (!pdata) { pr_err("No platform data\n"); return ERR_PTR(-EINVAL); } devirq = pdata->devirq; if (devirq < 0) { pr_err("missing devirq\n"); rc = devirq; return ERR_PTR(-EINVAL); } chip = kzalloc(sizeof(struct pm_irq_chip) + sizeof(u8) * pdata->irq_cdata.nirqs, GFP_KERNEL); if (!chip) { pr_err("Cannot alloc pm_irq_chip struct\n"); return ERR_PTR(-EINVAL); } memset((void*)&pm8xxx_wake_state.wake_enable[0],0,sizeof(u8)*MAX_PM_IRQ); pm8xxx_wake_state.count_wakeable = 0; chip->dev = dev; chip->devirq = devirq; chip->irq_base = pdata->irq_base; chip->num_irqs = pdata->irq_cdata.nirqs; chip->base_addr = pdata->irq_cdata.base_addr; chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8); chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8); spin_lock_init(&chip->pm_irq_lock); for (pmirq = 0; pmirq < chip->num_irqs; pmirq++) { irq_set_chip_and_handler(chip->irq_base + pmirq, &pm8xxx_irq_chip, handle_level_irq); irq_set_chip_data(chip->irq_base + pmirq, chip); #ifdef CONFIG_ARM set_irq_flags(chip->irq_base + pmirq, IRQF_VALID); #else irq_set_noprobe(chip->irq_base + pmirq); #endif } if (devirq != 0) { rc = request_irq(devirq, pm8xxx_irq_handler, pdata->irq_trigger_flag, "pm8xxx_usr_irq", chip); if (rc) { pr_err("failed to request_irq for %d rc=%d\n", devirq, rc); } else { irq_set_irq_wake(devirq, 1); } } return chip; }
static int gpio_h2w_probe(struct platform_device *pdev) { int ret; struct gpio_h2w_platform_data *pdata = pdev->dev.platform_data; H2W_DBG("H2W: Registering H2W (headset) driver\n"); hi = kzalloc(sizeof(struct h2w_info), GFP_KERNEL); if (!hi) return -ENOMEM; atomic_set(&hi->btn_state, 0); hi->ignore_btn = 0; hi->debounce_time = ktime_set(0, 500000000); /* VS760 100 ms -> 300ms */ hi->btn_debounce_time = ktime_set(0, 100000000); /* 10 ms */ hi->unplug_debounce_time = ktime_set(0, 100000000); //add eklee 100 ms hi->gpio_detect = pdata->gpio_detect; hi->gpio_button_detect = pdata->gpio_button_detect; hi->gpio_jpole = pdata->gpio_jpole; hi->gpio_mic_bias_en = pdata->gpio_mic_bias_en; hi->sdev.name = "h2w"; hi->sdev.print_name = gpio_h2w_print_name; wake_lock_init(&hi->wake_lock, WAKE_LOCK_SUSPEND, "h2w_detect_lock"); ret = switch_dev_register(&hi->sdev); if (ret < 0) goto err_switch_dev_register; g_detection_work_queue = create_workqueue("detection"); if (g_detection_work_queue == NULL) { ret = -ENOMEM; goto err_create_work_queue; } ret = gpio_request(hi->gpio_detect, "h2w_detect"); if (ret < 0) goto err_request_detect_gpio; ret = gpio_request(hi->gpio_button_detect, "h2w_button"); if (ret < 0) goto err_request_button_gpio; ret = gpio_request(hi->gpio_jpole, "h2w_jpole"); if (ret < 0) goto err_request_jpole_gpio; ret = gpio_request(hi->gpio_mic_bias_en, "h2w_mic_bias_en"); if (ret < 0) goto err_request_mic_bias_en_gpio; ret = gpio_direction_input(hi->gpio_detect); if (ret < 0) goto err_set_detect_gpio; ret = gpio_direction_input(hi->gpio_button_detect); if (ret < 0) goto err_set_button_gpio; ret = gpio_direction_input(hi->gpio_jpole); if (ret < 0) goto err_set_jpole_gpio; ret = gpio_direction_output(hi->gpio_mic_bias_en,0); if (ret < 0) goto err_set_mic_bias_en_gpio; hi->irq = gpio_to_irq(hi->gpio_detect); if (hi->irq < 0) { ret = hi->irq; goto err_get_h2w_detect_irq_num_failed; } hi->irq_btn = gpio_to_irq(hi->gpio_button_detect); if (hi->irq_btn < 0) { ret = hi->irq_btn; goto err_get_button_irq_num_failed; } hi->irq_jpole = gpio_to_irq(hi->gpio_jpole); if (hi->irq_jpole < 0) { ret = hi->irq_jpole; goto err_get_jpole_irq_num_failed; } gpio_set_value(hi->gpio_mic_bias_en, 0); // hrtimer_init(&hi->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hrtimer_init(&hi->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); hi->timer.function = detect_event_timer_func; hrtimer_init(&hi->btn_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hi->btn_timer.function = button_event_timer_func; ret = request_irq(hi->irq, detect_irq_handler, IRQF_TRIGGER_LOW, "h2w_detect", NULL); if (ret < 0) goto err_request_detect_irq; /* Disable button until plugged in */ set_irq_flags(hi->irq_btn, IRQF_VALID | IRQF_NOAUTOEN); ret = request_irq(hi->irq_btn, button_irq_handler, IRQF_TRIGGER_HIGH, "h2w_button", NULL); if (ret < 0) goto err_request_h2w_headset_button_irq; ret = set_irq_wake(hi->irq, 1); if (ret < 0) goto err_request_input_dev; hi->input = input_allocate_device(); if (!hi->input) { ret = -ENOMEM; goto err_request_input_dev; } hi->input->name = "h2w headset"; hi->input->evbit[0] = BIT_MASK(EV_KEY); hi->input->keybit[BIT_WORD(KEY_MEDIA)] = BIT_MASK(KEY_MEDIA); ret = input_register_device(hi->input); if (ret < 0) goto err_register_input_dev; ip_dev_reg = 1; /* check the inital state of headset */ queue_work(g_detection_work_queue, &g_detection_work); return 0; err_register_input_dev: input_free_device(hi->input); err_request_input_dev: free_irq(hi->irq_btn, 0); err_request_h2w_headset_button_irq: free_irq(hi->irq, 0); err_request_detect_irq: err_get_button_irq_num_failed: err_get_jpole_irq_num_failed: err_get_h2w_detect_irq_num_failed: err_set_button_gpio: err_set_detect_gpio: err_set_jpole_gpio: err_set_mic_bias_en_gpio: gpio_free(hi->gpio_button_detect); err_request_button_gpio: gpio_free(hi->gpio_detect); err_request_mic_bias_en_gpio: gpio_free(hi->gpio_mic_bias_en); err_request_jpole_gpio: gpio_free(hi->gpio_jpole); err_request_detect_gpio: destroy_workqueue(g_detection_work_queue); err_create_work_queue: switch_dev_unregister(&hi->sdev); err_switch_dev_register: printk(KERN_ERR "H2W: Failed to register driver\n"); wake_lock_destroy(&hi->wake_lock); return ret; }
int arizona_irq_init(struct arizona *arizona) { int flags = IRQF_ONESHOT; int ret, i; struct regmap_irq_chip *aod, *irq; bool ctrlif_error = true; int irq_base; switch (arizona->type) { #ifdef CONFIG_MFD_WM5102 case WM5102: aod = &wm5102_aod; irq = &wm5102_irq; switch (arizona->rev) { case 0: ctrlif_error = false; break; default: break; } break; #endif #ifdef CONFIG_MFD_WM5110 case WM5110: aod = &wm5110_aod; irq = &wm5110_irq; switch (arizona->rev) { case 0: ctrlif_error = false; break; default: break; } break; #endif default: BUG_ON("Unknown Arizona class device" == NULL); return -EINVAL; } if (arizona->pdata.irq_active_high) { ret = regmap_update_bits(arizona->regmap, ARIZONA_IRQ_CTRL_1, ARIZONA_IRQ_POL, 0); if (ret != 0) { dev_err(arizona->dev, "Couldn't set IRQ polarity: %d\n", ret); goto err; } flags |= IRQF_TRIGGER_HIGH; } else { flags |= IRQF_TRIGGER_LOW; } /* set virtual IRQs */ if (arizona->pdata.irq_base > 0) { arizona->virq[0] = arizona->pdata.irq_base; arizona->virq[1] = arizona->pdata.irq_base + 1; } else { dev_err(arizona->dev, "No irq_base specified\n"); return -EINVAL; } ret = irq_alloc_descs(arizona->pdata.irq_base, 0, ARRAY_SIZE(arizona->virq), 0); if (ret < 0) { dev_err(arizona->dev, "Failed to allocate IRQs: %d\n", ret); return ret; } for (i = 0; i < ARRAY_SIZE(arizona->virq); i++) { irq_set_chip_data(arizona->virq[i], arizona); irq_set_chip_and_handler(arizona->virq[i], &arizona_irq_chip, handle_edge_irq); irq_set_nested_thread(arizona->virq[i], 1); /* ARM needs us to explicitly flag the IRQ as valid and * will set them noprobe when we do so. */ #ifdef CONFIG_ARM set_irq_flags(arizona->virq[i], IRQF_VALID); #else irq_set_noprobe(arizona->virq[i]); #endif } irq_base = arizona->pdata.irq_base + 2; ret = regmap_add_irq_chip(arizona->regmap, arizona->virq[0], IRQF_ONESHOT, irq_base, aod, &arizona->aod_irq_chip); if (ret != 0) { dev_err(arizona->dev, "Failed to add AOD IRQs: %d\n", ret); goto err_domain; } irq_base = arizona->pdata.irq_base + 2 + ARIZONA_NUM_IRQ; ret = regmap_add_irq_chip(arizona->regmap, arizona->virq[1], IRQF_ONESHOT, irq_base, irq, &arizona->irq_chip); if (ret != 0) { dev_err(arizona->dev, "Failed to add IRQs: %d\n", ret); goto err_aod; } /* Make sure the boot done IRQ is unmasked for resumes */ i = arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE); ret = request_threaded_irq(i, NULL, arizona_boot_done, IRQF_ONESHOT, "Boot done", arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to request boot done %d: %d\n", arizona->irq, ret); goto err_boot_done; } /* Handle control interface errors in the core */ if (ctrlif_error) { i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR); ret = request_threaded_irq(i, NULL, arizona_ctrlif_err, IRQF_ONESHOT, "Control interface error", arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to request CTRLIF_ERR %d: %d\n", arizona->irq, ret); goto err_ctrlif; } } ret = request_threaded_irq(arizona->irq, NULL, arizona_irq_thread, flags, "arizona", arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to request IRQ %d: %d\n", arizona->irq, ret); goto err_main_irq; } return 0; err_main_irq: free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR), arizona); err_ctrlif: free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona); err_boot_done: regmap_del_irq_chip(arizona->virq[1], arizona->irq_chip); err_aod: regmap_del_irq_chip(arizona->virq[0], arizona->aod_irq_chip); err_domain: err: return ret; }
static void __init clps7500_init_irq(void) { unsigned int irq, flags; iomd_writeb(0, IOMD_IRQMASKA); iomd_writeb(0, IOMD_IRQMASKB); iomd_writeb(0, IOMD_FIQMASK); iomd_writeb(0, IOMD_DMAMASK); for (irq = 0; irq < NR_IRQS; irq++) { flags = IRQF_VALID; if (irq <= 6 || (irq >= 9 && irq <= 15) || (irq >= 48 && irq <= 55)) flags |= IRQF_PROBE; switch (irq) { case 0 ... 7: set_irq_chip(irq, &clps7500_a_chip); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 8 ... 15: set_irq_chip(irq, &clps7500_b_chip); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 16 ... 22: set_irq_chip(irq, &clps7500_dma_chip); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 24 ... 31: set_irq_chip(irq, &clps7500_c_chip); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 40 ... 47: set_irq_chip(irq, &clps7500_d_chip); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 48 ... 55: set_irq_chip(irq, &clps7500_no_chip); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 64 ... 72: set_irq_chip(irq, &clps7500_fiq_chip); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; } } setup_irq(IRQ_ISA, &irq_isa); }
/* MMP2 (ARMv7) */ void __init mmp2_init_icu(void) { int irq; max_icu_nr = 8; mmp_icu_base = ioremap(0xd4282000, 0x1000); icu_data[0].conf_enable = mmp2_conf.conf_enable; icu_data[0].conf_disable = mmp2_conf.conf_disable; icu_data[0].conf_mask = mmp2_conf.conf_mask; icu_data[0].nr_irqs = 64; icu_data[0].virq_base = 0; icu_data[0].domain = irq_domain_add_legacy(NULL, 64, 0, 0, &irq_domain_simple_ops, &icu_data[0]); icu_data[1].reg_status = mmp_icu_base + 0x150; icu_data[1].reg_mask = mmp_icu_base + 0x168; icu_data[1].clr_mfp_irq_base = IRQ_MMP2_PMIC_BASE; icu_data[1].clr_mfp_hwirq = IRQ_MMP2_PMIC - IRQ_MMP2_PMIC_BASE; icu_data[1].nr_irqs = 2; icu_data[1].cascade_irq = 4; icu_data[1].virq_base = IRQ_MMP2_PMIC_BASE; icu_data[1].domain = irq_domain_add_legacy(NULL, icu_data[1].nr_irqs, icu_data[1].virq_base, 0, &irq_domain_simple_ops, &icu_data[1]); icu_data[2].reg_status = mmp_icu_base + 0x154; icu_data[2].reg_mask = mmp_icu_base + 0x16c; icu_data[2].nr_irqs = 2; icu_data[2].cascade_irq = 5; icu_data[2].virq_base = IRQ_MMP2_RTC_BASE; icu_data[2].domain = irq_domain_add_legacy(NULL, icu_data[2].nr_irqs, icu_data[2].virq_base, 0, &irq_domain_simple_ops, &icu_data[2]); icu_data[3].reg_status = mmp_icu_base + 0x180; icu_data[3].reg_mask = mmp_icu_base + 0x17c; icu_data[3].nr_irqs = 3; icu_data[3].cascade_irq = 9; icu_data[3].virq_base = IRQ_MMP2_KEYPAD_BASE; icu_data[3].domain = irq_domain_add_legacy(NULL, icu_data[3].nr_irqs, icu_data[3].virq_base, 0, &irq_domain_simple_ops, &icu_data[3]); icu_data[4].reg_status = mmp_icu_base + 0x158; icu_data[4].reg_mask = mmp_icu_base + 0x170; icu_data[4].nr_irqs = 5; icu_data[4].cascade_irq = 17; icu_data[4].virq_base = IRQ_MMP2_TWSI_BASE; icu_data[4].domain = irq_domain_add_legacy(NULL, icu_data[4].nr_irqs, icu_data[4].virq_base, 0, &irq_domain_simple_ops, &icu_data[4]); icu_data[5].reg_status = mmp_icu_base + 0x15c; icu_data[5].reg_mask = mmp_icu_base + 0x174; icu_data[5].nr_irqs = 15; icu_data[5].cascade_irq = 35; icu_data[5].virq_base = IRQ_MMP2_MISC_BASE; icu_data[5].domain = irq_domain_add_legacy(NULL, icu_data[5].nr_irqs, icu_data[5].virq_base, 0, &irq_domain_simple_ops, &icu_data[5]); icu_data[6].reg_status = mmp_icu_base + 0x160; icu_data[6].reg_mask = mmp_icu_base + 0x178; icu_data[6].nr_irqs = 2; icu_data[6].cascade_irq = 51; icu_data[6].virq_base = IRQ_MMP2_MIPI_HSI1_BASE; icu_data[6].domain = irq_domain_add_legacy(NULL, icu_data[6].nr_irqs, icu_data[6].virq_base, 0, &irq_domain_simple_ops, &icu_data[6]); icu_data[7].reg_status = mmp_icu_base + 0x188; icu_data[7].reg_mask = mmp_icu_base + 0x184; icu_data[7].nr_irqs = 2; icu_data[7].cascade_irq = 55; icu_data[7].virq_base = IRQ_MMP2_MIPI_HSI0_BASE; icu_data[7].domain = irq_domain_add_legacy(NULL, icu_data[7].nr_irqs, icu_data[7].virq_base, 0, &irq_domain_simple_ops, &icu_data[7]); for (irq = 0; irq < IRQ_MMP2_MUX_END; irq++) { icu_mask_irq(irq_get_irq_data(irq)); switch (irq) { case IRQ_MMP2_PMIC_MUX: case IRQ_MMP2_RTC_MUX: case IRQ_MMP2_KEYPAD_MUX: case IRQ_MMP2_TWSI_MUX: case IRQ_MMP2_MISC_MUX: case IRQ_MMP2_MIPI_HSI1_MUX: case IRQ_MMP2_MIPI_HSI0_MUX: irq_set_chip(irq, &icu_irq_chip); irq_set_chained_handler(irq, icu_mux_irq_demux); break; default: irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq); break; } set_irq_flags(irq, IRQF_VALID); } irq_set_default_host(icu_data[0].domain); #ifdef CONFIG_CPU_MMP2 icu_irq_chip.irq_set_wake = mmp2_set_wake; #endif }
static int msm7200a_wl1251_probe(struct platform_device *pdev) { int rc; struct vreg* vreg; struct msm7200a_wl1251_pdata *pdata = pdev->dev.platform_data; if (!pdata) { pr_err("%s: no platform data\n", __func__); return -EINVAL; } if (pdata->slot_number < 1 || pdata->slot_number > 4) { pr_err("%s: invalid slot number %d\n", __func__, pdata->slot_number); return -EINVAL; } memset(&wl1251_priv, 0, sizeof(wl1251_priv)); if (pdata->gpio_irq >= 0) { rc = gpio_request(pdata->gpio_irq, "WiFi IRQ"); if (rc) { goto err_gpio_irq; } #if MSM7200A_WL1251_HACK wl1251_pdata.irq = gpio_to_irq(pdata->gpio_irq); set_irq_flags(wl1251_pdata.irq, IRQF_VALID | IRQF_NOAUTOEN); #endif } if (pdata->gpio_32k_osc >= 0) { rc = gpio_request(pdata->gpio_32k_osc, "WiFi IRQ"); if (rc) { goto err_gpio_32k_osc; } } if (pdata->gpio_enable >= 0) { rc = gpio_request(pdata->gpio_enable, "WiFi Power"); if (rc) { goto err_gpio_enable; } } if (pdata->gpio_reset >= 0) { rc = gpio_request(pdata->gpio_reset, "WiFi Reset"); if (rc) { goto err_gpio_reset; } } if (pdata->vreg_id >= 0) { vreg = vreg_get_by_id(&pdev->dev, pdata->vreg_id); if (IS_ERR(vreg)) { rc = PTR_ERR(vreg); goto err_vreg; } wl1251_priv.vreg = vreg; } msm7200a_setup_gpios(pdata->slot_number, &wl1251_priv.gpios); rc = msm_gpios_request(wl1251_priv.gpios.on, wl1251_priv.gpios.on_length); if (rc) { goto err_sdcc_gpios; } wl1251_priv.pdata = pdata; rc = msm_add_sdcc(pdata->slot_number, &msm7200a_wl1251_data, 0, 0); if (rc) { goto err_sdcc_dev; } #if MSM7200A_WL1251_HACK rc = platform_device_register(&wl1251_device); if (rc) { goto err_pdev; } #endif return 0; #if MSM7200A_WL1251_HACK err_pdev: msm_delete_sdcc(pdata->slot_number); #endif err_sdcc_dev: wl1251_priv.pdata = NULL; err_sdcc_gpios: if (wl1251_priv.vreg) { vreg_put(wl1251_priv.vreg); wl1251_priv.vreg = NULL; } err_vreg: if (pdata->gpio_reset >= 0) { gpio_free(pdata->gpio_reset); } err_gpio_reset: if (pdata->gpio_enable >= 0) { gpio_free(pdata->gpio_enable); } err_gpio_enable: if (pdata->gpio_32k_osc >= 0) { gpio_free(pdata->gpio_32k_osc); } err_gpio_32k_osc: if (pdata->gpio_irq >= 0) { gpio_free(pdata->gpio_irq); } err_gpio_irq: return rc; }