[PATCH v3 11/12] gpio: pxa: discard irq base in pxa_gpio_chip

Haojian Zhuang haojian.zhuang at linaro.org
Mon Feb 18 00:12:37 EST 2013


Discard irq_base in struct pxa_gpio_chip. Use irq_domain instead.

Signed-off-by: Haojian Zhuang <haojian.zhuang at linaro.org>
---
 drivers/gpio/gpio-pxa.c |   91 +++++++++++++++++++++++------------------------
 1 file changed, 44 insertions(+), 47 deletions(-)

diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 35cdb23..d45cb57 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -66,8 +66,8 @@ int pxa_last_gpio;
 
 struct pxa_gpio_chip {
 	struct gpio_chip chip;
+	struct irq_domain *domain;
 	void __iomem	*regbase;
-	unsigned int	irq_base;
 	bool		inverted;
 	bool		gafr;
 	char label[10];
@@ -147,17 +147,7 @@ static int pxa_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
 	struct pxa_gpio_chip *chip = NULL;
 
 	chip = container_of(gc, struct pxa_gpio_chip, chip);
-	return chip->irq_base + offset;
-}
-
-int pxa_irq_to_gpio(struct irq_data *d)
-{
-	struct pxa_gpio_chip *chip;
-	int gpio;
-
-	chip = (struct pxa_gpio_chip *)d->domain->host_data;
-	gpio = d->irq - chip->irq_base + chip->chip.base;
-	return gpio;
+	return irq_create_mapping(chip->domain, offset);
 }
 
 static int pxa_gpio_request(struct gpio_chip *gc, unsigned offset)
@@ -270,18 +260,19 @@ static inline void update_edge_detect(struct pxa_gpio_chip *chip)
 
 static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
 {
-	struct pxa_gpio_chip *chip;
-	int gpio = pxa_irq_to_gpio(d);
-	unsigned long gpdr, mask = GPIO_bit(gpio);
+	struct pxa_gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	int offset = irqd_to_hwirq(d);
+	int gpio;
+	unsigned long gpdr, mask;
 
-	chip = gpio_to_pxachip(gpio);
+	mask = 1 << offset;
+	gpio = chip->chip.base + offset;
 
 	if (type == IRQ_TYPE_PROBE) {
 		/* Don't mess with enabled GPIOs using preconfigured edges or
 		 * GPIOs set to alternate function or to output during probe
 		 */
-		if ((chip->irq_edge_rise | chip->irq_edge_fall)
-			& GPIO_bit(gpio))
+		if ((chip->irq_edge_rise | chip->irq_edge_fall) & mask)
 			return 0;
 
 		if (__gpio_is_occupied(chip, gpio))
@@ -318,16 +309,15 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
 static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
 {
 	struct pxa_gpio_chip *chip;
-	int loop, gpio, gpio_base, n;
-	unsigned long gedr;
 	struct irq_chip *ic = irq_desc_get_chip(desc);
+	int n, gpio, loop;
+	unsigned long gedr;
 
 	chained_irq_enter(ic, desc);
 
 	do {
 		loop = 0;
 		for_each_gpio_chip(gpio, chip) {
-			gpio_base = chip->chip.base;
 
 			gedr = readl_relaxed(chip->regbase + GEDR_OFFSET);
 			gedr = gedr & chip->irq_mask;
@@ -335,8 +325,8 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
 
 			for_each_set_bit(n, &gedr, BITS_PER_LONG) {
 				loop = 1;
-
-				generic_handle_irq(gpio_to_irq(gpio_base + n));
+				generic_handle_irq(pxa_gpio_to_irq(&chip->chip,
+								   n));
 			}
 		}
 	} while (loop);
@@ -346,31 +336,35 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
 
 static void pxa_ack_muxed_gpio(struct irq_data *d)
 {
-	int gpio = pxa_irq_to_gpio(d);
-	struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
+	struct pxa_gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	int offset = irqd_to_hwirq(d);
 
-	writel_relaxed(GPIO_bit(gpio), chip->regbase + GEDR_OFFSET);
+	writel_relaxed(1 << offset, chip->regbase + GEDR_OFFSET);
 }
 
 static void pxa_mask_muxed_gpio(struct irq_data *d)
 {
-	int gpio = pxa_irq_to_gpio(d);
-	struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
+	struct pxa_gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	int offset = irqd_to_hwirq(d);
+	int mask;
 	uint32_t grer, gfer;
 
-	chip->irq_mask &= ~GPIO_bit(gpio);
+	mask = 1 << offset;
+	chip->irq_mask &= ~mask;
 
-	grer = readl_relaxed(chip->regbase + GRER_OFFSET) & ~GPIO_bit(gpio);
-	gfer = readl_relaxed(chip->regbase + GFER_OFFSET) & ~GPIO_bit(gpio);
+	grer = readl_relaxed(chip->regbase + GRER_OFFSET) & ~mask;
+	gfer = readl_relaxed(chip->regbase + GFER_OFFSET) & ~mask;
 	writel_relaxed(grer, chip->regbase + GRER_OFFSET);
 	writel_relaxed(gfer, chip->regbase + GFER_OFFSET);
 }
 
 static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
 {
-	int gpio = pxa_irq_to_gpio(d);
-	struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
+	struct pxa_gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	int offset = irqd_to_hwirq(d);
+	int gpio;
 
+	gpio = chip->chip.base + offset;
 	if (chip->set_wake)
 		return chip->set_wake(gpio, on);
 	else
@@ -379,10 +373,10 @@ static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
 
 static void pxa_unmask_muxed_gpio(struct irq_data *d)
 {
-	int gpio = pxa_irq_to_gpio(d);
-	struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
+	struct pxa_gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	int offset = irqd_to_hwirq(d);
 
-	chip->irq_mask |= GPIO_bit(gpio);
+	chip->irq_mask |= 1 << offset;
 	update_edge_detect(chip);
 }
 
@@ -395,12 +389,16 @@ static struct irq_chip pxa_muxed_gpio_chip = {
 	.irq_set_wake	= pxa_gpio_set_wake,
 };
 
-static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
+static int pxa_irq_domain_map(struct irq_domain *d, unsigned int virq,
 			      irq_hw_number_t hw)
 {
-	irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
-				 handle_edge_irq);
-	set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	struct pxa_gpio_chip *chip = d->host_data;
+
+	irq_set_chip_and_handler_name(virq, &pxa_muxed_gpio_chip,
+				      handle_edge_irq, "gpio");
+	irq_set_chip_data(virq, chip);
+	irq_set_irq_type(virq, IRQ_TYPE_NONE);
+	set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
 	return 0;
 }
 
@@ -483,13 +481,12 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
 		if (pdata->irq_base)
 			irq_base = pdata->irq_base + gpio;
 		else
-			irq_base = -1;
-		chips[i].irq_base = irq_alloc_descs(irq_base, 0, gc->ngpio, 0);
-		if (chips[i].irq_base < 0)
-			return -EINVAL;
-		if (!irq_domain_add_legacy(pdev->dev.of_node, gc->ngpio,
-					   chips[i].irq_base, 0,
-					   &pxa_irq_domain_ops, &chips[i]))
+			irq_base = 0;
+		chips[i].domain = irq_domain_add_simple(pdev->dev.of_node,
+							gc->ngpio, irq_base,
+							&pxa_irq_domain_ops,
+							&chips[i]);
+		if (!chips[i].domain)
 			return -ENODEV;
 
 		gc->base  = gpio;
-- 
1.7.10.4




More information about the linux-arm-kernel mailing list