Commit cdcb0ab6 authored by Linus Walleij's avatar Linus Walleij

pinctrl: msm: switch to using generic GPIO irqchip helpers

This switches the Qualcomm MSM pin control driver over to using
the generic GPIO irqchip helpers.

Cc: Stephen Boyd <sboyd@codeaurora.org>
Cc: Josh Cartwright <joshc@codeaurora.org>
Acked-by: default avatarBjorn Andersson <bjorn.andersson@sonymobile.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent ba6764d5
...@@ -224,6 +224,7 @@ config PINCTRL_MSM ...@@ -224,6 +224,7 @@ config PINCTRL_MSM
select PINMUX select PINMUX
select PINCONF select PINCONF
select GENERIC_PINCONF select GENERIC_PINCONF
select GPIOLIB_IRQCHIP
config PINCTRL_APQ8064 config PINCTRL_APQ8064
tristate "Qualcomm APQ8064 pin controller driver" tristate "Qualcomm APQ8064 pin controller driver"
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
*/ */
#include <linux/err.h> #include <linux/err.h>
#include <linux/irqdomain.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -26,8 +25,6 @@ ...@@ -26,8 +25,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include "core.h" #include "core.h"
...@@ -41,7 +38,6 @@ ...@@ -41,7 +38,6 @@
* struct msm_pinctrl - state for a pinctrl-msm device * struct msm_pinctrl - state for a pinctrl-msm device
* @dev: device handle. * @dev: device handle.
* @pctrl: pinctrl handle. * @pctrl: pinctrl handle.
* @domain: irqdomain handle.
* @chip: gpiochip handle. * @chip: gpiochip handle.
* @irq: parent irq for the TLMM irq_chip. * @irq: parent irq for the TLMM irq_chip.
* @lock: Spinlock to protect register resources as well * @lock: Spinlock to protect register resources as well
...@@ -55,7 +51,6 @@ ...@@ -55,7 +51,6 @@
struct msm_pinctrl { struct msm_pinctrl {
struct device *dev; struct device *dev;
struct pinctrl_dev *pctrl; struct pinctrl_dev *pctrl;
struct irq_domain *domain;
struct gpio_chip chip; struct gpio_chip chip;
int irq; int irq;
...@@ -68,6 +63,11 @@ struct msm_pinctrl { ...@@ -68,6 +63,11 @@ struct msm_pinctrl {
void __iomem *regs; void __iomem *regs;
}; };
static inline struct msm_pinctrl *to_msm_pinctrl(struct gpio_chip *gc)
{
return container_of(gc, struct msm_pinctrl, chip);
}
static int msm_get_groups_count(struct pinctrl_dev *pctldev) static int msm_get_groups_count(struct pinctrl_dev *pctldev)
{ {
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
...@@ -480,13 +480,6 @@ static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value) ...@@ -480,13 +480,6 @@ static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
spin_unlock_irqrestore(&pctrl->lock, flags); spin_unlock_irqrestore(&pctrl->lock, flags);
} }
static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
return irq_find_mapping(pctrl->domain, offset);
}
static int msm_gpio_request(struct gpio_chip *chip, unsigned offset) static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
{ {
int gpio = chip->base + offset; int gpio = chip->base + offset;
...@@ -556,7 +549,6 @@ static struct gpio_chip msm_gpio_template = { ...@@ -556,7 +549,6 @@ static struct gpio_chip msm_gpio_template = {
.direction_output = msm_gpio_direction_output, .direction_output = msm_gpio_direction_output,
.get = msm_gpio_get, .get = msm_gpio_get,
.set = msm_gpio_set, .set = msm_gpio_set,
.to_irq = msm_gpio_to_irq,
.request = msm_gpio_request, .request = msm_gpio_request,
.free = msm_gpio_free, .free = msm_gpio_free,
.dbg_show = msm_gpio_dbg_show, .dbg_show = msm_gpio_dbg_show,
...@@ -608,12 +600,12 @@ static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl, ...@@ -608,12 +600,12 @@ static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl,
static void msm_gpio_irq_mask(struct irq_data *d) static void msm_gpio_irq_mask(struct irq_data *d)
{ {
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
const struct msm_pingroup *g; const struct msm_pingroup *g;
struct msm_pinctrl *pctrl;
unsigned long flags; unsigned long flags;
u32 val; u32 val;
pctrl = irq_data_get_irq_chip_data(d);
g = &pctrl->soc->groups[d->hwirq]; g = &pctrl->soc->groups[d->hwirq];
spin_lock_irqsave(&pctrl->lock, flags); spin_lock_irqsave(&pctrl->lock, flags);
...@@ -629,12 +621,12 @@ static void msm_gpio_irq_mask(struct irq_data *d) ...@@ -629,12 +621,12 @@ static void msm_gpio_irq_mask(struct irq_data *d)
static void msm_gpio_irq_unmask(struct irq_data *d) static void msm_gpio_irq_unmask(struct irq_data *d)
{ {
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
const struct msm_pingroup *g; const struct msm_pingroup *g;
struct msm_pinctrl *pctrl;
unsigned long flags; unsigned long flags;
u32 val; u32 val;
pctrl = irq_data_get_irq_chip_data(d);
g = &pctrl->soc->groups[d->hwirq]; g = &pctrl->soc->groups[d->hwirq];
spin_lock_irqsave(&pctrl->lock, flags); spin_lock_irqsave(&pctrl->lock, flags);
...@@ -654,12 +646,12 @@ static void msm_gpio_irq_unmask(struct irq_data *d) ...@@ -654,12 +646,12 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
static void msm_gpio_irq_ack(struct irq_data *d) static void msm_gpio_irq_ack(struct irq_data *d)
{ {
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
const struct msm_pingroup *g; const struct msm_pingroup *g;
struct msm_pinctrl *pctrl;
unsigned long flags; unsigned long flags;
u32 val; u32 val;
pctrl = irq_data_get_irq_chip_data(d);
g = &pctrl->soc->groups[d->hwirq]; g = &pctrl->soc->groups[d->hwirq];
spin_lock_irqsave(&pctrl->lock, flags); spin_lock_irqsave(&pctrl->lock, flags);
...@@ -681,12 +673,12 @@ static void msm_gpio_irq_ack(struct irq_data *d) ...@@ -681,12 +673,12 @@ static void msm_gpio_irq_ack(struct irq_data *d)
static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type) static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{ {
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
const struct msm_pingroup *g; const struct msm_pingroup *g;
struct msm_pinctrl *pctrl;
unsigned long flags; unsigned long flags;
u32 val; u32 val;
pctrl = irq_data_get_irq_chip_data(d);
g = &pctrl->soc->groups[d->hwirq]; g = &pctrl->soc->groups[d->hwirq];
spin_lock_irqsave(&pctrl->lock, flags); spin_lock_irqsave(&pctrl->lock, flags);
...@@ -775,11 +767,10 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type) ...@@ -775,11 +767,10 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on) static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
{ {
struct msm_pinctrl *pctrl; struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
unsigned long flags; unsigned long flags;
pctrl = irq_data_get_irq_chip_data(d);
spin_lock_irqsave(&pctrl->lock, flags); spin_lock_irqsave(&pctrl->lock, flags);
irq_set_irq_wake(pctrl->irq, on); irq_set_irq_wake(pctrl->irq, on);
...@@ -789,25 +780,6 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on) ...@@ -789,25 +780,6 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
return 0; return 0;
} }
static int msm_gpio_irq_reqres(struct irq_data *d)
{
struct msm_pinctrl *pctrl = irq_data_get_irq_chip_data(d);
if (gpio_lock_as_irq(&pctrl->chip, d->hwirq)) {
dev_err(pctrl->dev, "unable to lock HW IRQ %lu for IRQ\n",
d->hwirq);
return -EINVAL;
}
return 0;
}
static void msm_gpio_irq_relres(struct irq_data *d)
{
struct msm_pinctrl *pctrl = irq_data_get_irq_chip_data(d);
gpio_unlock_as_irq(&pctrl->chip, d->hwirq);
}
static struct irq_chip msm_gpio_irq_chip = { static struct irq_chip msm_gpio_irq_chip = {
.name = "msmgpio", .name = "msmgpio",
.irq_mask = msm_gpio_irq_mask, .irq_mask = msm_gpio_irq_mask,
...@@ -815,14 +787,13 @@ static struct irq_chip msm_gpio_irq_chip = { ...@@ -815,14 +787,13 @@ static struct irq_chip msm_gpio_irq_chip = {
.irq_ack = msm_gpio_irq_ack, .irq_ack = msm_gpio_irq_ack,
.irq_set_type = msm_gpio_irq_set_type, .irq_set_type = msm_gpio_irq_set_type,
.irq_set_wake = msm_gpio_irq_set_wake, .irq_set_wake = msm_gpio_irq_set_wake,
.irq_request_resources = msm_gpio_irq_reqres,
.irq_release_resources = msm_gpio_irq_relres,
}; };
static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{ {
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
const struct msm_pingroup *g; const struct msm_pingroup *g;
struct msm_pinctrl *pctrl = irq_desc_get_handler_data(desc); struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
struct irq_chip *chip = irq_get_chip(irq); struct irq_chip *chip = irq_get_chip(irq);
int irq_pin; int irq_pin;
int handled = 0; int handled = 0;
...@@ -839,7 +810,7 @@ static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) ...@@ -839,7 +810,7 @@ static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
g = &pctrl->soc->groups[i]; g = &pctrl->soc->groups[i];
val = readl(pctrl->regs + g->intr_status_reg); val = readl(pctrl->regs + g->intr_status_reg);
if (val & BIT(g->intr_status_bit)) { if (val & BIT(g->intr_status_bit)) {
irq_pin = irq_find_mapping(pctrl->domain, i); irq_pin = irq_find_mapping(gc->irqdomain, i);
generic_handle_irq(irq_pin); generic_handle_irq(irq_pin);
handled++; handled++;
} }
...@@ -852,19 +823,10 @@ static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) ...@@ -852,19 +823,10 @@ static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
} }
/*
* This lock class tells lockdep that GPIO irqs are in a different
* category than their parents, so it won't report false recursion.
*/
static struct lock_class_key gpio_lock_class;
static int msm_gpio_init(struct msm_pinctrl *pctrl) static int msm_gpio_init(struct msm_pinctrl *pctrl)
{ {
struct gpio_chip *chip; struct gpio_chip *chip;
int irq;
int ret; int ret;
int i;
int r;
unsigned ngpio = pctrl->soc->ngpios; unsigned ngpio = pctrl->soc->ngpios;
if (WARN_ON(ngpio > MAX_NR_GPIO)) if (WARN_ON(ngpio > MAX_NR_GPIO))
...@@ -890,23 +852,18 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) ...@@ -890,23 +852,18 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
return ret; return ret;
} }
pctrl->domain = irq_domain_add_linear(pctrl->dev->of_node, chip->ngpio, ret = gpiochip_irqchip_add(chip,
&irq_domain_simple_ops, NULL); &msm_gpio_irq_chip,
if (!pctrl->domain) { 0,
dev_err(pctrl->dev, "Failed to register irq domain\n"); handle_edge_irq,
r = gpiochip_remove(&pctrl->chip); IRQ_TYPE_NONE);
if (ret) {
dev_err(pctrl->dev, "Failed to add irqchip to gpiochip\n");
return -ENOSYS; return -ENOSYS;
} }
for (i = 0; i < chip->ngpio; i++) { gpiochip_set_chained_irqchip(chip, &msm_gpio_irq_chip, pctrl->irq,
irq = irq_create_mapping(pctrl->domain, i); msm_gpio_irq_handler);
irq_set_lockdep_class(irq, &gpio_lock_class);
irq_set_chip_and_handler(irq, &msm_gpio_irq_chip, handle_edge_irq);
irq_set_chip_data(irq, pctrl);
}
irq_set_handler_data(pctrl->irq, pctrl);
irq_set_chained_handler(pctrl->irq, msm_gpio_irq_handler);
return 0; return 0;
} }
...@@ -974,8 +931,6 @@ int msm_pinctrl_remove(struct platform_device *pdev) ...@@ -974,8 +931,6 @@ int msm_pinctrl_remove(struct platform_device *pdev)
return ret; return ret;
} }
irq_set_chained_handler(pctrl->irq, NULL);
irq_domain_remove(pctrl->domain);
pinctrl_unregister(pctrl->pctrl); pinctrl_unregister(pctrl->pctrl);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment