diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2011-04-02 21:23:36 +0200 |
---|---|---|
committer | Matthew Garrett <mjg@redhat.com> | 2011-04-04 18:51:16 +0200 |
commit | 65d7ac038e34702feedad91d0bf597b1f0a4174a (patch) | |
tree | f6c6ae566e9996fde751686fdee3fa9edddd702f /drivers/platform | |
parent | sony-laptop: fix early NULL pointer dereference (diff) | |
download | linux-65d7ac038e34702feedad91d0bf597b1f0a4174a.tar.xz linux-65d7ac038e34702feedad91d0bf597b1f0a4174a.zip |
platform-drivers: x86: pmic: Restore the dropped buslock/unlock
When I added the buslock/unlock mechanism to the pmic code in order to
get rid of the horrible work queue stuff, stupid me missed to add the
new callbacks to the irq_chip.
In consequence Andrew removed the unused functions, but I missed that.
Add them back and hook them up proper.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Matthew Garrett <mjg@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/intel_pmic_gpio.c | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c index d653104b59cb..7bbb5388e564 100644 --- a/drivers/platform/x86/intel_pmic_gpio.c +++ b/drivers/platform/x86/intel_pmic_gpio.c @@ -74,6 +74,19 @@ struct pmic_gpio { u32 trigger_type; }; +static void pmic_program_irqtype(int gpio, int type) +{ + if (type & IRQ_TYPE_EDGE_RISING) + intel_scu_ipc_update_register(GPIO0 + gpio, 0x20, 0x20); + else + intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x20); + + if (type & IRQ_TYPE_EDGE_FALLING) + intel_scu_ipc_update_register(GPIO0 + gpio, 0x10, 0x10); + else + intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x10); +}; + static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { if (offset > 8) { @@ -166,16 +179,38 @@ static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned offset) return pg->irq_base + offset; } +static void pmic_bus_lock(struct irq_data *data) +{ + struct pmic_gpio *pg = irq_data_get_irq_chip_data(data); + + mutex_lock(&pg->buslock); +} + +static void pmic_bus_sync_unlock(struct irq_data *data) +{ + struct pmic_gpio *pg = irq_data_get_irq_chip_data(data); + + if (pg->update_type) { + unsigned int gpio = pg->update_type & ~GPIO_UPDATE_TYPE; + + pmic_program_irqtype(gpio, pg->trigger_type); + pg->update_type = 0; + } + mutex_unlock(&pg->buslock); +} + /* the gpiointr register is read-clear, so just do nothing. */ static void pmic_irq_unmask(struct irq_data *data) { } static void pmic_irq_mask(struct irq_data *data) { } static struct irq_chip pmic_irqchip = { - .name = "PMIC-GPIO", - .irq_mask = pmic_irq_mask, - .irq_unmask = pmic_irq_unmask, - .irq_set_type = pmic_irq_type, + .name = "PMIC-GPIO", + .irq_mask = pmic_irq_mask, + .irq_unmask = pmic_irq_unmask, + .irq_set_type = pmic_irq_type, + .irq_bus_lock = pmic_irq_buslock, + .irq_bus_sync_unlock = pmic_bus_sync_unlock, }; static irqreturn_t pmic_irq_handler(int irq, void *data) |