forked from Minki/linux
9bc747bea5
These cleanups are basically all over the place. The idea is to collect changes with minimal impact but large number of changes so we can avoid them from distracting in the diffstat in the other series. A significant number of lines get removed here, in particular because the ixp2000 and ixp23xx platforms get removed. These have never been extremely popular and have fallen into disuse over time with no active maintainer taking care of them. The u5500 soc never made it into a product, so we are removing it from the ux500 platform. Many good cleanups also went into the at91 and omap platforms, as has been the case for a number of releases. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJPuemiAAoJEIwa5zzehBx3L9oQAKiu0bsCiT6BM3VC5VGpluk7 YVLH/fkYGdSUTeGrpjeaoxxZnN5M1CLwErg3DxWcyYidy0zfmqitC8t2KQxZMxuf bt+hn4flpFnXMNm31B9xBCXOOVAvteZHYS35FdSKGyWo5Kz2WKM8ZrrihkAA7jVi U75x4+shFPtIhLNg2sJg4e/9D1T14ypElB7W989NzxMtco5fbukVd6vDBHPlFDG3 RVI2z2MbWUj3HVmdoyB+09ekruys0MQsbPOGo8D4aeJicrli/JBtL1r1w6ZZ6I8v Pe0+CbgemMWS69I37Zuxt35Bejpdofa8nKhT1jBrH4uHYxroKkhhx+VMTtuCcFVw Q2DhbbHImiW3598c0jkGi7Gk+TalTxkStMQiO3bqYAHApftdqFUgkpFSnOC/Jxgj Y6nUmd+GVPS+r0dDwZg4z5/AnUQd6t8Azp784muPDDxgTV1ZfdaC0LlLjdWesvMO x+PQib/U7NdxN5lifV6xCXpPoCQsgshrOkVUQiKVHmzaghm9MXgB8qrzXdTz3dLL XtR3+1KmSDTfHPSlTq/9vIN4RJtsKUnDWzNViTElEql36KzT7l5mJnBe6CJWirJh 7JNyH0p6XDZfc2q7LgdiSU0dv/j9LzBaYUukQCyUI3Tk+5zKgAdKbYNJpRcfPuoO BK6OKbjCAoAHL+/nDU2s =Hcjs -----END PGP SIGNATURE----- Merge tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc Pull first batch of arm-soc cleanups from Olof Johansson: "These cleanups are basically all over the place. The idea is to collect changes with minimal impact but large number of changes so we can avoid them from distracting in the diffstat in the other series. A significant number of lines get removed here, in particular because the ixp2000 and ixp23xx platforms get removed. These have never been extremely popular and have fallen into disuse over time with no active maintainer taking care of them. The u5500 soc never made it into a product, so we are removing it from the ux500 platform. Many good cleanups also went into the at91 and omap platforms, as has been the case for a number of releases." Trivial modify-delete conflicts in arch/arm/mach-{ixp2000,ixp23xx} * tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (152 commits) ARM: clps711x: Cleanup IRQ handling ARM clps711x: Removed unused header mach/time.h ARM: clps711x: Added note about support EP731x CPU to Kconfig ARM: clps711x: Added missing register definitions ARM: clps711x: Used own subarch directory for store header file Dove: Fix Section mismatch warnings ARM: orion5x: ts78xx debugging changes ARM: orion5x: remove PM dependency from ts78xx ARM: orion5x: ts78xx fix NAND resource off by one ARM: orion5x: ts78xx whitespace cleanups Orion5x: Fix Section mismatch warnings Orion5x: Fix warning: struct pci_dev declared inside paramter list ARM: clps711x: Combine header files into one for clps711x-targets ARM: S3C24XX: Use common macro to define resources on mach-qt2410.c ARM: S3C24XX: Use common macro to define resources on mach-osiris.c ARM: EXYNOS: Adapt to cpuidle core time keeping and irq enable ARM: S5PV210: Use common macro to define resources on mach-smdkv210.c ARM: S5PV210: Use common macro to define resources on dev-audio.c ARM: S5PC100: Use common macro to define resources on dev-audio.c ARM: S5P64X0: Use common macro to define resources on dev-audio.c ...
159 lines
4.4 KiB
C
159 lines
4.4 KiB
C
/*
|
|
* Amstrad E3 FIQ handling
|
|
*
|
|
* Copyright (C) 2009 Janusz Krzysztofik
|
|
* Copyright (c) 2006 Matt Callow
|
|
* Copyright (c) 2004 Amstrad Plc
|
|
* Copyright (C) 2001 RidgeRun, Inc.
|
|
*
|
|
* Parts of this code are taken from linux/arch/arm/mach-omap/irq.c
|
|
* in the MontaVista 2.4 kernel (and the Amstrad changes therein)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 as published by
|
|
* the Free Software Foundation.
|
|
*/
|
|
#include <linux/gpio.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/irq.h>
|
|
#include <linux/module.h>
|
|
#include <linux/io.h>
|
|
|
|
#include <plat/board-ams-delta.h>
|
|
|
|
#include <asm/fiq.h>
|
|
|
|
#include <mach/ams-delta-fiq.h>
|
|
|
|
static struct fiq_handler fh = {
|
|
.name = "ams-delta-fiq"
|
|
};
|
|
|
|
/*
|
|
* This buffer is shared between FIQ and IRQ contexts.
|
|
* The FIQ and IRQ isrs can both read and write it.
|
|
* It is structured as a header section several 32bit slots,
|
|
* followed by the circular buffer where the FIQ isr stores
|
|
* keystrokes received from the qwerty keyboard.
|
|
* See ams-delta-fiq.h for details of offsets.
|
|
*/
|
|
unsigned int fiq_buffer[1024];
|
|
EXPORT_SYMBOL(fiq_buffer);
|
|
|
|
static unsigned int irq_counter[16];
|
|
|
|
static irqreturn_t deferred_fiq(int irq, void *dev_id)
|
|
{
|
|
struct irq_desc *irq_desc;
|
|
struct irq_chip *irq_chip = NULL;
|
|
int gpio, irq_num, fiq_count;
|
|
|
|
irq_desc = irq_to_desc(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK));
|
|
if (irq_desc)
|
|
irq_chip = irq_desc->irq_data.chip;
|
|
|
|
/*
|
|
* For each handled GPIO interrupt, keep calling its interrupt handler
|
|
* until the IRQ counter catches the FIQ incremented interrupt counter.
|
|
*/
|
|
for (gpio = AMS_DELTA_GPIO_PIN_KEYBRD_CLK;
|
|
gpio <= AMS_DELTA_GPIO_PIN_HOOK_SWITCH; gpio++) {
|
|
irq_num = gpio_to_irq(gpio);
|
|
fiq_count = fiq_buffer[FIQ_CNT_INT_00 + gpio];
|
|
|
|
while (irq_counter[gpio] < fiq_count) {
|
|
if (gpio != AMS_DELTA_GPIO_PIN_KEYBRD_CLK) {
|
|
struct irq_data *d = irq_get_irq_data(irq_num);
|
|
|
|
/*
|
|
* It looks like handle_edge_irq() that
|
|
* OMAP GPIO edge interrupts default to,
|
|
* expects interrupt already unmasked.
|
|
*/
|
|
if (irq_chip && irq_chip->irq_unmask)
|
|
irq_chip->irq_unmask(d);
|
|
}
|
|
generic_handle_irq(irq_num);
|
|
|
|
irq_counter[gpio]++;
|
|
}
|
|
}
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
void __init ams_delta_init_fiq(void)
|
|
{
|
|
void *fiqhandler_start;
|
|
unsigned int fiqhandler_length;
|
|
struct pt_regs FIQ_regs;
|
|
unsigned long val, offset;
|
|
int i, retval;
|
|
|
|
fiqhandler_start = &qwerty_fiqin_start;
|
|
fiqhandler_length = &qwerty_fiqin_end - &qwerty_fiqin_start;
|
|
pr_info("Installing fiq handler from %p, length 0x%x\n",
|
|
fiqhandler_start, fiqhandler_length);
|
|
|
|
retval = claim_fiq(&fh);
|
|
if (retval) {
|
|
pr_err("ams_delta_init_fiq(): couldn't claim FIQ, ret=%d\n",
|
|
retval);
|
|
return;
|
|
}
|
|
|
|
retval = request_irq(INT_DEFERRED_FIQ, deferred_fiq,
|
|
IRQ_TYPE_EDGE_RISING, "deferred_fiq", NULL);
|
|
if (retval < 0) {
|
|
pr_err("Failed to get deferred_fiq IRQ, ret=%d\n", retval);
|
|
release_fiq(&fh);
|
|
return;
|
|
}
|
|
/*
|
|
* Since no set_type() method is provided by OMAP irq chip,
|
|
* switch to edge triggered interrupt type manually.
|
|
*/
|
|
offset = IRQ_ILR0_REG_OFFSET + INT_DEFERRED_FIQ * 0x4;
|
|
val = omap_readl(DEFERRED_FIQ_IH_BASE + offset) & ~(1 << 1);
|
|
omap_writel(val, DEFERRED_FIQ_IH_BASE + offset);
|
|
|
|
set_fiq_handler(fiqhandler_start, fiqhandler_length);
|
|
|
|
/*
|
|
* Initialise the buffer which is shared
|
|
* between FIQ mode and IRQ mode
|
|
*/
|
|
fiq_buffer[FIQ_GPIO_INT_MASK] = 0;
|
|
fiq_buffer[FIQ_MASK] = 0;
|
|
fiq_buffer[FIQ_STATE] = 0;
|
|
fiq_buffer[FIQ_KEY] = 0;
|
|
fiq_buffer[FIQ_KEYS_CNT] = 0;
|
|
fiq_buffer[FIQ_KEYS_HICNT] = 0;
|
|
fiq_buffer[FIQ_TAIL_OFFSET] = 0;
|
|
fiq_buffer[FIQ_HEAD_OFFSET] = 0;
|
|
fiq_buffer[FIQ_BUF_LEN] = 256;
|
|
fiq_buffer[FIQ_MISSED_KEYS] = 0;
|
|
fiq_buffer[FIQ_BUFFER_START] =
|
|
(unsigned int) &fiq_buffer[FIQ_CIRC_BUFF];
|
|
|
|
for (i = FIQ_CNT_INT_00; i <= FIQ_CNT_INT_15; i++)
|
|
fiq_buffer[i] = 0;
|
|
|
|
/*
|
|
* FIQ mode r9 always points to the fiq_buffer, becauses the FIQ isr
|
|
* will run in an unpredictable context. The fiq_buffer is the FIQ isr's
|
|
* only means of communication with the IRQ level and other kernel
|
|
* context code.
|
|
*/
|
|
FIQ_regs.ARM_r9 = (unsigned int)fiq_buffer;
|
|
set_fiq_regs(&FIQ_regs);
|
|
|
|
pr_info("request_fiq(): fiq_buffer = %p\n", fiq_buffer);
|
|
|
|
/*
|
|
* Redirect GPIO interrupts to FIQ
|
|
*/
|
|
offset = IRQ_ILR0_REG_OFFSET + INT_GPIO_BANK1 * 0x4;
|
|
val = omap_readl(OMAP_IH1_BASE + offset) | 1;
|
|
omap_writel(val, OMAP_IH1_BASE + offset);
|
|
}
|