Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (370 commits) ARM: S3C2443: Add set_rate and round_rate calls for armdiv clock ARM: S3C2443: Remove #if 0 for clk_mpll ARM: S3C2443: Update notes on MPLLREF clock ARM: S3C2443: Further clksrc-clk conversions ARM: S3C2443: Change to using plat-samsung clksrc-clk implementation USB: Fix s3c-hsotg build following Samsung platform header moves ARM: S3C64XX: Reintroduce unconditional build of audio device ARM: 5961/1: ux500: fix CLKRST addresses ARM: 5977/1: arm: Enable backtrace printing on oops when PC is corrupted ASoC: Fix S3C64xx IIS driver for Samsung header reorg ARM: S3C2440: Fix plat-s3c24xx move of s3c2440/s3c2442 support [ARM] pxa: fix typo in mxm8x10.h [ARM] pxa/raumfeld: set GPIO drive bits for LED pins [ARM] pxa/zeus: Add support for mcp2515 CAN bus [ARM] pxa/zeus: Add support for onboard max6369 watchdog [ARM] pxa/zeus: Add Eurotech as the manufacturer [ARM] pxa/zeus: Correct the USB host initialisation flags [ARM] pxa/zeus: Allow usage of 8250-compatible UART in uncompress [ARM] pxa: refactor uncompress.h for non-PXA uarts [ARM] mmp2: fix incorrect calling of chip->mask_ack() for 2nd level cascaded IRQs ...
This commit is contained in:
@@ -32,6 +32,12 @@
|
||||
|
||||
#include <asm/hardware/locomo.h>
|
||||
|
||||
/* LoCoMo Interrupts */
|
||||
#define IRQ_LOCOMO_KEY (0)
|
||||
#define IRQ_LOCOMO_GPIO (1)
|
||||
#define IRQ_LOCOMO_LT (2)
|
||||
#define IRQ_LOCOMO_SPI (3)
|
||||
|
||||
/* M62332 output channel selection */
|
||||
#define M62332_EVR_CH 1 /* M62332 volume channel number */
|
||||
/* 0 : CH.1 , 1 : CH. 2 */
|
||||
@@ -58,6 +64,7 @@ struct locomo {
|
||||
struct device *dev;
|
||||
unsigned long phys;
|
||||
unsigned int irq;
|
||||
int irq_base;
|
||||
spinlock_t lock;
|
||||
void __iomem *base;
|
||||
#ifdef CONFIG_PM
|
||||
@@ -81,9 +88,7 @@ struct locomo_dev_info {
|
||||
static struct locomo_dev_info locomo_devices[] = {
|
||||
{
|
||||
.devid = LOCOMO_DEVID_KEYBOARD,
|
||||
.irq = {
|
||||
IRQ_LOCOMO_KEY,
|
||||
},
|
||||
.irq = { IRQ_LOCOMO_KEY },
|
||||
.name = "locomo-keyboard",
|
||||
.offset = LOCOMO_KEYBOARD,
|
||||
.length = 16,
|
||||
@@ -133,53 +138,20 @@ static struct locomo_dev_info locomo_devices[] = {
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/** LoCoMo interrupt handling stuff.
|
||||
* NOTE: LoCoMo has a 1 to many mapping on all of its IRQs.
|
||||
* that is, there is only one real hardware interrupt
|
||||
* we determine which interrupt it is by reading some IO memory.
|
||||
* We have two levels of expansion, first in the handler for the
|
||||
* hardware interrupt we generate an interrupt
|
||||
* IRQ_LOCOMO_*_BASE and those handlers generate more interrupts
|
||||
*
|
||||
* hardware irq reads LOCOMO_ICR & 0x0f00
|
||||
* IRQ_LOCOMO_KEY_BASE
|
||||
* IRQ_LOCOMO_GPIO_BASE
|
||||
* IRQ_LOCOMO_LT_BASE
|
||||
* IRQ_LOCOMO_SPI_BASE
|
||||
* IRQ_LOCOMO_KEY_BASE reads LOCOMO_KIC & 0x0001
|
||||
* IRQ_LOCOMO_KEY
|
||||
* IRQ_LOCOMO_GPIO_BASE reads LOCOMO_GIR & LOCOMO_GPD & 0xffff
|
||||
* IRQ_LOCOMO_GPIO[0-15]
|
||||
* IRQ_LOCOMO_LT_BASE reads LOCOMO_LTINT & 0x0001
|
||||
* IRQ_LOCOMO_LT
|
||||
* IRQ_LOCOMO_SPI_BASE reads LOCOMO_SPIIR & 0x000F
|
||||
* IRQ_LOCOMO_SPI_RFR
|
||||
* IRQ_LOCOMO_SPI_RFW
|
||||
* IRQ_LOCOMO_SPI_OVRN
|
||||
* IRQ_LOCOMO_SPI_TEND
|
||||
*/
|
||||
|
||||
#define LOCOMO_IRQ_START (IRQ_LOCOMO_KEY_BASE)
|
||||
#define LOCOMO_IRQ_KEY_START (IRQ_LOCOMO_KEY)
|
||||
#define LOCOMO_IRQ_GPIO_START (IRQ_LOCOMO_GPIO0)
|
||||
#define LOCOMO_IRQ_LT_START (IRQ_LOCOMO_LT)
|
||||
#define LOCOMO_IRQ_SPI_START (IRQ_LOCOMO_SPI_RFR)
|
||||
|
||||
static void locomo_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct locomo *lchip = get_irq_chip_data(irq);
|
||||
int req, i;
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
|
||||
/* Acknowledge the parent IRQ */
|
||||
desc->chip->ack(irq);
|
||||
|
||||
/* check why this interrupt was generated */
|
||||
req = locomo_readl(mapbase + LOCOMO_ICR) & 0x0f00;
|
||||
req = locomo_readl(lchip->base + LOCOMO_ICR) & 0x0f00;
|
||||
|
||||
if (req) {
|
||||
/* generate the next interrupt(s) */
|
||||
irq = LOCOMO_IRQ_START;
|
||||
irq = lchip->irq_base;
|
||||
for (i = 0; i <= 3; i++, irq++) {
|
||||
if (req & (0x0100 << i)) {
|
||||
generic_handle_irq(irq);
|
||||
@@ -195,20 +167,20 @@ static void locomo_ack_irq(unsigned int irq)
|
||||
|
||||
static void locomo_mask_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
struct locomo *lchip = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_ICR);
|
||||
r &= ~(0x0010 << (irq - LOCOMO_IRQ_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_ICR);
|
||||
r = locomo_readl(lchip->base + LOCOMO_ICR);
|
||||
r &= ~(0x0010 << (irq - lchip->irq_base));
|
||||
locomo_writel(r, lchip->base + LOCOMO_ICR);
|
||||
}
|
||||
|
||||
static void locomo_unmask_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
struct locomo *lchip = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_ICR);
|
||||
r |= (0x0010 << (irq - LOCOMO_IRQ_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_ICR);
|
||||
r = locomo_readl(lchip->base + LOCOMO_ICR);
|
||||
r |= (0x0010 << (irq - lchip->irq_base));
|
||||
locomo_writel(r, lchip->base + LOCOMO_ICR);
|
||||
}
|
||||
|
||||
static struct irq_chip locomo_chip = {
|
||||
@@ -218,297 +190,22 @@ static struct irq_chip locomo_chip = {
|
||||
.unmask = locomo_unmask_irq,
|
||||
};
|
||||
|
||||
static void locomo_key_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
|
||||
if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) {
|
||||
generic_handle_irq(LOCOMO_IRQ_KEY_START);
|
||||
}
|
||||
}
|
||||
|
||||
static void locomo_key_ack_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
|
||||
r &= ~(0x0100 << (irq - LOCOMO_IRQ_KEY_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
|
||||
}
|
||||
|
||||
static void locomo_key_mask_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
|
||||
r &= ~(0x0010 << (irq - LOCOMO_IRQ_KEY_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
|
||||
}
|
||||
|
||||
static void locomo_key_unmask_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
|
||||
r |= (0x0010 << (irq - LOCOMO_IRQ_KEY_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
|
||||
}
|
||||
|
||||
static struct irq_chip locomo_key_chip = {
|
||||
.name = "LOCOMO-key",
|
||||
.ack = locomo_key_ack_irq,
|
||||
.mask = locomo_key_mask_irq,
|
||||
.unmask = locomo_key_unmask_irq,
|
||||
};
|
||||
|
||||
static void locomo_gpio_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
int req, i;
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
|
||||
req = locomo_readl(mapbase + LOCOMO_GIR) &
|
||||
locomo_readl(mapbase + LOCOMO_GPD) &
|
||||
0xffff;
|
||||
|
||||
if (req) {
|
||||
irq = LOCOMO_IRQ_GPIO_START;
|
||||
for (i = 0; i <= 15; i++, irq++) {
|
||||
if (req & (0x0001 << i)) {
|
||||
generic_handle_irq(irq);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void locomo_gpio_ack_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_GWE);
|
||||
r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_GWE);
|
||||
|
||||
r = locomo_readl(mapbase + LOCOMO_GIS);
|
||||
r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_GIS);
|
||||
|
||||
r = locomo_readl(mapbase + LOCOMO_GWE);
|
||||
r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_GWE);
|
||||
}
|
||||
|
||||
static void locomo_gpio_mask_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_GIE);
|
||||
r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_GIE);
|
||||
}
|
||||
|
||||
static void locomo_gpio_unmask_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_GIE);
|
||||
r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_GIE);
|
||||
}
|
||||
|
||||
static int GPIO_IRQ_rising_edge;
|
||||
static int GPIO_IRQ_falling_edge;
|
||||
|
||||
static int locomo_gpio_type(unsigned int irq, unsigned int type)
|
||||
{
|
||||
unsigned int mask;
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
|
||||
mask = 1 << (irq - LOCOMO_IRQ_GPIO_START);
|
||||
|
||||
if (type == IRQ_TYPE_PROBE) {
|
||||
if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
|
||||
return 0;
|
||||
type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
|
||||
}
|
||||
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
GPIO_IRQ_rising_edge |= mask;
|
||||
else
|
||||
GPIO_IRQ_rising_edge &= ~mask;
|
||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
GPIO_IRQ_falling_edge |= mask;
|
||||
else
|
||||
GPIO_IRQ_falling_edge &= ~mask;
|
||||
locomo_writel(GPIO_IRQ_rising_edge, mapbase + LOCOMO_GRIE);
|
||||
locomo_writel(GPIO_IRQ_falling_edge, mapbase + LOCOMO_GFIE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip locomo_gpio_chip = {
|
||||
.name = "LOCOMO-gpio",
|
||||
.ack = locomo_gpio_ack_irq,
|
||||
.mask = locomo_gpio_mask_irq,
|
||||
.unmask = locomo_gpio_unmask_irq,
|
||||
.set_type = locomo_gpio_type,
|
||||
};
|
||||
|
||||
static void locomo_lt_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
|
||||
if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) {
|
||||
generic_handle_irq(LOCOMO_IRQ_LT_START);
|
||||
}
|
||||
}
|
||||
|
||||
static void locomo_lt_ack_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_LTINT);
|
||||
r &= ~(0x0100 << (irq - LOCOMO_IRQ_LT_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_LTINT);
|
||||
}
|
||||
|
||||
static void locomo_lt_mask_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_LTINT);
|
||||
r &= ~(0x0010 << (irq - LOCOMO_IRQ_LT_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_LTINT);
|
||||
}
|
||||
|
||||
static void locomo_lt_unmask_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_LTINT);
|
||||
r |= (0x0010 << (irq - LOCOMO_IRQ_LT_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_LTINT);
|
||||
}
|
||||
|
||||
static struct irq_chip locomo_lt_chip = {
|
||||
.name = "LOCOMO-lt",
|
||||
.ack = locomo_lt_ack_irq,
|
||||
.mask = locomo_lt_mask_irq,
|
||||
.unmask = locomo_lt_unmask_irq,
|
||||
};
|
||||
|
||||
static void locomo_spi_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
int req, i;
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
|
||||
req = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIR) & 0x000F;
|
||||
if (req) {
|
||||
irq = LOCOMO_IRQ_SPI_START;
|
||||
|
||||
for (i = 0; i <= 3; i++, irq++) {
|
||||
if (req & (0x0001 << i)) {
|
||||
generic_handle_irq(irq);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void locomo_spi_ack_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
|
||||
r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
|
||||
|
||||
r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIS);
|
||||
r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIS);
|
||||
|
||||
r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
|
||||
r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
|
||||
}
|
||||
|
||||
static void locomo_spi_mask_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
|
||||
r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
|
||||
}
|
||||
|
||||
static void locomo_spi_unmask_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned int r;
|
||||
r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
|
||||
r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START));
|
||||
locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
|
||||
}
|
||||
|
||||
static struct irq_chip locomo_spi_chip = {
|
||||
.name = "LOCOMO-spi",
|
||||
.ack = locomo_spi_ack_irq,
|
||||
.mask = locomo_spi_mask_irq,
|
||||
.unmask = locomo_spi_unmask_irq,
|
||||
};
|
||||
|
||||
static void locomo_setup_irq(struct locomo *lchip)
|
||||
{
|
||||
int irq;
|
||||
void __iomem *irqbase = lchip->base;
|
||||
int irq = lchip->irq_base;
|
||||
|
||||
/*
|
||||
* Install handler for IRQ_LOCOMO_HW.
|
||||
*/
|
||||
set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
|
||||
set_irq_chip_data(lchip->irq, irqbase);
|
||||
set_irq_chip_data(lchip->irq, lchip);
|
||||
set_irq_chained_handler(lchip->irq, locomo_handler);
|
||||
|
||||
/* Install handlers for IRQ_LOCOMO_*_BASE */
|
||||
set_irq_chip(IRQ_LOCOMO_KEY_BASE, &locomo_chip);
|
||||
set_irq_chip_data(IRQ_LOCOMO_KEY_BASE, irqbase);
|
||||
set_irq_chained_handler(IRQ_LOCOMO_KEY_BASE, locomo_key_handler);
|
||||
|
||||
set_irq_chip(IRQ_LOCOMO_GPIO_BASE, &locomo_chip);
|
||||
set_irq_chip_data(IRQ_LOCOMO_GPIO_BASE, irqbase);
|
||||
set_irq_chained_handler(IRQ_LOCOMO_GPIO_BASE, locomo_gpio_handler);
|
||||
|
||||
set_irq_chip(IRQ_LOCOMO_LT_BASE, &locomo_chip);
|
||||
set_irq_chip_data(IRQ_LOCOMO_LT_BASE, irqbase);
|
||||
set_irq_chained_handler(IRQ_LOCOMO_LT_BASE, locomo_lt_handler);
|
||||
|
||||
set_irq_chip(IRQ_LOCOMO_SPI_BASE, &locomo_chip);
|
||||
set_irq_chip_data(IRQ_LOCOMO_SPI_BASE, irqbase);
|
||||
set_irq_chained_handler(IRQ_LOCOMO_SPI_BASE, locomo_spi_handler);
|
||||
|
||||
/* install handlers for IRQ_LOCOMO_KEY_BASE generated interrupts */
|
||||
set_irq_chip(LOCOMO_IRQ_KEY_START, &locomo_key_chip);
|
||||
set_irq_chip_data(LOCOMO_IRQ_KEY_START, irqbase);
|
||||
set_irq_handler(LOCOMO_IRQ_KEY_START, handle_edge_irq);
|
||||
set_irq_flags(LOCOMO_IRQ_KEY_START, IRQF_VALID | IRQF_PROBE);
|
||||
|
||||
/* install handlers for IRQ_LOCOMO_GPIO_BASE generated interrupts */
|
||||
for (irq = LOCOMO_IRQ_GPIO_START; irq < LOCOMO_IRQ_GPIO_START + 16; irq++) {
|
||||
set_irq_chip(irq, &locomo_gpio_chip);
|
||||
set_irq_chip_data(irq, irqbase);
|
||||
set_irq_handler(irq, handle_edge_irq);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
|
||||
/* install handlers for IRQ_LOCOMO_LT_BASE generated interrupts */
|
||||
set_irq_chip(LOCOMO_IRQ_LT_START, &locomo_lt_chip);
|
||||
set_irq_chip_data(LOCOMO_IRQ_LT_START, irqbase);
|
||||
set_irq_handler(LOCOMO_IRQ_LT_START, handle_edge_irq);
|
||||
set_irq_flags(LOCOMO_IRQ_LT_START, IRQF_VALID | IRQF_PROBE);
|
||||
|
||||
/* install handlers for IRQ_LOCOMO_SPI_BASE generated interrupts */
|
||||
for (irq = LOCOMO_IRQ_SPI_START; irq < LOCOMO_IRQ_SPI_START + 4; irq++) {
|
||||
set_irq_chip(irq, &locomo_spi_chip);
|
||||
set_irq_chip_data(irq, irqbase);
|
||||
set_irq_handler(irq, handle_edge_irq);
|
||||
/* Install handlers for IRQ_LOCOMO_* */
|
||||
for ( ; irq <= lchip->irq_base + 3; irq++) {
|
||||
set_irq_chip(irq, &locomo_chip);
|
||||
set_irq_chip_data(irq, lchip);
|
||||
set_irq_handler(irq, handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
}
|
||||
@@ -555,7 +252,8 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
|
||||
dev->mapbase = 0;
|
||||
dev->length = info->length;
|
||||
|
||||
memmove(dev->irq, info->irq, sizeof(dev->irq));
|
||||
dev->irq[0] = (lchip->irq_base == NO_IRQ) ?
|
||||
NO_IRQ : lchip->irq_base + info->irq[0];
|
||||
|
||||
ret = device_register(&dev->dev);
|
||||
if (ret) {
|
||||
@@ -672,6 +370,7 @@ static int locomo_resume(struct platform_device *dev)
|
||||
static int
|
||||
__locomo_probe(struct device *me, struct resource *mem, int irq)
|
||||
{
|
||||
struct locomo_platform_data *pdata = me->platform_data;
|
||||
struct locomo *lchip;
|
||||
unsigned long r;
|
||||
int i, ret = -ENODEV;
|
||||
@@ -687,6 +386,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
|
||||
|
||||
lchip->phys = mem->start;
|
||||
lchip->irq = irq;
|
||||
lchip->irq_base = (pdata) ? pdata->irq_base : NO_IRQ;
|
||||
|
||||
/*
|
||||
* Map the whole region. This also maps the
|
||||
@@ -753,7 +453,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
|
||||
* The interrupt controller must be initialised before any
|
||||
* other device to ensure that the interrupts are available.
|
||||
*/
|
||||
if (lchip->irq != NO_IRQ)
|
||||
if (lchip->irq != NO_IRQ && lchip->irq_base != NO_IRQ)
|
||||
locomo_setup_irq(lchip);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(locomo_devices); i++)
|
||||
|
@@ -35,6 +35,58 @@
|
||||
|
||||
#include <asm/hardware/sa1111.h>
|
||||
|
||||
/* SA1111 IRQs */
|
||||
#define IRQ_GPAIN0 (0)
|
||||
#define IRQ_GPAIN1 (1)
|
||||
#define IRQ_GPAIN2 (2)
|
||||
#define IRQ_GPAIN3 (3)
|
||||
#define IRQ_GPBIN0 (4)
|
||||
#define IRQ_GPBIN1 (5)
|
||||
#define IRQ_GPBIN2 (6)
|
||||
#define IRQ_GPBIN3 (7)
|
||||
#define IRQ_GPBIN4 (8)
|
||||
#define IRQ_GPBIN5 (9)
|
||||
#define IRQ_GPCIN0 (10)
|
||||
#define IRQ_GPCIN1 (11)
|
||||
#define IRQ_GPCIN2 (12)
|
||||
#define IRQ_GPCIN3 (13)
|
||||
#define IRQ_GPCIN4 (14)
|
||||
#define IRQ_GPCIN5 (15)
|
||||
#define IRQ_GPCIN6 (16)
|
||||
#define IRQ_GPCIN7 (17)
|
||||
#define IRQ_MSTXINT (18)
|
||||
#define IRQ_MSRXINT (19)
|
||||
#define IRQ_MSSTOPERRINT (20)
|
||||
#define IRQ_TPTXINT (21)
|
||||
#define IRQ_TPRXINT (22)
|
||||
#define IRQ_TPSTOPERRINT (23)
|
||||
#define SSPXMTINT (24)
|
||||
#define SSPRCVINT (25)
|
||||
#define SSPROR (26)
|
||||
#define AUDXMTDMADONEA (32)
|
||||
#define AUDRCVDMADONEA (33)
|
||||
#define AUDXMTDMADONEB (34)
|
||||
#define AUDRCVDMADONEB (35)
|
||||
#define AUDTFSR (36)
|
||||
#define AUDRFSR (37)
|
||||
#define AUDTUR (38)
|
||||
#define AUDROR (39)
|
||||
#define AUDDTS (40)
|
||||
#define AUDRDD (41)
|
||||
#define AUDSTO (42)
|
||||
#define IRQ_USBPWR (43)
|
||||
#define IRQ_HCIM (44)
|
||||
#define IRQ_HCIBUFFACC (45)
|
||||
#define IRQ_HCIRMTWKP (46)
|
||||
#define IRQ_NHCIMFCIR (47)
|
||||
#define IRQ_USB_PORT_RESUME (48)
|
||||
#define IRQ_S0_READY_NINT (49)
|
||||
#define IRQ_S1_READY_NINT (50)
|
||||
#define IRQ_S0_CD_VALID (51)
|
||||
#define IRQ_S1_CD_VALID (52)
|
||||
#define IRQ_S0_BVD1_STSCHG (53)
|
||||
#define IRQ_S1_BVD1_STSCHG (54)
|
||||
|
||||
extern void __init sa1110_mb_enable(void);
|
||||
|
||||
/*
|
||||
@@ -49,6 +101,7 @@ struct sa1111 {
|
||||
struct clk *clk;
|
||||
unsigned long phys;
|
||||
int irq;
|
||||
int irq_base; /* base for cascaded on-chip IRQs */
|
||||
spinlock_t lock;
|
||||
void __iomem *base;
|
||||
#ifdef CONFIG_PM
|
||||
@@ -152,36 +205,37 @@ static void
|
||||
sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
unsigned int stat0, stat1, i;
|
||||
void __iomem *base = get_irq_data(irq);
|
||||
struct sa1111 *sachip = get_irq_data(irq);
|
||||
void __iomem *mapbase = sachip->base + SA1111_INTC;
|
||||
|
||||
stat0 = sa1111_readl(base + SA1111_INTSTATCLR0);
|
||||
stat1 = sa1111_readl(base + SA1111_INTSTATCLR1);
|
||||
stat0 = sa1111_readl(mapbase + SA1111_INTSTATCLR0);
|
||||
stat1 = sa1111_readl(mapbase + SA1111_INTSTATCLR1);
|
||||
|
||||
sa1111_writel(stat0, base + SA1111_INTSTATCLR0);
|
||||
sa1111_writel(stat0, mapbase + SA1111_INTSTATCLR0);
|
||||
|
||||
desc->chip->ack(irq);
|
||||
|
||||
sa1111_writel(stat1, base + SA1111_INTSTATCLR1);
|
||||
sa1111_writel(stat1, mapbase + SA1111_INTSTATCLR1);
|
||||
|
||||
if (stat0 == 0 && stat1 == 0) {
|
||||
do_bad_IRQ(irq, desc);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1)
|
||||
for (i = 0; stat0; i++, stat0 >>= 1)
|
||||
if (stat0 & 1)
|
||||
handle_edge_irq(i, irq_desc + i);
|
||||
generic_handle_irq(i + sachip->irq_base);
|
||||
|
||||
for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1)
|
||||
for (i = 32; stat1; i++, stat1 >>= 1)
|
||||
if (stat1 & 1)
|
||||
handle_edge_irq(i, irq_desc + i);
|
||||
generic_handle_irq(i + sachip->irq_base);
|
||||
|
||||
/* For level-based interrupts */
|
||||
desc->chip->unmask(irq);
|
||||
}
|
||||
|
||||
#define SA1111_IRQMASK_LO(x) (1 << (x - IRQ_SA1111_START))
|
||||
#define SA1111_IRQMASK_HI(x) (1 << (x - IRQ_SA1111_START - 32))
|
||||
#define SA1111_IRQMASK_LO(x) (1 << (x - sachip->irq_base))
|
||||
#define SA1111_IRQMASK_HI(x) (1 << (x - sachip->irq_base - 32))
|
||||
|
||||
static void sa1111_ack_irq(unsigned int irq)
|
||||
{
|
||||
@@ -189,7 +243,8 @@ static void sa1111_ack_irq(unsigned int irq)
|
||||
|
||||
static void sa1111_mask_lowirq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
struct sa1111 *sachip = get_irq_chip_data(irq);
|
||||
void __iomem *mapbase = sachip->base + SA1111_INTC;
|
||||
unsigned long ie0;
|
||||
|
||||
ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
|
||||
@@ -199,7 +254,8 @@ static void sa1111_mask_lowirq(unsigned int irq)
|
||||
|
||||
static void sa1111_unmask_lowirq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
struct sa1111 *sachip = get_irq_chip_data(irq);
|
||||
void __iomem *mapbase = sachip->base + SA1111_INTC;
|
||||
unsigned long ie0;
|
||||
|
||||
ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
|
||||
@@ -216,8 +272,9 @@ static void sa1111_unmask_lowirq(unsigned int irq)
|
||||
*/
|
||||
static int sa1111_retrigger_lowirq(unsigned int irq)
|
||||
{
|
||||
struct sa1111 *sachip = get_irq_chip_data(irq);
|
||||
void __iomem *mapbase = sachip->base + SA1111_INTC;
|
||||
unsigned int mask = SA1111_IRQMASK_LO(irq);
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned long ip0;
|
||||
int i;
|
||||
|
||||
@@ -237,8 +294,9 @@ static int sa1111_retrigger_lowirq(unsigned int irq)
|
||||
|
||||
static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
|
||||
{
|
||||
struct sa1111 *sachip = get_irq_chip_data(irq);
|
||||
void __iomem *mapbase = sachip->base + SA1111_INTC;
|
||||
unsigned int mask = SA1111_IRQMASK_LO(irq);
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned long ip0;
|
||||
|
||||
if (flags == IRQ_TYPE_PROBE)
|
||||
@@ -260,8 +318,9 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
|
||||
|
||||
static int sa1111_wake_lowirq(unsigned int irq, unsigned int on)
|
||||
{
|
||||
struct sa1111 *sachip = get_irq_chip_data(irq);
|
||||
void __iomem *mapbase = sachip->base + SA1111_INTC;
|
||||
unsigned int mask = SA1111_IRQMASK_LO(irq);
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned long we0;
|
||||
|
||||
we0 = sa1111_readl(mapbase + SA1111_WAKEEN0);
|
||||
@@ -286,7 +345,8 @@ static struct irq_chip sa1111_low_chip = {
|
||||
|
||||
static void sa1111_mask_highirq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
struct sa1111 *sachip = get_irq_chip_data(irq);
|
||||
void __iomem *mapbase = sachip->base + SA1111_INTC;
|
||||
unsigned long ie1;
|
||||
|
||||
ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
|
||||
@@ -296,7 +356,8 @@ static void sa1111_mask_highirq(unsigned int irq)
|
||||
|
||||
static void sa1111_unmask_highirq(unsigned int irq)
|
||||
{
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
struct sa1111 *sachip = get_irq_chip_data(irq);
|
||||
void __iomem *mapbase = sachip->base + SA1111_INTC;
|
||||
unsigned long ie1;
|
||||
|
||||
ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
|
||||
@@ -313,8 +374,9 @@ static void sa1111_unmask_highirq(unsigned int irq)
|
||||
*/
|
||||
static int sa1111_retrigger_highirq(unsigned int irq)
|
||||
{
|
||||
struct sa1111 *sachip = get_irq_chip_data(irq);
|
||||
void __iomem *mapbase = sachip->base + SA1111_INTC;
|
||||
unsigned int mask = SA1111_IRQMASK_HI(irq);
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned long ip1;
|
||||
int i;
|
||||
|
||||
@@ -334,8 +396,9 @@ static int sa1111_retrigger_highirq(unsigned int irq)
|
||||
|
||||
static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
|
||||
{
|
||||
struct sa1111 *sachip = get_irq_chip_data(irq);
|
||||
void __iomem *mapbase = sachip->base + SA1111_INTC;
|
||||
unsigned int mask = SA1111_IRQMASK_HI(irq);
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned long ip1;
|
||||
|
||||
if (flags == IRQ_TYPE_PROBE)
|
||||
@@ -357,8 +420,9 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
|
||||
|
||||
static int sa1111_wake_highirq(unsigned int irq, unsigned int on)
|
||||
{
|
||||
struct sa1111 *sachip = get_irq_chip_data(irq);
|
||||
void __iomem *mapbase = sachip->base + SA1111_INTC;
|
||||
unsigned int mask = SA1111_IRQMASK_HI(irq);
|
||||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned long we1;
|
||||
|
||||
we1 = sa1111_readl(mapbase + SA1111_WAKEEN1);
|
||||
@@ -412,14 +476,14 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
|
||||
|
||||
for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
|
||||
set_irq_chip(irq, &sa1111_low_chip);
|
||||
set_irq_chip_data(irq, irqbase);
|
||||
set_irq_chip_data(irq, sachip);
|
||||
set_irq_handler(irq, handle_edge_irq);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
|
||||
for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) {
|
||||
set_irq_chip(irq, &sa1111_high_chip);
|
||||
set_irq_chip_data(irq, irqbase);
|
||||
set_irq_chip_data(irq, sachip);
|
||||
set_irq_handler(irq, handle_edge_irq);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
@@ -428,7 +492,7 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
|
||||
* Register SA1111 interrupt
|
||||
*/
|
||||
set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
|
||||
set_irq_data(sachip->irq, irqbase);
|
||||
set_irq_data(sachip->irq, sachip);
|
||||
set_irq_chained_handler(sachip->irq, sa1111_irq_handler);
|
||||
}
|
||||
|
||||
|
@@ -140,6 +140,7 @@ EXPORT_SYMBOL(reset_scoop);
|
||||
EXPORT_SYMBOL(read_scoop_reg);
|
||||
EXPORT_SYMBOL(write_scoop_reg);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static void check_scoop_reg(struct scoop_dev *sdev)
|
||||
{
|
||||
unsigned short mcr;
|
||||
@@ -149,7 +150,6 @@ static void check_scoop_reg(struct scoop_dev *sdev)
|
||||
iowrite16(0x0101, sdev->base + SCOOP_MCR);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int scoop_suspend(struct platform_device *dev, pm_message_t state)
|
||||
{
|
||||
struct scoop_dev *sdev = platform_get_drvdata(dev);
|
||||
|
Reference in New Issue
Block a user