Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
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();
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
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) {
		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;
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
static int pm8901_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int	i, rc;
	struct	pm8901_platform_data *pdata = client->dev.platform_data;
	struct	pm8901_chip *chip;

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

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

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

	chip->dev = client;

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

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

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

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

	i2c_set_clientdata(client, chip);

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

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

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

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

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

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

	return rc;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
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);
	}
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
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");
Ejemplo n.º 16
0
/**
 * 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;
}
Ejemplo n.º 17
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);
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
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);
}
Ejemplo n.º 20
0
static int pm8901_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int	i, rc;
	struct	pm8901_platform_data *pdata = client->dev.platform_data;
	struct	pm8901_chip *chip;

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

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

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

	chip->dev = client;

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

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

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

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

	i2c_set_clientdata(client, chip);

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

	/* 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;
}
Ejemplo n.º 21
0
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);
	}
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
0
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;
}
Ejemplo n.º 26
0
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);
}
Ejemplo n.º 27
0
/* 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
}
Ejemplo n.º 28
0
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;
}