linux/arch/arm/mach-omap1/ams-delta-fiq.c
Linus Torvalds 9bc747bea5 arm-soc: First batch of cleanups
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
  ...
2012-05-22 09:23:24 -07:00

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);
}