示例#1
0
static int __init msm_init_gpio(void)
{
	int i, j = 0;

	for (i = FIRST_GPIO_IRQ; i < FIRST_GPIO_IRQ + NR_GPIO_IRQS; i++) {
		if (i - FIRST_GPIO_IRQ > msm_gpio_chips[j].chip.end)
			j++;
		set_irq_chip_data(i, &msm_gpio_chips[j]);
		set_irq_chip(i, &msm_gpio_irq_chip);
		set_irq_handler(i, handle_edge_irq);
		set_irq_flags(i, IRQF_VALID);
	}

	for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
		writel(0, msm_gpio_chips[i].regs.int_en);
		register_gpio_chip(&msm_gpio_chips[i].chip);
	}

	set_irq_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler);
	set_irq_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler);
	set_irq_wake(INT_GPIO_GROUP1, 1);
	set_irq_wake(INT_GPIO_GROUP2, 2);
	return 0;
}
示例#2
0
文件: irq.c 项目: juergh/dns323-fw
void __init mv_init_irq(void)
{
	u32 gppMask,i;

	/* Set Gpp interrupts as needed */
        gppMask = mvBoardGpioIntMaskGet();
//jack20060626 mark
        //mvGppOutEnablle(0, gppMask , (MV_GPP_IN & gppMask));
       mvGppPolaritySet(0, gppMask , (MV_GPP_IN_INVERT & gppMask));
                                                                                                                                               
	/* Disable all interrupts initially. */
	MV_REG_WRITE(MV_IRQ_MASK_REG, 0x0);
	MV_REG_WRITE(MV_GPP_IRQ_MASK_REG, 0x0);

	/* enable GPP in the main cause */
	MV_REG_BIT_SET(MV_IRQ_MASK_REG, (1 << IRQ_GPP_0_7) | (1 << IRQ_GPP_8_15));
#if defined(CONFIG_ARCH_MV88f5181)
	MV_REG_BIT_SET(MV_IRQ_MASK_REG, (1 << IRQ_GPP_16_23) | (1 << IRQ_GPP_24_31));	
#endif

	/* clear all int */
	MV_REG_WRITE(MV_IRQ_CAUSE_REG, 0x0);
	MV_REG_WRITE(MV_GPP_IRQ_CAUSE_REG, 0x0);


	/* Do the core module ones */
	for (i = 0; i < NR_IRQS; i++) {
		set_irq_chip(i, &mv_chip);
		set_irq_handler(i, do_level_IRQ);
		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
	}
	
	/* TBD. Add support for error interrupts */

	return;
}
示例#3
0
void __init plat_perf_setup(struct irqaction *irq)
{
	cp0_perfcount_irq = -1;

#ifdef MSC01E_INT_BASE
	if (cpu_has_veic) {
		set_vi_handler (MSC01E_INT_PERFCTR, mips_perf_dispatch);
		cp0_perfcount_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
	} else
#endif
	if (cp0_perfcount_irq >= 0) {
		if (cpu_has_vint)
			set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch);
#ifdef CONFIG_MIPS_MT_SMTC
		setup_irq_smtc(cp0_perfcount_irq, irq,
		               0x100 << cp0_perfcount_irq);
#else
		setup_irq(cp0_perfcount_irq, irq);
#endif /* CONFIG_MIPS_MT_SMTC */
#ifdef CONFIG_SMP
		set_irq_handler(cp0_perfcount_irq, handle_percpu_irq);
#endif
	}
}
示例#4
0
void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_of_irqs)
{
	unsigned int irq;

	ixp2000_init_irq();
	
	if (!ixdp2x00_master_npu())
		return;

	board_irq_stat = stat_reg;
	board_irq_mask = mask_reg;
	board_irq_count = nr_of_irqs;

	*board_irq_mask = 0xffffffff;

	for(irq = IXP2000_BOARD_IRQ(0); irq < IXP2000_BOARD_IRQ(board_irq_count); irq++) {
		set_irq_chip(irq, &ixdp2x00_cpld_irq_chip);
		set_irq_handler(irq, handle_level_irq);
		set_irq_flags(irq, IRQF_VALID);
	}

	/* Hook into PCI interrupt */
	set_irq_chained_handler(IRQ_IXP2000_PCIB, ixdp2x00_irq_handler);
}
示例#5
0
/*
 * This function initializes the TZIC hardware and disables all the
 * interrupts. It registers the interrupt enable and disable functions
 * to the kernel for each interrupt source.
 */
void __init tzic_init_irq(void __iomem *irqbase)
{
	int i;

	tzic_base = irqbase;
	/* put the TZIC into the reset value with
	 * all interrupts disabled
	 */
	i = __raw_readl(tzic_base + TZIC_INTCNTL);

	__raw_writel(0x80010001, tzic_base + TZIC_INTCNTL);
	__raw_writel(0x1f, tzic_base + TZIC_PRIOMASK);
	__raw_writel(0x02, tzic_base + TZIC_SYNCCTRL);

	for (i = 0; i < 4; i++)
		__raw_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0(i));

	/* disable all interrupts */
	for (i = 0; i < 4; i++)
		__raw_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0(i));

	/* all IRQ no FIQ Warning :: No selection */

	for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
		set_irq_chip(i, &mxc_tzic_chip.base);
		set_irq_handler(i, handle_level_irq);
		set_irq_flags(i, IRQF_VALID);
	}

#ifdef CONFIG_FIQ
	/* Initialize FIQ */
	init_FIQ();
#endif

	pr_info("TrustZone Interrupt Controller (TZIC) initialized\n");
}
示例#6
0
static void __init mainstone_init_irq(void)
{
	int irq;

	pxa_init_irq();

	/* setup extra Mainstone irqs */
	for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) {
		set_irq_chip(irq, &mainstone_irq_chip);
		set_irq_handler(irq, handle_level_irq);
		if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14))
			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN);
		else
			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
	}
	set_irq_flags(MAINSTONE_IRQ(8), 0);
	set_irq_flags(MAINSTONE_IRQ(12), 0);

	MST_INTMSKENA = 0;
	MST_INTSETCLR = 0;

	set_irq_chained_handler(IRQ_GPIO(0), mainstone_irq_handler);
	set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
}
示例#7
0
int
htcapache_egpio_init(void)
{
	int irq;

	spin_lock_init(&outLock);

	// Map egpio chip into virtual address space.
	egpio = (volatile u16 *)ioremap_nocache(EGPIO_BASE
						, sizeof(cached_out_egpio));
	if (!egpio)
		return -ENODEV;

	printk(KERN_NOTICE "EGPIO phys=%08x virt=%p\n"
	       , EGPIO_BASE, egpio);

	// Setup irq handlers.
	for (irq = IRQ_EGPIO(0); irq <= IRQ_EGPIO(LAST_EGPIO); irq++) {
		set_irq_chip(irq, &egpio_muxed_chip);
		set_irq_handler(irq, handle_simple_irq);
		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
	}
	set_irq_type(IRQ_GPIO(GPIO_NR_HTCAPACHE_EGPIO_IRQ), IRQT_RISING);
        set_irq_chained_handler(IRQ_GPIO(GPIO_NR_HTCAPACHE_EGPIO_IRQ)
				, egpio_handler);

	// Setup initial output pin values.
	cached_out_egpio[2] = (1<<8); // Disable Charger
	egpio[1] = cached_out_egpio[1];
	egpio[2] = cached_out_egpio[2];

	// Unmask all current irqs.
	egpio[0] = 0;

	return 0;
}
示例#8
0
void __init msm_init_sirc(void)
{
	int i;

	int_enable = 0;
	wake_enable = 0;

	for (i = FIRST_SIRC_IRQ; i < FIRST_SIRC_IRQ + NR_SIRC_IRQS; i++) {
		set_irq_chip(i, &sirc_irq_chip);
		set_irq_handler(i, handle_edge_irq);
		set_irq_flags(i, IRQF_VALID);
	}

	for (i = 0; i < ARRAY_SIZE(sirc_reg_table); i++) {
		set_irq_chained_handler(sirc_reg_table[i].cascade_irq,
					sirc_irq_handler);
		set_irq_wake(sirc_reg_table[i].cascade_irq, 1);
#if defined(CONFIG_MSM_FIQ_SUPPORT)
		msm_fiq_select(sirc_reg_table[i].cascade_fiq);
		msm_fiq_enable(sirc_reg_table[i].cascade_fiq);
#endif
	}
	return;
}
示例#9
0
void __init iop13xx_init_irq(void)
{
	unsigned int i;

	iop_init_cp6_handler();

	/* disable all interrupts */
	write_intctl_0(0);
	write_intctl_1(0);
	write_intctl_2(0);
	write_intctl_3(0);

	/* treat all as IRQ */
	write_intstr_0(0);
	write_intstr_1(0);
	write_intstr_2(0);
	write_intstr_3(0);

	/* initialize the interrupt vector generator */
	write_intbase(INTBASE);
	write_intsize(INTSIZE_4);

	for(i = 0; i < NR_IOP13XX_IRQS; i++) {
		if (i < 32)
			set_irq_chip(i, &iop13xx_irqchip1);
		else if (i < 64)
			set_irq_chip(i, &iop13xx_irqchip2);
		else if (i < 96)
			set_irq_chip(i, &iop13xx_irqchip3);
		else
			set_irq_chip(i, &iop13xx_irqchip4);

		set_irq_handler(i, handle_level_irq);
		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
	}
}
示例#10
0
static int asic2_remove(struct platform_device *pdev)
{
	int i;
	struct asic2_platform_data *pdata = pdev->dev.platform_data;
	struct asic2_data *asic;

	if (pdata && pdata->num_child_devs != 0) {
		for (i = 0; i < pdata->num_child_devs; i++) {
			platform_device_unregister(pdata->child_devs[i]);
		}
	}

	asic = platform_get_drvdata(pdev);

	__asic2_write_register(asic, IPAQ_ASIC2_CLOCK_Enable, 0);

	for (i = 0 ; i < ASIC2_NR_IRQS ; i++) {
		int irq = i + asic->irq_base;
		set_irq_handler(irq, NULL);
		set_irq_chip(irq, NULL);
		set_irq_chip_data(irq, NULL);
		set_irq_flags(irq, 0);
	}

	set_irq_chained_handler(asic->irq_nr, NULL);

	if (asic->devices) {
		soc_free_devices(asic->devices, ARRAY_SIZE(asic2_blocks));
	}

	iounmap(asic->mapping);

	kfree(asic);

	return 0;
}
示例#11
0
/*
 * This function initializes the AVIC hardware and disables all the
 * interrupts. It registers the interrupt enable and disable functions
 * to the kernel for each interrupt source.
 */
void __init mxc_init_irq(void __iomem *irqbase)
{
	int i;

	avic_base = irqbase;

	/* put the AVIC into the reset value with
	 * all interrupts disabled
	 */
	__raw_writel(0, avic_base + AVIC_INTCNTL);
	__raw_writel(0x1f, avic_base + AVIC_NIMASK);

	/* disable all interrupts */
	__raw_writel(0, avic_base + AVIC_INTENABLEH);
	__raw_writel(0, avic_base + AVIC_INTENABLEL);

	/* all IRQ no FIQ */
	__raw_writel(0, avic_base + AVIC_INTTYPEH);
	__raw_writel(0, avic_base + AVIC_INTTYPEL);
	for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
		set_irq_chip(i, &mxc_avic_chip.base);
		set_irq_handler(i, handle_level_irq);
		set_irq_flags(i, IRQF_VALID);
	}

	/* Set default priority value (0) for all IRQ's */
	for (i = 0; i < 8; i++)
		__raw_writel(0, avic_base + AVIC_NIPRIORITY(i));

#ifdef CONFIG_FIQ
	/* Initialize FIQ */
	init_FIQ();
#endif

	printk(KERN_INFO "MXC IRQ initialized\n");
}
示例#12
0
int main(void)
{
	const int cpu = procnum();

	printf("Hello from processor %d\n", procnum());
	
	set_irq_handler(irq_handler);
	enable_hw_irq(0);
	irq_enable();

	soclib_io_set(
		base(TIMER),
		procnum()*TIMER_SPAN+TIMER_PERIOD,
		period[cpu]);
	soclib_io_set(
		base(TIMER),
		procnum()*TIMER_SPAN+TIMER_MODE,
		TIMER_RUNNING|TIMER_IRQ_ENABLED);
	
	while (1){
	  pause();
	}
	return 0;
}
示例#13
0
void __init lh7a404_init_irq (void)
{
	int irq;

#if defined(CONFIG_ARCH_LH7A400) && defined(CONFIG_ARCH_LH7A404)
#define NOP 0xe1a00000			/* mov r0, r0 */
	branch_irq_lh7a400 = NOP;
#endif

	VIC1_INTENCLR = 0xffffffff;
	VIC2_INTENCLR = 0xffffffff;
	VIC1_INTSEL = 0;		/* All IRQs */
	VIC2_INTSEL = 0;		/* All IRQs */
	VIC1_NVADDR = VA_VIC1DEFAULT;
	VIC2_NVADDR = VA_VIC2DEFAULT;
	VIC1_VECTADDR = 0;
	VIC2_VECTADDR = 0;

	GPIO_GPIOFINTEN = 0x00;		/* Disable all GPIOF interrupts */
	barrier ();

		/* Install prioritized interrupts, if there are any. */
		/* The | 0x20*/
	for (irq = 0; irq < 16; ++irq) {
		(&VIC1_VAD0)[irq]
			= (irq < ARRAY_SIZE (irq_pri_vic1))
			? (irq_pri_vic1[irq] | VA_VECTORED) : 0;
		(&VIC1_VECTCNTL0)[irq]
			= (irq < ARRAY_SIZE (irq_pri_vic1))
			? (irq_pri_vic1[irq] | VIC_CNTL_ENABLE) : 0;
		(&VIC2_VAD0)[irq]
			= (irq < ARRAY_SIZE (irq_pri_vic2))
			? (irq_pri_vic2[irq] | VA_VECTORED) : 0;
		(&VIC2_VECTCNTL0)[irq]
			= (irq < ARRAY_SIZE (irq_pri_vic2))
			? (irq_pri_vic2[irq] | VIC_CNTL_ENABLE) : 0;
	}

	for (irq = 0; irq < NR_IRQS; ++irq) {
		switch (irq) {
		case IRQ_GPIO0INTR:
		case IRQ_GPIO1INTR:
		case IRQ_GPIO2INTR:
		case IRQ_GPIO3INTR:
		case IRQ_GPIO4INTR:
		case IRQ_GPIO5INTR:
		case IRQ_GPIO6INTR:
		case IRQ_GPIO7INTR:
			set_irq_chip (irq, irq < 32
				      ? &lh7a404_gpio_vic1_chip
				      : &lh7a404_gpio_vic2_chip);
			set_irq_handler (irq, handle_level_irq); /* OK default */
			break;
		default:
			set_irq_chip (irq, irq < 32
				      ? &lh7a404_vic1_chip
				      : &lh7a404_vic2_chip);
			set_irq_handler (irq, handle_level_irq);
		}
		set_irq_flags (irq, IRQF_VALID);
	}

	lh7a40x_init_board_irq ();
}
示例#14
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_OMAP15XX
	if (cpu_is_omap1510()) {
		irq_banks = omap1510_irq_banks;
		irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
	}
	if (cpu_is_omap310()) {
		irq_banks = omap310_irq_banks;
		irq_bank_count = ARRAY_SIZE(omap310_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, handle_level_irq);
			set_irq_flags(j, IRQF_VALID);
		}
	}

	/* Unmask level 2 handler */

	if (cpu_is_omap730())
		omap_unmask_irq(INT_730_IH2_IRQ);
	else if (cpu_is_omap15xx())
		omap_unmask_irq(INT_1510_IH2_IRQ);
	else if (cpu_is_omap16xx())
		omap_unmask_irq(INT_1610_IH2_IRQ);
}
示例#15
0
文件: irq.c 项目: dgeo96/src
static int ks8695_irq_set_type(unsigned int irqno, unsigned int type)
{
	unsigned long ctrl, mode;
	unsigned short level_triggered = 0;

	ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);

	switch (type) {
		case IRQT_HIGH:
			mode = IOPC_TM_HIGH;
			level_triggered = 1;
			break;
		case IRQT_LOW:
			mode = IOPC_TM_LOW;
			level_triggered = 1;
			break;
		case IRQT_RISING:
			mode = IOPC_TM_RISING;
			break;
		case IRQT_FALLING:
			mode = IOPC_TM_FALLING;
			break;
		case IRQT_BOTHEDGE:
			mode = IOPC_TM_EDGE;
			break;
		default:
			return -EINVAL;
	}

	switch (irqno) {
		case KS8695_IRQ_EXTERN0:
			ctrl &= ~IOPC_IOEINT0TM;
			ctrl |= IOPC_IOEINT0_MODE(mode);
			break;
		case KS8695_IRQ_EXTERN1:
			ctrl &= ~IOPC_IOEINT1TM;
			ctrl |= IOPC_IOEINT1_MODE(mode);
			break;
		case KS8695_IRQ_EXTERN2:
			ctrl &= ~IOPC_IOEINT2TM;
			ctrl |= IOPC_IOEINT2_MODE(mode);
			break;
		case KS8695_IRQ_EXTERN3:
			ctrl &= ~IOPC_IOEINT3TM;
			ctrl |= IOPC_IOEINT3_MODE(mode);
			break;
		default:
			return -EINVAL;
	}

	if (level_triggered) {
		set_irq_chip(irqno, &ks8695_irq_level_chip);
		set_irq_handler(irqno, handle_level_irq);
	}
	else {
		set_irq_chip(irqno, &ks8695_irq_edge_chip);
		set_irq_handler(irqno, handle_edge_irq);
	}

	__raw_writel(ctrl, KS8695_GPIO_VA + KS8695_IOPC);
	return 0;
}
示例#16
0
void init_keybord (void)
{
	kb_in.count = 0;
	kb_in.p_head = kb_in.p_tail = kb_in.buf;
	set_irq_handler (KEYBORD_INTR, keyboard_interrupt);
}
示例#17
0
/*
 * Probe for an expansion card.
 *
 * If bit 1 of the first byte of the card is set, then the
 * card does not exist.
 */
static int __init
ecard_probe(int slot, card_type_t type)
{
	ecard_t **ecp;
	ecard_t *ec;
	struct ex_ecid cid;
	int i, rc = -ENOMEM;

	ec = kmalloc(sizeof(ecard_t), GFP_KERNEL);
	if (!ec)
		goto nomem;

	memset(ec, 0, sizeof(ecard_t));

	ec->slot_no	= slot;
	ec->type        = type;
	ec->irq		= NO_IRQ;
	ec->fiq		= NO_IRQ;
	ec->dma		= NO_DMA;
	ec->card_desc	= NULL;
	ec->ops		= &ecard_default_ops;

	rc = -ENODEV;
	if ((ec->podaddr = ecard_address(ec, type, ECARD_SYNC)) == 0)
		goto nodev;

	cid.r_zero = 1;
	ecard_readbytes(&cid, ec, 0, 16, 0);
	if (cid.r_zero)
		goto nodev;

	ec->cid.id	= cid.r_id;
	ec->cid.cd	= cid.r_cd;
	ec->cid.is	= cid.r_is;
	ec->cid.w	= cid.r_w;
	ec->cid.manufacturer = ecard_getu16(cid.r_manu);
	ec->cid.product = ecard_getu16(cid.r_prod);
	ec->cid.country = cid.r_country;
	ec->cid.irqmask = cid.r_irqmask;
	ec->cid.irqoff  = ecard_gets24(cid.r_irqoff);
	ec->cid.fiqmask = cid.r_fiqmask;
	ec->cid.fiqoff  = ecard_gets24(cid.r_fiqoff);
	ec->fiqaddr	=
	ec->irqaddr	= (unsigned char *)ioaddr(ec->podaddr);

	if (ec->cid.is) {
		ec->irqmask = ec->cid.irqmask;
		ec->irqaddr += ec->cid.irqoff;
		ec->fiqmask = ec->cid.fiqmask;
		ec->fiqaddr += ec->cid.fiqoff;
	} else {
		ec->irqmask = 1;
		ec->fiqmask = 4;
	}

	for (i = 0; i < sizeof(blacklist) / sizeof(*blacklist); i++)
		if (blacklist[i].manufacturer == ec->cid.manufacturer &&
		    blacklist[i].product == ec->cid.product) {
			ec->card_desc = blacklist[i].type;
			break;
		}

	snprintf(ec->dev.bus_id, sizeof(ec->dev.bus_id), "ecard%d", slot);
	ec->dev.parent = NULL;
	ec->dev.bus    = &ecard_bus_type;
	ec->dev.dma_mask = &ec->dma_mask;
	ec->dma_mask = (u64)0xffffffff;

	ecard_init_resources(ec);

	/*
	 * hook the interrupt handlers
	 */
	ec->irq = 32 + slot;
	set_irq_chip(ec->irq, &ecard_chip);
	set_irq_handler(ec->irq, do_level_IRQ);
	set_irq_flags(ec->irq, IRQF_VALID);

	for (ecp = &cards; *ecp; ecp = &(*ecp)->next);

	*ecp = ec;
	slot_to_expcard[slot] = ec;

	device_register(&ec->dev);
	device_create_file(&ec->dev, &dev_attr_dma);
	device_create_file(&ec->dev, &dev_attr_irq);
	device_create_file(&ec->dev, &dev_attr_resource);
	device_create_file(&ec->dev, &dev_attr_vendor);
	device_create_file(&ec->dev, &dev_attr_device); 

	return 0;

nodev:
	kfree(ec);
nomem:
	return rc;
}
示例#18
0
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);
}
示例#19
0
static int __init pnx_gpio_probe(struct platform_device *pdev)
{
	int i,j;
	int gpio = 0;
	struct gpio_bank *bank;
	struct gpio_data *data = pdev->dev.platform_data;
	unsigned long flags;

	initialized = 1;

	printk(KERN_INFO "PNX GPIO\n");
	gpio_bank_desc = data->gpio_bank_desc;
	gpio_bank_count = data->nb_banks;

	for (i = 0; i < gpio_bank_count; i++) {
		int gpio_count = 32; /* 32 GPIO per bank */
		bank = &gpio_bank_desc[i];
		bank->reserved_map = 0; /* must always be initialized */
		spin_lock_init(&bank->lock);

		/* check if bank is managed by PNX GPIO driver */
		if ((bank->gpio_base != 0) && (bank->mux_base != 0)) {
		bank->chip.request = pnx_gpio_acquire;
		bank->chip.free = pnx_gpio_release;
		bank->chip.direction_input = gpio_input;
		bank->chip.get = gpio_get;
		bank->chip.direction_output = gpio_output;
		bank->chip.set = gpio_set;
		bank->chip.to_irq = gpio_2irq;
		bank->chip.label = "gpio";
		bank->chip.base = gpio;

		bank->chip.ngpio = gpio_count;

		gpiochip_add(&bank->chip);
		}
		gpio += gpio_count;
	}

#ifdef CONFIG_MODEM_BLACK_BOX
	/* set init value */
	printk(KERN_INFO "PNX GPIO initialize SCON\n");

	/* configure MUX and PAD settings */
	for (i = 0; i< SCON_REGISTER_NB; i++)
		__raw_writel(pnx_scon_init_config[i].scon_reg_value,
			     pnx_scon_init_config[i].scon_reg_addr);

	/* configure GPIO direction and value */
	for (i=0; i < gpio_to_configure; i++) {
		int index;

		bank = get_gpio_bank(pnx_gpio_init_config[i].gpio);
		index = get_gpio_index(pnx_gpio_init_config[i].gpio);
		_set_gpio_direction(bank, index, pnx_gpio_init_config[i].dir);
		_write_gpio_pin(bank, index, pnx_gpio_init_config[i].value);
	}

	/* reserve GPIO used by Modem */
	for (i = 0; i < pnx_modem_gpio_reserved_nb; i++) {
		int index;

		bank = get_gpio_bank(pnx_modem_gpio_reserved[i]);
		index = get_gpio_index(pnx_modem_gpio_reserved[i]);
		bank->reserved_map |= (1 << index);
	}

	/* configure EXTINT used by modem */
	for (i = 0; i< pnx_modem_extint_nb; i++)
		__raw_writel(pnx_extint_init_config[i].reg_value,
			     pnx_extint_init_config[i].reg_addr);

	printk(KERN_INFO "PNX GPIO Driver\n");
#endif

	/* for extint */
	for (j = IRQ_COUNT; j < IRQ_COUNT + NR_EXTINT; j++) {
		set_irq_chip(j, &gpio_irq_chip);
		set_irq_handler(j, handle_simple_irq);
		set_irq_flags(j, IRQF_VALID);
	}

	hw_raw_local_irq_save ( flags );
	/* mask all EXT IRQ sources before registring handler */
	/* read status */
	j = __raw_readl(EXTINT_STATUS_REG) & __raw_readl(EXTINT_ENABLE3_REG);
	/* clear IRQ source(s)*/
	__raw_writel(j, EXTINT_STATUS_REG);

	__raw_writel(0, EXTINT_ENABLE3_REG);

	/* set irq in low level */
	set_irq_type(IRQ_EXTINT3, IRQF_TRIGGER_LOW);

	/* chained GPIO-IRQ on EXTINT3 */
	set_irq_chained_handler(IRQ_EXTINT3, gpio_irq_handler);
	hw_raw_local_irq_restore ( flags );

	return 0;
}
示例#20
0
void __init isa_init_irq(unsigned int host_irq)
{
	unsigned int irq;

	/*
	 * Setup, and then probe for an ISA PIC
	 * If the PIC is not there, then we
	 * ignore the PIC.
	 */
	outb(0x11, PIC_LO);
	outb(_ISA_IRQ(0), PIC_MASK_LO);	/* IRQ number		*/
	outb(0x04, PIC_MASK_LO);	/* Slave on Ch2		*/
	outb(0x01, PIC_MASK_LO);	/* x86			*/
	outb(0xf5, PIC_MASK_LO);	/* pattern: 11110101	*/

	outb(0x11, PIC_HI);
	outb(_ISA_IRQ(8), PIC_MASK_HI);	/* IRQ number		*/
	outb(0x02, PIC_MASK_HI);	/* Slave on Ch1		*/
	outb(0x01, PIC_MASK_HI);	/* x86			*/
	outb(0xfa, PIC_MASK_HI);	/* pattern: 11111010	*/

	outb(0x0b, PIC_LO);
	outb(0x0b, PIC_HI);

	if (inb(PIC_MASK_LO) == 0xf5 && inb(PIC_MASK_HI) == 0xfa) {
		outb(0xff, PIC_MASK_LO);/* mask all IRQs	*/
		outb(0xff, PIC_MASK_HI);/* mask all IRQs	*/
	} else {
		printk(KERN_INFO "IRQ: ISA PIC not found\n");
		host_irq = (unsigned int)-1;
	}

	if (host_irq != (unsigned int)-1) {
		for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) {
			set_irq_chip(irq, &isa_lo_chip);
			set_irq_handler(irq, do_level_IRQ);
			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
		}

		for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) {
			set_irq_chip(irq, &isa_hi_chip);
			set_irq_handler(irq, do_level_IRQ);
			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
		}

		request_resource(&ioport_resource, &pic1_resource);
		request_resource(&ioport_resource, &pic2_resource);
		setup_irq(IRQ_ISA_CASCADE, &irq_cascade);

		set_irq_chained_handler(host_irq, isa_irq_handler);

		/*
		 * On the NetWinder, don't automatically
		 * enable ISA IRQ11 when it is requested.
		 * There appears to be a missing pull-up
		 * resistor on this line.
		 */
		if (machine_is_netwinder())
			set_irq_flags(_ISA_IRQ(11), IRQF_VALID |
				      IRQF_PROBE | IRQF_NOAUTOEN);
	}
}
示例#21
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);

    /*
     * 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);
}
示例#22
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;
}
示例#23
0
static int __devinit lis302dl_probe(struct spi_device *spi)
{
	int rc;
	struct lis302dl_info *lis;
	u_int8_t wai;
	unsigned long flags;
	struct lis302dl_platform_data *pdata = spi->dev.platform_data;

	spi->mode = SPI_MODE_3;
	rc = spi_setup(spi);
	if (rc < 0) {
		dev_err(&spi->dev, "spi_setup failed\n");
		return rc;
	}

	lis = kzalloc(sizeof(*lis), GFP_KERNEL);
	if (!lis)
		return -ENOMEM;

	lis->dev = &spi->dev;
	lis->spi = spi;

	dev_set_drvdata(lis->dev, lis);

	lis->pdata = pdata;

	rc = sysfs_create_group(&lis->dev->kobj, &lis302dl_attr_group);
	if (rc) {
		dev_err(lis->dev, "error creating sysfs group\n");
		goto bail_free_lis;
	}

	/* initialize input layer details */
	lis->input_dev = input_allocate_device();
	if (!lis->input_dev) {
		dev_err(lis->dev, "Unable to allocate input device\n");
		goto bail_sysfs;
	}

	input_set_drvdata(lis->input_dev, lis);
	lis->input_dev->name = pdata->name;
	 /* SPI Bus not defined as a valid bus for input subsystem*/
	lis->input_dev->id.bustype = BUS_I2C; /* lie about it */
	lis->input_dev->open = lis302dl_input_open;
	lis->input_dev->close = lis302dl_input_close;

	rc = input_register_device(lis->input_dev);
	if (rc) {
		dev_err(lis->dev, "error %d registering input device\n", rc);
		goto bail_inp_dev;
	}

	local_irq_save(flags);
	/* Configure our IO */
	(lis->pdata->lis302dl_suspend_io)(lis, 1);

	wai = lis_reg_read(lis, LIS302DL_REG_WHO_AM_I);
	if (wai != LIS302DL_WHO_AM_I_MAGIC) {
		dev_err(lis->dev, "unknown who_am_i signature 0x%02x\n", wai);
		dev_set_drvdata(lis->dev, NULL);
		rc = -ENODEV;
		local_irq_restore(flags);
		goto bail_inp_reg;
	}

	set_bit(EV_ABS, lis->input_dev->evbit);
	input_set_abs_params(lis->input_dev, ABS_X, 0, 0, 0, 0);
	input_set_abs_params(lis->input_dev, ABS_Y, 0, 0, 0, 0);
	input_set_abs_params(lis->input_dev, ABS_Z, 0, 0, 0, 0);

	lis->threshold = 0;
	lis->duration = 0;
	memset(&lis->wakeup, 0, sizeof(lis->wakeup));

	if (__lis302dl_reset_device(lis))
		dev_err(lis->dev, "device BOOT reload failed\n");

	/* force us powered */
	lis_reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD |
			LIS302DL_CTRL1_Xen |
			LIS302DL_CTRL1_Yen |
			LIS302DL_CTRL1_Zen);
	mdelay(1);

	lis_reg_write(lis, LIS302DL_REG_CTRL2, 0);
	lis_reg_write(lis, LIS302DL_REG_CTRL3,
			LIS302DL_CTRL3_PP_OD | LIS302DL_CTRL3_IHL);
	lis_reg_write(lis, LIS302DL_REG_FF_WU_THS_1, 0x0);
	lis_reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, 0x00);
	lis_reg_write(lis, LIS302DL_REG_FF_WU_CFG_1, 0x0);

	/* start off in powered down mode; we power up when someone opens us */
	lis_reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_Xen |
			LIS302DL_CTRL1_Yen | LIS302DL_CTRL1_Zen);

	if (pdata->open_drain)
		/* switch interrupt to open collector, active-low */
		lis_reg_write(lis, LIS302DL_REG_CTRL3,
				LIS302DL_CTRL3_PP_OD | LIS302DL_CTRL3_IHL);
	else
		/* push-pull, active-low */
		lis_reg_write(lis, LIS302DL_REG_CTRL3, LIS302DL_CTRL3_IHL);

	lis302dl_set_int_mode(lis->dev, 1, LIS302DL_INTMODE_GND);
	lis302dl_set_int_mode(lis->dev, 2, LIS302DL_INTMODE_GND);

	lis_reg_read(lis, LIS302DL_REG_STATUS);
	lis_reg_read(lis, LIS302DL_REG_FF_WU_SRC_1);
	lis_reg_read(lis, LIS302DL_REG_FF_WU_SRC_2);
	lis_reg_read(lis, LIS302DL_REG_CLICK_SRC);
	local_irq_restore(flags);

	dev_info(lis->dev, "Found %s\n", pdata->name);

	lis->pdata = pdata;

    INIT_WORK(&lis->work, lis302dl_irq_worker);

    set_irq_handler(lis->pdata->interrupt, handle_level_irq);
    set_irq_type(lis->pdata->interrupt, IRQ_TYPE_LEVEL_LOW);
	rc = request_irq(lis->pdata->interrupt, lis302dl_interrupt,
			 IRQF_TRIGGER_FALLING, "lis302dl", lis);

	if (rc < 0) {
		dev_err(lis->dev, "error requesting IRQ %d\n",
			lis->pdata->interrupt);
		goto bail_inp_reg;
	}
	return 0;

bail_inp_reg:
	input_unregister_device(lis->input_dev);
bail_inp_dev:
	input_free_device(lis->input_dev);
bail_sysfs:
	sysfs_remove_group(&lis->dev->kobj, &lis302dl_attr_group);
bail_free_lis:
	kfree(lis);
	return rc;
}
示例#24
0
void __init arch_init_ipiirq(int irq, struct irqaction *action)
{
	setup_irq(irq, action);
	set_irq_handler(irq, handle_percpu_irq);
}
示例#25
0
static int pm8058_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int	i, rc;
	struct	pm8058_platform_data *pdata = client->dev.platform_data;
	struct	pm8058_chip *chip;

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

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

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

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

	chip->dev = client;

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

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

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

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

	i2c_set_clientdata(client, chip);

	pmic_chip = chip;

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

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

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

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

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

	return 0;
}
示例#26
0
文件: irq.c 项目: ryos36/xen-arm
void gic_dist_init(unsigned int gic_nr, void *base, unsigned int irq_start)
{
        unsigned int max_irq, i;
//      u32 cpumask = 1 << smp_processor_id();
        u32 cpumask = 1 << 0;

        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;

        mmio_writel(0, base + ICDDCR);

        /*
         * Find out how many interrupts are supported.
         */
        max_irq = mmio_readl(base + ICDICTR) & 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);
	}

        /*
         * Set all global interrupts to be level triggered, active low.
         */
        for (i = 32; i < max_irq; i += 16) {
                mmio_writel(0, base + ICDICFR + i * 4 / 16);
	}

        /*
         * Set all global interrupts to this CPU only.
         */
        for (i = 32; i < max_irq; i += 4) {
                mmio_writel(cpumask, base + ICDIPTR + i * 4 / 4);
	}

        /*
         * Set priority on all interrupts.
         */
        for (i = 0; i < max_irq; i += 4) {
                mmio_writel(0xa0a0a0a0, base + ICDIPR + i * 4 / 4);
	}

        /*
         * Disable all interrupts.
         */
        for (i = 0; i < max_irq; i += 32) {
                mmio_writel(0xffffffff, base + ICDICER + i * 4 / 32);
	}

        /*
         * Setup the Linux IRQ subsystem.
         */
        for (i = irq_start; i < max_irq; i++) {
		uint32_t int_config_field;
                set_irq_chip(i, &gic_chip);
                set_irq_chip_data(i, &gic_data[gic_nr]);
		int_config_field = mmio_readl(base + ICDICFR + i * 4 / 16);
		int_config_field >>= (((i % 16) * 2) + 1);
		int_config_field &= 0x1;
		if ( int_config_field ) {
			set_irq_handler(i, edge_irq_handler);
		} else {
			set_irq_handler(i, level_irq_handler);
		}
                set_irq_flags(i, IRQF_VALID);
        }

        mmio_writel(1, base + ICDDCR);
}
示例#27
0
static int msm_gpio_probe(struct platform_device *dev)
{
	struct msm_gpio_dev *msm_gpio;
	struct msm7200a_gpio_platform_data *pdata =
		(struct msm7200a_gpio_platform_data *)dev->dev.platform_data;
	int i, irq, ret;

	if (!pdata)
		return -EINVAL;

	msm_gpio = (struct msm_gpio_dev*)kzalloc(sizeof(struct msm_gpio_dev), GFP_KERNEL);
	if (!msm_gpio)
		return -ENOMEM;

	spin_lock_init(&msm_gpio->lock);
	platform_set_drvdata(dev, msm_gpio);
	memcpy(&msm_gpio->regs,
	       &pdata->regs,
	       sizeof(struct msm7200a_gpio_regs));

	msm_gpio->gpio_chip.label            = dev->name;
	msm_gpio->gpio_chip.base             = pdata->gpio_base;
	msm_gpio->gpio_chip.ngpio            = pdata->ngpio;
	msm_gpio->gpio_chip.direction_input  = gpio_chip_direction_input;
	msm_gpio->gpio_chip.direction_output = gpio_chip_direction_output;
	msm_gpio->gpio_chip.get              = gpio_chip_get;
	msm_gpio->gpio_chip.set              = gpio_chip_set;
	msm_gpio->gpio_chip.to_irq           = gpio_chip_to_irq;
	msm_gpio->irq_base                   = pdata->irq_base;
	msm_gpio->irq_summary                = pdata->irq_summary;

	ret = gpiochip_add(&msm_gpio->gpio_chip);
	if (ret < 0)
		goto err_post_malloc;

	for (i = 0; i < msm_gpio->gpio_chip.ngpio; ++i) {
		irq = msm_gpio->irq_base + i;
		set_irq_chip_data(irq, msm_gpio);
		set_irq_chip(irq, &msm_gpio_irq_chip);
		set_irq_handler(irq, handle_level_irq);
		set_irq_flags(irq, IRQF_VALID);
	}

	/*
	 * We use a level-triggered interrupt because of the nature
	 * of the shared GPIO-group interrupt.
	 *
	 * Many GPIO chips may be sharing the same group IRQ line, and
	 * it is possible for GPIO interrupt to re-occur while the system
	 * is still servicing the group interrupt associated with it.
	 * The group IRQ line would not de-assert and re-assert, and
	 * we'd get no second edge to cause the group IRQ to be handled again.
	 *
	 * Using a level interrupt guarantees that the group IRQ handlers
	 * will continue to be called as long as any GPIO chip in the group
	 * is asserting, even if the condition began while the group
	 * handler was in mid-pass.
	 */
	ret = request_irq(msm_gpio->irq_summary,
			  msm_gpio_irq_handler,
			  IRQF_SHARED | IRQF_TRIGGER_HIGH,
			  dev->name,
			  msm_gpio);
	if (ret < 0)
		goto err_post_gpiochip_add;

#ifdef CONFIG_PM_RUNTIME
	ret = pm_runtime_set_active(&dev->dev);
	if (ret < 0)
		goto err_post_req_irq;
	pm_runtime_enable(&dev->dev);
#endif

	return ret;
#ifdef CONFIG_PM_RUNTIME
err_post_req_irq:
	free_irq(msm_gpio->irq_summary, msm_gpio);
#endif
err_post_gpiochip_add:
	/*
	 * Under no circumstances should a line be held on a gpiochip
	 * which hasn't finished probing.
	 */
	BUG_ON(gpiochip_remove(&msm_gpio->gpio_chip) < 0);
err_post_malloc:
	kfree(msm_gpio);
	return ret;
}
示例#28
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);
	}
}
示例#29
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, do_level_IRQ);
			set_irq_flags(irq, flags);
			break;

		case 8 ... 15:
			set_irq_chip(irq, &clps7500_b_chip);
			set_irq_handler(irq, do_level_IRQ);
			set_irq_flags(irq, flags);
			break;

		case 16 ... 22:
			set_irq_chip(irq, &clps7500_dma_chip);
			set_irq_handler(irq, do_level_IRQ);
			set_irq_flags(irq, flags);
			break;

		case 24 ... 31:
			set_irq_chip(irq, &clps7500_c_chip);
			set_irq_handler(irq, do_level_IRQ);
			set_irq_flags(irq, flags);
			break;

		case 40 ... 47:
			set_irq_chip(irq, &clps7500_d_chip);
			set_irq_handler(irq, do_level_IRQ);
			set_irq_flags(irq, flags);
			break;

		case 48 ... 55:
			set_irq_chip(irq, &clps7500_no_chip);
			set_irq_handler(irq, do_level_IRQ);
			set_irq_flags(irq, flags);
			break;

		case 64 ... 72:
			set_irq_chip(irq, &clps7500_fiq_chip);
			set_irq_handler(irq, do_level_IRQ);
			set_irq_flags(irq, flags);
			break;
		}
	}

	setup_irq(IRQ_ISA, &irq_isa);
}
示例#30
0
文件: irq.c 项目: kzlin129/tt-gpl
void __init s3c24xx_init_irq(void)
{
	unsigned long pend;
	unsigned long last;
	int irqno;
	int i;

	irqdbf("s3c24xx_init_irq: clearing interrupt status flags\n");

	/* first, clear all interrupts pending... */

	last = 0;
	for (i = 0; i < 4; i++) {
		pend = __raw_readl(s3c24xx_eintpend);

		if (pend == 0 || pend == last)
			break;

		__raw_writel(pend, s3c24xx_eintpend);
		printk("irq: clearing pending ext status %08x\n", (int)pend);
		last = pend;
	}

	last = 0;
	for (i = 0; i < 4; i++) {
		pend = __raw_readl(S3C2410_INTPND);

		if (pend == 0 || pend == last)
			break;

		__raw_writel(pend, S3C2410_SRCPND);
		__raw_writel(pend, S3C2410_INTPND);
		printk("irq: clearing pending status %08x\n", (int)pend);
		last = pend;
	}

	last = 0;
	for (i = 0; i < 4; i++) {
		pend = __raw_readl(S3C2410_SUBSRCPND);

		if (pend == 0 || pend == last)
			break;

		printk("irq: clearing subpending status %08x\n", (int)pend);
		__raw_writel(pend, S3C2410_SUBSRCPND);
		last = pend;
	}

	/* register the main interrupts */

	irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");

	for (irqno = IRQ_BATT_FLT; irqno <= IRQ_ADCPARENT; irqno++) {
		/* set all the s3c2410 internal irqs */

		switch (irqno) {
			/* deal with the special IRQs (cascaded) */

		case IRQ_UART0:
		case IRQ_UART1:
		case IRQ_UART2:
		case IRQ_ADCPARENT:
			set_irq_chip(irqno, &s3c_irq_level_chip);
			set_irq_handler(irqno, do_level_IRQ);
			break;

		case IRQ_RESERVED6:
		case IRQ_RESERVED24:
			/* no IRQ here */
			break;

		default:
			//irqdbf("registering irq %d (s3c irq)\n", irqno);
			set_irq_chip(irqno, &s3c_irq_chip);
			set_irq_handler(irqno, do_edge_IRQ);
			set_irq_flags(irqno, IRQF_VALID);
		}
	}

	/* setup the cascade irq handlers */

	set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
	set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
	set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
	set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);


	/* external interrupts */

	for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
		irqdbf("registering irq %d (ext int)\n", irqno);
		set_irq_chip(irqno, &s3c_irq_eint0t4);
		set_irq_handler(irqno, do_edge_IRQ);
		set_irq_flags(irqno, IRQF_VALID);
	}

	for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
		irqdbf("registering irq %d (extended s3c irq)\n", irqno);
		set_irq_chip(irqno, &s3c_irqext_chip);
		set_irq_handler(irqno, do_edge_IRQ);
		set_irq_flags(irqno, IRQF_VALID);
	}

	/* register the uart interrupts */

	irqdbf("s3c2410: registering external interrupts\n");

	for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
		irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
		set_irq_chip(irqno, &s3c_irq_uart0);
		set_irq_handler(irqno, do_level_IRQ);
		set_irq_flags(irqno, IRQF_VALID);
	}

	for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
		irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
		set_irq_chip(irqno, &s3c_irq_uart1);
		set_irq_handler(irqno, do_level_IRQ);
		set_irq_flags(irqno, IRQF_VALID);
	}

	for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
		irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
		set_irq_chip(irqno, &s3c_irq_uart2);
		set_irq_handler(irqno, do_level_IRQ);
		set_irq_flags(irqno, IRQF_VALID);
	}

	for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
		irqdbf("registering irq %d (s3c adc irq)\n", irqno);
		set_irq_chip(irqno, &s3c_irq_adc);
		set_irq_handler(irqno, do_edge_IRQ);
		set_irq_flags(irqno, IRQF_VALID);
	}

	irqdbf("s3c2410: registered interrupt handlers\n");
}