0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/gpio/consumer.h>
0014 #include <linux/gpio/machine.h>
0015 #include <linux/gpio/driver.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/irq.h>
0018 #include <linux/module.h>
0019 #include <linux/io.h>
0020 #include <linux/platform_data/ams-delta-fiq.h>
0021 #include <linux/platform_device.h>
0022
0023 #include <asm/fiq.h>
0024 #include <linux/soc/ti/omap1-io.h>
0025
0026 #include "hardware.h"
0027 #include "ams-delta-fiq.h"
0028 #include "board-ams-delta.h"
0029
0030 static struct fiq_handler fh = {
0031 .name = "ams-delta-fiq"
0032 };
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 static unsigned int fiq_buffer[1024];
0043
0044 static struct irq_chip *irq_chip;
0045 static struct irq_data *irq_data[16];
0046 static unsigned int irq_counter[16];
0047
0048 static const char *pin_name[16] __initconst = {
0049 [AMS_DELTA_GPIO_PIN_KEYBRD_DATA] = "keybrd_data",
0050 [AMS_DELTA_GPIO_PIN_KEYBRD_CLK] = "keybrd_clk",
0051 };
0052
0053 static irqreturn_t deferred_fiq(int irq, void *dev_id)
0054 {
0055 struct irq_data *d;
0056 int gpio, irq_num, fiq_count;
0057
0058
0059
0060
0061
0062 for (gpio = AMS_DELTA_GPIO_PIN_KEYBRD_CLK;
0063 gpio <= AMS_DELTA_GPIO_PIN_HOOK_SWITCH; gpio++) {
0064 d = irq_data[gpio];
0065 irq_num = d->irq;
0066 fiq_count = fiq_buffer[FIQ_CNT_INT_00 + gpio];
0067
0068 if (irq_counter[gpio] < fiq_count &&
0069 gpio != AMS_DELTA_GPIO_PIN_KEYBRD_CLK) {
0070
0071
0072
0073
0074
0075 if (!WARN_ON_ONCE(!irq_chip->irq_unmask))
0076 irq_chip->irq_unmask(d);
0077 }
0078 for (; irq_counter[gpio] < fiq_count; irq_counter[gpio]++)
0079 generic_handle_irq(irq_num);
0080 }
0081 return IRQ_HANDLED;
0082 }
0083
0084 void __init ams_delta_init_fiq(struct gpio_chip *chip,
0085 struct platform_device *serio)
0086 {
0087 struct gpio_desc *gpiod, *data = NULL, *clk = NULL;
0088 void *fiqhandler_start;
0089 unsigned int fiqhandler_length;
0090 struct pt_regs FIQ_regs;
0091 unsigned long val, offset;
0092 int i, retval;
0093
0094
0095 irq_chip = chip->irq.chip;
0096 if (!irq_chip) {
0097 pr_err("%s: GPIO chip %s is missing IRQ function\n", __func__,
0098 chip->label);
0099 return;
0100 }
0101
0102 for (i = 0; i < ARRAY_SIZE(irq_data); i++) {
0103 gpiod = gpiochip_request_own_desc(chip, i, pin_name[i],
0104 GPIO_ACTIVE_HIGH, GPIOD_IN);
0105 if (IS_ERR(gpiod)) {
0106 pr_err("%s: failed to get GPIO pin %d (%ld)\n",
0107 __func__, i, PTR_ERR(gpiod));
0108 return;
0109 }
0110
0111 irq_data[i] = irq_get_irq_data(gpiod_to_irq(gpiod));
0112
0113
0114
0115
0116
0117
0118 switch (i) {
0119 case AMS_DELTA_GPIO_PIN_KEYBRD_DATA:
0120 data = gpiod;
0121 gpiod_direction_input(data);
0122 break;
0123 case AMS_DELTA_GPIO_PIN_KEYBRD_CLK:
0124 clk = gpiod;
0125 gpiod_direction_input(clk);
0126 break;
0127 default:
0128 gpiochip_free_own_desc(gpiod);
0129 break;
0130 }
0131 }
0132 if (!data || !clk)
0133 goto out_gpio;
0134
0135 fiqhandler_start = &qwerty_fiqin_start;
0136 fiqhandler_length = &qwerty_fiqin_end - &qwerty_fiqin_start;
0137 pr_info("Installing fiq handler from %p, length 0x%x\n",
0138 fiqhandler_start, fiqhandler_length);
0139
0140 retval = claim_fiq(&fh);
0141 if (retval) {
0142 pr_err("ams_delta_init_fiq(): couldn't claim FIQ, ret=%d\n",
0143 retval);
0144 goto out_gpio;
0145 }
0146
0147 retval = request_irq(INT_DEFERRED_FIQ, deferred_fiq,
0148 IRQ_TYPE_EDGE_RISING, "deferred_fiq", NULL);
0149 if (retval < 0) {
0150 pr_err("Failed to get deferred_fiq IRQ, ret=%d\n", retval);
0151 release_fiq(&fh);
0152 goto out_gpio;
0153 }
0154
0155
0156
0157
0158 offset = IRQ_ILR0_REG_OFFSET +
0159 ((INT_DEFERRED_FIQ - NR_IRQS_LEGACY) & 0x1f) * 0x4;
0160 val = omap_readl(DEFERRED_FIQ_IH_BASE + offset) & ~(1 << 1);
0161 omap_writel(val, DEFERRED_FIQ_IH_BASE + offset);
0162
0163 set_fiq_handler(fiqhandler_start, fiqhandler_length);
0164
0165
0166
0167
0168
0169 fiq_buffer[FIQ_GPIO_INT_MASK] = 0;
0170 fiq_buffer[FIQ_MASK] = 0;
0171 fiq_buffer[FIQ_STATE] = 0;
0172 fiq_buffer[FIQ_KEY] = 0;
0173 fiq_buffer[FIQ_KEYS_CNT] = 0;
0174 fiq_buffer[FIQ_KEYS_HICNT] = 0;
0175 fiq_buffer[FIQ_TAIL_OFFSET] = 0;
0176 fiq_buffer[FIQ_HEAD_OFFSET] = 0;
0177 fiq_buffer[FIQ_BUF_LEN] = 256;
0178 fiq_buffer[FIQ_MISSED_KEYS] = 0;
0179 fiq_buffer[FIQ_BUFFER_START] =
0180 (unsigned int) &fiq_buffer[FIQ_CIRC_BUFF];
0181
0182 for (i = FIQ_CNT_INT_00; i <= FIQ_CNT_INT_15; i++)
0183 fiq_buffer[i] = 0;
0184
0185
0186
0187
0188
0189
0190
0191 FIQ_regs.ARM_r9 = (unsigned int)fiq_buffer;
0192 set_fiq_regs(&FIQ_regs);
0193
0194 pr_info("request_fiq(): fiq_buffer = %p\n", fiq_buffer);
0195
0196
0197
0198
0199 offset = IRQ_ILR0_REG_OFFSET + (INT_GPIO_BANK1 - NR_IRQS_LEGACY) * 0x4;
0200 val = omap_readl(OMAP_IH1_BASE + offset) | 1;
0201 omap_writel(val, OMAP_IH1_BASE + offset);
0202
0203
0204 serio->resource[0].start = gpiod_to_irq(clk);
0205 serio->resource[0].end = serio->resource[0].start;
0206 serio->dev.platform_data = fiq_buffer;
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220 return;
0221
0222 out_gpio:
0223 if (data)
0224 gpiochip_free_own_desc(data);
0225 if (clk)
0226 gpiochip_free_own_desc(clk);
0227 }