|
@@ -45,6 +45,11 @@ static struct irq_chip *irq_chip;
|
|
|
static struct irq_data *irq_data[16];
|
|
|
static unsigned int irq_counter[16];
|
|
|
|
|
|
+static const char *pin_name[16] __initconst = {
|
|
|
+ [AMS_DELTA_GPIO_PIN_KEYBRD_DATA] = "keybrd_data",
|
|
|
+ [AMS_DELTA_GPIO_PIN_KEYBRD_CLK] = "keybrd_clk",
|
|
|
+};
|
|
|
+
|
|
|
static irqreturn_t deferred_fiq(int irq, void *dev_id)
|
|
|
{
|
|
|
struct irq_data *d;
|
|
@@ -80,7 +85,7 @@ static irqreturn_t deferred_fiq(int irq, void *dev_id)
|
|
|
|
|
|
void __init ams_delta_init_fiq(struct gpio_chip *chip)
|
|
|
{
|
|
|
- struct gpio_desc *gpiod;
|
|
|
+ struct gpio_desc *gpiod, *data = NULL, *clk = NULL;
|
|
|
void *fiqhandler_start;
|
|
|
unsigned int fiqhandler_length;
|
|
|
struct pt_regs FIQ_regs;
|
|
@@ -96,7 +101,7 @@ void __init ams_delta_init_fiq(struct gpio_chip *chip)
|
|
|
}
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(irq_data); i++) {
|
|
|
- gpiod = gpiochip_request_own_desc(chip, i, NULL);
|
|
|
+ gpiod = gpiochip_request_own_desc(chip, i, pin_name[i]);
|
|
|
if (IS_ERR(gpiod)) {
|
|
|
pr_err("%s: failed to get GPIO pin %d (%ld)\n",
|
|
|
__func__, i, PTR_ERR(gpiod));
|
|
@@ -105,8 +110,27 @@ void __init ams_delta_init_fiq(struct gpio_chip *chip)
|
|
|
/* Store irq_data location for IRQ handler use */
|
|
|
irq_data[i] = irq_get_irq_data(gpiod_to_irq(gpiod));
|
|
|
|
|
|
- gpiochip_free_own_desc(gpiod);
|
|
|
+ /*
|
|
|
+ * FIQ handler takes full control over serio data and clk GPIO
|
|
|
+ * pins. Initiaize them and keep requested so nobody can
|
|
|
+ * interfere. Fail if any of those two couldn't be requested.
|
|
|
+ */
|
|
|
+ switch (i) {
|
|
|
+ case AMS_DELTA_GPIO_PIN_KEYBRD_DATA:
|
|
|
+ data = gpiod;
|
|
|
+ gpiod_direction_input(data);
|
|
|
+ break;
|
|
|
+ case AMS_DELTA_GPIO_PIN_KEYBRD_CLK:
|
|
|
+ clk = gpiod;
|
|
|
+ gpiod_direction_input(clk);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ gpiochip_free_own_desc(gpiod);
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
+ if (!data || !clk)
|
|
|
+ goto out_gpio;
|
|
|
|
|
|
fiqhandler_start = &qwerty_fiqin_start;
|
|
|
fiqhandler_length = &qwerty_fiqin_end - &qwerty_fiqin_start;
|
|
@@ -117,7 +141,7 @@ void __init ams_delta_init_fiq(struct gpio_chip *chip)
|
|
|
if (retval) {
|
|
|
pr_err("ams_delta_init_fiq(): couldn't claim FIQ, ret=%d\n",
|
|
|
retval);
|
|
|
- return;
|
|
|
+ goto out_gpio;
|
|
|
}
|
|
|
|
|
|
retval = request_irq(INT_DEFERRED_FIQ, deferred_fiq,
|
|
@@ -125,7 +149,7 @@ void __init ams_delta_init_fiq(struct gpio_chip *chip)
|
|
|
if (retval < 0) {
|
|
|
pr_err("Failed to get deferred_fiq IRQ, ret=%d\n", retval);
|
|
|
release_fiq(&fh);
|
|
|
- return;
|
|
|
+ goto out_gpio;
|
|
|
}
|
|
|
/*
|
|
|
* Since no set_type() method is provided by OMAP irq chip,
|
|
@@ -175,4 +199,12 @@ void __init ams_delta_init_fiq(struct gpio_chip *chip)
|
|
|
offset = IRQ_ILR0_REG_OFFSET + (INT_GPIO_BANK1 - NR_IRQS_LEGACY) * 0x4;
|
|
|
val = omap_readl(OMAP_IH1_BASE + offset) | 1;
|
|
|
omap_writel(val, OMAP_IH1_BASE + offset);
|
|
|
+
|
|
|
+ return;
|
|
|
+
|
|
|
+out_gpio:
|
|
|
+ if (data)
|
|
|
+ gpiochip_free_own_desc(data);
|
|
|
+ if (clk)
|
|
|
+ gpiochip_free_own_desc(clk);
|
|
|
}
|