root/drivers/bcma/driver_gpio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bcma_gpio_get_value
  2. bcma_gpio_set_value
  3. bcma_gpio_direction_input
  4. bcma_gpio_direction_output
  5. bcma_gpio_request
  6. bcma_gpio_free
  7. bcma_gpio_irq_unmask
  8. bcma_gpio_irq_mask
  9. bcma_gpio_irq_handler
  10. bcma_gpio_irq_init
  11. bcma_gpio_irq_exit
  12. bcma_gpio_irq_init
  13. bcma_gpio_irq_exit
  14. bcma_gpio_init
  15. bcma_gpio_unregister

   1 /*
   2  * Broadcom specific AMBA
   3  * GPIO driver
   4  *
   5  * Copyright 2011, Broadcom Corporation
   6  * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
   7  *
   8  * Licensed under the GNU/GPL. See COPYING for details.
   9  */
  10 
  11 #include <linux/gpio/driver.h>
  12 #include <linux/interrupt.h>
  13 #include <linux/export.h>
  14 #include <linux/bcma/bcma.h>
  15 
  16 #include "bcma_private.h"
  17 
  18 #define BCMA_GPIO_MAX_PINS      32
  19 
  20 static int bcma_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
  21 {
  22         struct bcma_drv_cc *cc = gpiochip_get_data(chip);
  23 
  24         return !!bcma_chipco_gpio_in(cc, 1 << gpio);
  25 }
  26 
  27 static void bcma_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
  28                                 int value)
  29 {
  30         struct bcma_drv_cc *cc = gpiochip_get_data(chip);
  31 
  32         bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0);
  33 }
  34 
  35 static int bcma_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
  36 {
  37         struct bcma_drv_cc *cc = gpiochip_get_data(chip);
  38 
  39         bcma_chipco_gpio_outen(cc, 1 << gpio, 0);
  40         return 0;
  41 }
  42 
  43 static int bcma_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
  44                                       int value)
  45 {
  46         struct bcma_drv_cc *cc = gpiochip_get_data(chip);
  47 
  48         bcma_chipco_gpio_outen(cc, 1 << gpio, 1 << gpio);
  49         bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0);
  50         return 0;
  51 }
  52 
  53 static int bcma_gpio_request(struct gpio_chip *chip, unsigned gpio)
  54 {
  55         struct bcma_drv_cc *cc = gpiochip_get_data(chip);
  56 
  57         bcma_chipco_gpio_control(cc, 1 << gpio, 0);
  58         /* clear pulldown */
  59         bcma_chipco_gpio_pulldown(cc, 1 << gpio, 0);
  60         /* Set pullup */
  61         bcma_chipco_gpio_pullup(cc, 1 << gpio, 1 << gpio);
  62 
  63         return 0;
  64 }
  65 
  66 static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio)
  67 {
  68         struct bcma_drv_cc *cc = gpiochip_get_data(chip);
  69 
  70         /* clear pullup */
  71         bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
  72 }
  73 
  74 #if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X)
  75 
  76 static void bcma_gpio_irq_unmask(struct irq_data *d)
  77 {
  78         struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
  79         struct bcma_drv_cc *cc = gpiochip_get_data(gc);
  80         int gpio = irqd_to_hwirq(d);
  81         u32 val = bcma_chipco_gpio_in(cc, BIT(gpio));
  82 
  83         bcma_chipco_gpio_polarity(cc, BIT(gpio), val);
  84         bcma_chipco_gpio_intmask(cc, BIT(gpio), BIT(gpio));
  85 }
  86 
  87 static void bcma_gpio_irq_mask(struct irq_data *d)
  88 {
  89         struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
  90         struct bcma_drv_cc *cc = gpiochip_get_data(gc);
  91         int gpio = irqd_to_hwirq(d);
  92 
  93         bcma_chipco_gpio_intmask(cc, BIT(gpio), 0);
  94 }
  95 
  96 static struct irq_chip bcma_gpio_irq_chip = {
  97         .name           = "BCMA-GPIO",
  98         .irq_mask       = bcma_gpio_irq_mask,
  99         .irq_unmask     = bcma_gpio_irq_unmask,
 100 };
 101 
 102 static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id)
 103 {
 104         struct bcma_drv_cc *cc = dev_id;
 105         struct gpio_chip *gc = &cc->gpio;
 106         u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN);
 107         u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ);
 108         u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL);
 109         unsigned long irqs = (val ^ pol) & mask;
 110         int gpio;
 111 
 112         if (!irqs)
 113                 return IRQ_NONE;
 114 
 115         for_each_set_bit(gpio, &irqs, gc->ngpio)
 116                 generic_handle_irq(irq_find_mapping(gc->irq.domain, gpio));
 117         bcma_chipco_gpio_polarity(cc, irqs, val & irqs);
 118 
 119         return IRQ_HANDLED;
 120 }
 121 
 122 static int bcma_gpio_irq_init(struct bcma_drv_cc *cc)
 123 {
 124         struct gpio_chip *chip = &cc->gpio;
 125         int hwirq, err;
 126 
 127         if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
 128                 return 0;
 129 
 130         hwirq = bcma_core_irq(cc->core, 0);
 131         err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio",
 132                           cc);
 133         if (err)
 134                 return err;
 135 
 136         bcma_chipco_gpio_intmask(cc, ~0, 0);
 137         bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO);
 138 
 139         err =  gpiochip_irqchip_add(chip,
 140                                     &bcma_gpio_irq_chip,
 141                                     0,
 142                                     handle_simple_irq,
 143                                     IRQ_TYPE_NONE);
 144         if (err) {
 145                 free_irq(hwirq, cc);
 146                 return err;
 147         }
 148 
 149         return 0;
 150 }
 151 
 152 static void bcma_gpio_irq_exit(struct bcma_drv_cc *cc)
 153 {
 154         if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
 155                 return;
 156 
 157         bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO);
 158         free_irq(bcma_core_irq(cc->core, 0), cc);
 159 }
 160 #else
 161 static int bcma_gpio_irq_init(struct bcma_drv_cc *cc)
 162 {
 163         return 0;
 164 }
 165 
 166 static void bcma_gpio_irq_exit(struct bcma_drv_cc *cc)
 167 {
 168 }
 169 #endif
 170 
 171 int bcma_gpio_init(struct bcma_drv_cc *cc)
 172 {
 173         struct bcma_bus *bus = cc->core->bus;
 174         struct gpio_chip *chip = &cc->gpio;
 175         int err;
 176 
 177         chip->label             = "bcma_gpio";
 178         chip->owner             = THIS_MODULE;
 179         chip->request           = bcma_gpio_request;
 180         chip->free              = bcma_gpio_free;
 181         chip->get               = bcma_gpio_get_value;
 182         chip->set               = bcma_gpio_set_value;
 183         chip->direction_input   = bcma_gpio_direction_input;
 184         chip->direction_output  = bcma_gpio_direction_output;
 185         chip->owner             = THIS_MODULE;
 186         chip->parent            = bus->dev;
 187 #if IS_BUILTIN(CONFIG_OF)
 188         chip->of_node           = cc->core->dev.of_node;
 189 #endif
 190         switch (bus->chipinfo.id) {
 191         case BCMA_CHIP_ID_BCM4707:
 192         case BCMA_CHIP_ID_BCM5357:
 193         case BCMA_CHIP_ID_BCM53572:
 194         case BCMA_CHIP_ID_BCM53573:
 195         case BCMA_CHIP_ID_BCM47094:
 196                 chip->ngpio     = 32;
 197                 break;
 198         default:
 199                 chip->ngpio     = 16;
 200         }
 201 
 202         /*
 203          * Register SoC GPIO devices with absolute GPIO pin base.
 204          * On MIPS, we don't have Device Tree and we can't use relative (per chip)
 205          * GPIO numbers.
 206          * On some ARM devices, user space may want to access some system GPIO
 207          * pins directly, which is easier to do with a predictable GPIO base.
 208          */
 209         if (IS_BUILTIN(CONFIG_BCM47XX) ||
 210             cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
 211                 chip->base              = bus->num * BCMA_GPIO_MAX_PINS;
 212         else
 213                 chip->base              = -1;
 214 
 215         err = gpiochip_add_data(chip, cc);
 216         if (err)
 217                 return err;
 218 
 219         err = bcma_gpio_irq_init(cc);
 220         if (err) {
 221                 gpiochip_remove(chip);
 222                 return err;
 223         }
 224 
 225         return 0;
 226 }
 227 
 228 int bcma_gpio_unregister(struct bcma_drv_cc *cc)
 229 {
 230         bcma_gpio_irq_exit(cc);
 231         gpiochip_remove(&cc->gpio);
 232         return 0;
 233 }

/* [<][>][^][v][top][bottom][index][help] */