Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f44ddba3 authored by Heiko Stuebner's avatar Heiko Stuebner Committed by Kukjin Kim
Browse files

ARM: S3C24XX: transform s3c2443 subirqs into new structure



Share the common irq code by simply defining a correct mapping declaration
for the s3c2443.

Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Signed-off-by: default avatarKukjin Kim <kgene.kim@samsung.com>
parent b499b7a8
Loading
Loading
Loading
Loading
+75 −214
Original line number Original line Diff line number Diff line
@@ -732,230 +732,91 @@ void __init s3c2416_init_irq(void)
#endif
#endif


#ifdef CONFIG_CPU_S3C2443
#ifdef CONFIG_CPU_S3C2443
#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
static struct s3c_irq_data init_s3c2443base[32] = {

	{ .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
	{ .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
{
	{ .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
	unsigned int subsrc, submsk;
	{ .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
	unsigned int end;
	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */

	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
	/* read the current pending interrupts, and the mask
	{ .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
	 * for what it is available */
	{ .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */

	{ .type = S3C_IRQTYPE_EDGE, }, /* TICK */
	subsrc = __raw_readl(S3C2410_SUBSRCPND);
	{ .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
	submsk = __raw_readl(S3C2410_INTSUBMSK);
	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */

	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
	subsrc  &= ~submsk;
	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
	subsrc >>= (irq - S3C2410_IRQSUB(0));
	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
	subsrc  &= (1 << len)-1;
	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */

	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
	end = len + irq;
	{ .type = S3C_IRQTYPE_LEVEL, }, /* LCD */

	{ .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
	for (; irq < end && subsrc; irq++) {
	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
		if (subsrc & 1)
	{ .type = S3C_IRQTYPE_EDGE, }, /* CFON */
			generic_handle_irq(irq);
	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */

	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
		subsrc >>= 1;
	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
	}
	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
}
	{ .type = S3C_IRQTYPE_EDGE, }, /* NAND */

	{ .type = S3C_IRQTYPE_EDGE, }, /* USBD */
/* WDT/AC97 sub interrupts */
	{ .type = S3C_IRQTYPE_EDGE, }, /* USBH */

	{ .type = S3C_IRQTYPE_EDGE, }, /* IIC */
static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
{
	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
	s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
	{ .type = S3C_IRQTYPE_EDGE, }, /* RTC */
}
	{ .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */

#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)

static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
{
	s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
}

static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
{
	s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
}

static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
{
	s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
}

static struct irq_chip s3c2443_irq_wdtac97 = {
	.irq_mask	= s3c2443_irq_wdtac97_mask,
	.irq_unmask	= s3c2443_irq_wdtac97_unmask,
	.irq_ack	= s3c2443_irq_wdtac97_ack,
};

/* LCD sub interrupts */

static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
{
	s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
}

#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)

static void s3c2443_irq_lcd_mask(struct irq_data *data)
{
	s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
}

static void s3c2443_irq_lcd_unmask(struct irq_data *data)
{
	s3c_irqsub_unmask(data->irq, INTMSK_LCD);
}

static void s3c2443_irq_lcd_ack(struct irq_data *data)
{
	s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
}

static struct irq_chip s3c2443_irq_lcd = {
	.irq_mask	= s3c2443_irq_lcd_mask,
	.irq_unmask	= s3c2443_irq_lcd_unmask,
	.irq_ack	= s3c2443_irq_lcd_ack,
};

/* DMA sub interrupts */

static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
{
	s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
}

#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)

static void s3c2443_irq_dma_mask(struct irq_data *data)
{
	s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
}

static void s3c2443_irq_dma_unmask(struct irq_data *data)
{
	s3c_irqsub_unmask(data->irq, INTMSK_DMA);
}

static void s3c2443_irq_dma_ack(struct irq_data *data)
{
	s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
}

static struct irq_chip s3c2443_irq_dma = {
	.irq_mask	= s3c2443_irq_dma_mask,
	.irq_unmask	= s3c2443_irq_dma_unmask,
	.irq_ack	= s3c2443_irq_dma_ack,
};

/* UART3 sub interrupts */

static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
{
	s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
}

#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
#define SUBMSK_UART3	(0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))

static void s3c2443_irq_uart3_mask(struct irq_data *data)
{
	s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
}

static void s3c2443_irq_uart3_unmask(struct irq_data *data)
{
	s3c_irqsub_unmask(data->irq, INTMSK_UART3);
}

static void s3c2443_irq_uart3_ack(struct irq_data *data)
{
	s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
}

static struct irq_chip s3c2443_irq_uart3 = {
	.irq_mask	= s3c2443_irq_uart3_mask,
	.irq_unmask	= s3c2443_irq_uart3_unmask,
	.irq_ack	= s3c2443_irq_uart3_ack,
};
};


/* CAM sub interrupts */


static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
static struct s3c_irq_data init_s3c2443subint[32] = {
{
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
	s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
}
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */

	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
#define INTMSK_CAM	(1UL << (IRQ_CAM - IRQ_EINT0))
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
#define SUBMSK_CAM	INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */

	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
static void s3c2443_irq_cam_mask(struct irq_data *data)
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
{
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
	s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
}
	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */

	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
static void s3c2443_irq_cam_unmask(struct irq_data *data)
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
{
	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
	s3c_irqsub_unmask(data->irq, INTMSK_CAM);
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD1 */
}
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */

	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
static void s3c2443_irq_cam_ack(struct irq_data *data)
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
{
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
	s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
}
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */

	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
static struct irq_chip s3c2443_irq_cam = {
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
	.irq_mask	= s3c2443_irq_cam_mask,
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
	.irq_unmask	= s3c2443_irq_cam_unmask,
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
	.irq_ack	= s3c2443_irq_cam_ack,
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
};
};


/* IRQ initialisation code */

static int s3c2443_add_sub(unsigned int base,
				   void (*demux)(unsigned int,
						 struct irq_desc *),
				   struct irq_chip *chip,
				   unsigned int start, unsigned int end)
{
	unsigned int irqno;

	irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
	irq_set_chained_handler(base, demux);

	for (irqno = start; irqno <= end; irqno++) {
		irq_set_chip_and_handler(irqno, chip, handle_level_irq);
		set_irq_flags(irqno, IRQF_VALID);
	}

	return 0;
}

void __init s3c2443_init_irq(void)
void __init s3c2443_init_irq(void)
{
{
	pr_info("S3C2443: IRQ Support\n");
	struct s3c_irq_intc *main_intc;

	s3c24xx_init_irq();

	s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
			IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);


	s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
	pr_info("S3C2443: IRQ Support\n");
			IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);


	s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
#ifdef CONFIG_FIQ
			&s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
	init_FIQ(FIQ_START);
#endif


	s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
	main_intc = s3c24xx_init_intc(NULL, &init_s3c2443base[0], NULL, 0x4a000000);
			&s3c2443_irq_uart3,
	if (IS_ERR(main_intc)) {
			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
		pr_err("irq: could not create main interrupt controller\n");
		return;
	}


	s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
	s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
			&s3c2443_irq_wdtac97,
	s3c24xx_init_intc(NULL, &init_s3c2443subint[0], main_intc, 0x4a000018);
			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
}
}
#endif
#endif