165fa22b73f95c481db125ba9a34de1553c638548Ben Dooks/* linux/arch/arm/plat-s3c24xx/irq-om.c
265fa22b73f95c481db125ba9a34de1553c638548Ben Dooks *
3e02f866456ec31d20649670e3af048ddc2a3892bBen Dooks * Copyright (c) 2003-2004 Simtec Electronics
465fa22b73f95c481db125ba9a34de1553c638548Ben Dooks *	Ben Dooks <ben@simtec.co.uk>
565fa22b73f95c481db125ba9a34de1553c638548Ben Dooks *	http://armlinux.simtec.co.uk/
665fa22b73f95c481db125ba9a34de1553c638548Ben Dooks *
765fa22b73f95c481db125ba9a34de1553c638548Ben Dooks * S3C24XX - IRQ PM code
865fa22b73f95c481db125ba9a34de1553c638548Ben Dooks *
965fa22b73f95c481db125ba9a34de1553c638548Ben Dooks * This program is free software; you can redistribute it and/or modify
1065fa22b73f95c481db125ba9a34de1553c638548Ben Dooks * it under the terms of the GNU General Public License version 2 as
1165fa22b73f95c481db125ba9a34de1553c638548Ben Dooks * published by the Free Software Foundation.
1265fa22b73f95c481db125ba9a34de1553c638548Ben Dooks */
1365fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
1465fa22b73f95c481db125ba9a34de1553c638548Ben Dooks#include <linux/init.h>
1565fa22b73f95c481db125ba9a34de1553c638548Ben Dooks#include <linux/module.h>
1665fa22b73f95c481db125ba9a34de1553c638548Ben Dooks#include <linux/interrupt.h>
1757436c2db4426c5dcbaaba0acd5204f5fa71b762Lennert Buytenhek#include <linux/irq.h>
1865fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
1965fa22b73f95c481db125ba9a34de1553c638548Ben Dooks#include <plat/cpu.h>
2065fa22b73f95c481db125ba9a34de1553c638548Ben Dooks#include <plat/pm.h>
2165fa22b73f95c481db125ba9a34de1553c638548Ben Dooks#include <plat/irq.h>
2265fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
2357436c2db4426c5dcbaaba0acd5204f5fa71b762Lennert Buytenhek#include <asm/irq.h>
2457436c2db4426c5dcbaaba0acd5204f5fa71b762Lennert Buytenhek
2565fa22b73f95c481db125ba9a34de1553c638548Ben Dooks/* state for IRQs over sleep */
2665fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
2765fa22b73f95c481db125ba9a34de1553c638548Ben Dooks/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
2865fa22b73f95c481db125ba9a34de1553c638548Ben Dooks *
2965fa22b73f95c481db125ba9a34de1553c638548Ben Dooks * set bit to 1 in allow bitfield to enable the wakeup settings on it
3065fa22b73f95c481db125ba9a34de1553c638548Ben Dooks*/
3165fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
3265fa22b73f95c481db125ba9a34de1553c638548Ben Dooksunsigned long s3c_irqwake_intallow	= 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
3365fa22b73f95c481db125ba9a34de1553c638548Ben Dooksunsigned long s3c_irqwake_eintallow	= 0x0000fff0L;
3465fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
3557436c2db4426c5dcbaaba0acd5204f5fa71b762Lennert Buytenhekint s3c_irq_wake(struct irq_data *data, unsigned int state)
3665fa22b73f95c481db125ba9a34de1553c638548Ben Dooks{
3757436c2db4426c5dcbaaba0acd5204f5fa71b762Lennert Buytenhek	unsigned long irqbit = 1 << (data->irq - IRQ_EINT0);
3865fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
3965fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	if (!(s3c_irqwake_intallow & irqbit))
4065fa22b73f95c481db125ba9a34de1553c638548Ben Dooks		return -ENOENT;
4165fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
4265fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	printk(KERN_INFO "wake %s for irq %d\n",
4357436c2db4426c5dcbaaba0acd5204f5fa71b762Lennert Buytenhek	       state ? "enabled" : "disabled", data->irq);
4465fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
4565fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	if (!state)
4665fa22b73f95c481db125ba9a34de1553c638548Ben Dooks		s3c_irqwake_intmask |= irqbit;
4765fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	else
4865fa22b73f95c481db125ba9a34de1553c638548Ben Dooks		s3c_irqwake_intmask &= ~irqbit;
4965fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
5065fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	return 0;
5165fa22b73f95c481db125ba9a34de1553c638548Ben Dooks}
5265fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
5365fa22b73f95c481db125ba9a34de1553c638548Ben Dooksstatic struct sleep_save irq_save[] = {
5465fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	SAVE_ITEM(S3C2410_INTMSK),
5565fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	SAVE_ITEM(S3C2410_INTSUBMSK),
5665fa22b73f95c481db125ba9a34de1553c638548Ben Dooks};
5765fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
5865fa22b73f95c481db125ba9a34de1553c638548Ben Dooks/* the extint values move between the s3c2410/s3c2440 and the s3c2412
5965fa22b73f95c481db125ba9a34de1553c638548Ben Dooks * so we use an array to hold them, and to calculate the address of
6065fa22b73f95c481db125ba9a34de1553c638548Ben Dooks * the register at run-time
6165fa22b73f95c481db125ba9a34de1553c638548Ben Dooks*/
6265fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
6365fa22b73f95c481db125ba9a34de1553c638548Ben Dooksstatic unsigned long save_extint[3];
6465fa22b73f95c481db125ba9a34de1553c638548Ben Dooksstatic unsigned long save_eintflt[4];
6565fa22b73f95c481db125ba9a34de1553c638548Ben Dooksstatic unsigned long save_eintmask;
6665fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
67bb072c3cf21d1c9a5a2eeb5a00679ee7bf39675bRafael J. Wysockiint s3c24xx_irq_suspend(void)
6865fa22b73f95c481db125ba9a34de1553c638548Ben Dooks{
6965fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	unsigned int i;
7065fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
7165fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
7265fa22b73f95c481db125ba9a34de1553c638548Ben Dooks		save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
7365fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
7465fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
7565fa22b73f95c481db125ba9a34de1553c638548Ben Dooks		save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
7665fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
7765fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
7865fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	save_eintmask = __raw_readl(S3C24XX_EINTMASK);
7965fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
8065fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	return 0;
8165fa22b73f95c481db125ba9a34de1553c638548Ben Dooks}
8265fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
83bb072c3cf21d1c9a5a2eeb5a00679ee7bf39675bRafael J. Wysockivoid s3c24xx_irq_resume(void)
8465fa22b73f95c481db125ba9a34de1553c638548Ben Dooks{
8565fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	unsigned int i;
8665fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
8765fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
8865fa22b73f95c481db125ba9a34de1553c638548Ben Dooks		__raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
8965fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
9065fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
9165fa22b73f95c481db125ba9a34de1553c638548Ben Dooks		__raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
9265fa22b73f95c481db125ba9a34de1553c638548Ben Dooks
9365fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
9465fa22b73f95c481db125ba9a34de1553c638548Ben Dooks	__raw_writel(save_eintmask, S3C24XX_EINTMASK);
9565fa22b73f95c481db125ba9a34de1553c638548Ben Dooks}
96