Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bcma: add GPIO driver

Register a GPIO driver to access the GPIOs provided by the chip.
The GPIOs of the SoC should always start at 0 and the other GPIOs could
start at a random position. There is just one SoC in a system and when
they start at 0 the number is predictable.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Patchwork: http://patchwork.linux-mips.org/patch/4587
Acked-by: Florian Fainelli <florian@openwrt.org>

authored by

Hauke Mehrtens and committed by
John Crispin
cf0936b0 3e8bb507

+128
+9
drivers/bcma/Kconfig
··· 65 65 66 66 If unsure, say N 67 67 68 + config BCMA_DRIVER_GPIO 69 + bool "BCMA GPIO driver" 70 + depends on BCMA 71 + select GPIOLIB 72 + help 73 + Driver to provide access to the GPIO pins of the bcma bus. 74 + 75 + If unsure, say N 76 + 68 77 config BCMA_DEBUG 69 78 bool "BCMA debugging" 70 79 depends on BCMA
+1
drivers/bcma/Makefile
··· 6 6 bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o 7 7 bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o 8 8 bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o 9 + bcma-$(CONFIG_BCMA_DRIVER_GPIO) += driver_gpio.o 9 10 bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o 10 11 bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o 11 12 obj-$(CONFIG_BCMA) += bcma.o
+10
drivers/bcma/bcma_private.h
··· 89 89 void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc); 90 90 #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */ 91 91 92 + #ifdef CONFIG_BCMA_DRIVER_GPIO 93 + /* driver_gpio.c */ 94 + int bcma_gpio_init(struct bcma_drv_cc *cc); 95 + #else 96 + static inline int bcma_gpio_init(struct bcma_drv_cc *cc) 97 + { 98 + return -ENOTSUPP; 99 + } 100 + #endif /* CONFIG_BCMA_DRIVER_GPIO */ 101 + 92 102 #endif
+98
drivers/bcma/driver_gpio.c
··· 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.h> 12 + #include <linux/export.h> 13 + #include <linux/bcma/bcma.h> 14 + 15 + #include "bcma_private.h" 16 + 17 + static inline struct bcma_drv_cc *bcma_gpio_get_cc(struct gpio_chip *chip) 18 + { 19 + return container_of(chip, struct bcma_drv_cc, gpio); 20 + } 21 + 22 + static int bcma_gpio_get_value(struct gpio_chip *chip, unsigned gpio) 23 + { 24 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 25 + 26 + return !!bcma_chipco_gpio_in(cc, 1 << gpio); 27 + } 28 + 29 + static void bcma_gpio_set_value(struct gpio_chip *chip, unsigned gpio, 30 + int value) 31 + { 32 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 33 + 34 + bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0); 35 + } 36 + 37 + static int bcma_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) 38 + { 39 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 40 + 41 + bcma_chipco_gpio_outen(cc, 1 << gpio, 0); 42 + return 0; 43 + } 44 + 45 + static int bcma_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, 46 + int value) 47 + { 48 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 49 + 50 + bcma_chipco_gpio_outen(cc, 1 << gpio, 1 << gpio); 51 + bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0); 52 + return 0; 53 + } 54 + 55 + static int bcma_gpio_request(struct gpio_chip *chip, unsigned gpio) 56 + { 57 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 58 + 59 + bcma_chipco_gpio_control(cc, 1 << gpio, 0); 60 + /* clear pulldown */ 61 + bcma_chipco_gpio_pulldown(cc, 1 << gpio, 0); 62 + /* Set pullup */ 63 + bcma_chipco_gpio_pullup(cc, 1 << gpio, 1 << gpio); 64 + 65 + return 0; 66 + } 67 + 68 + static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio) 69 + { 70 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 71 + 72 + /* clear pullup */ 73 + bcma_chipco_gpio_pullup(cc, 1 << gpio, 0); 74 + } 75 + 76 + int bcma_gpio_init(struct bcma_drv_cc *cc) 77 + { 78 + struct gpio_chip *chip = &cc->gpio; 79 + 80 + chip->label = "bcma_gpio"; 81 + chip->owner = THIS_MODULE; 82 + chip->request = bcma_gpio_request; 83 + chip->free = bcma_gpio_free; 84 + chip->get = bcma_gpio_get_value; 85 + chip->set = bcma_gpio_set_value; 86 + chip->direction_input = bcma_gpio_direction_input; 87 + chip->direction_output = bcma_gpio_direction_output; 88 + chip->ngpio = 16; 89 + /* There is just one SoC in one device and its GPIO addresses should be 90 + * deterministic to address them more easily. The other buses could get 91 + * a random base number. */ 92 + if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) 93 + chip->base = 0; 94 + else 95 + chip->base = -1; 96 + 97 + return gpiochip_add(chip); 98 + }
+5
drivers/bcma/main.c
··· 152 152 bcma_err(bus, "Error registering NAND flash\n"); 153 153 } 154 154 #endif 155 + err = bcma_gpio_init(&bus->drv_cc); 156 + if (err == -ENOTSUPP) 157 + bcma_debug(bus, "GPIO driver not activated\n"); 158 + else if (err) 159 + bcma_err(bus, "Error registering GPIO driver: %i\n", err); 155 160 156 161 return 0; 157 162 }
+5
include/linux/bcma/bcma_driver_chipcommon.h
··· 1 1 #ifndef LINUX_BCMA_DRIVER_CC_H_ 2 2 #define LINUX_BCMA_DRIVER_CC_H_ 3 3 4 + #include <linux/gpio.h> 5 + 4 6 /** ChipCommon core registers. **/ 5 7 #define BCMA_CC_ID 0x0000 6 8 #define BCMA_CC_ID_ID 0x0000FFFF ··· 572 570 573 571 /* Lock for GPIO register access. */ 574 572 spinlock_t gpio_lock; 573 + #ifdef CONFIG_BCMA_DRIVER_GPIO 574 + struct gpio_chip gpio; 575 + #endif 575 576 }; 576 577 577 578 /* Register access */