1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net> 7 */ 8 9#include <linux/export.h> 10#include <linux/ssb/ssb.h> 11#include <linux/ssb/ssb_driver_chipcommon.h> 12#include <linux/ssb/ssb_driver_extif.h> 13#include <asm/mach-bcm47xx/bcm47xx.h> 14#include <asm/mach-bcm47xx/gpio.h> 15 16#if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES) 17static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES); 18#else 19static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES); 20#endif 21 22int gpio_request(unsigned gpio, const char *tag) 23{ 24 switch (bcm47xx_bus_type) { 25#ifdef CONFIG_BCM47XX_SSB 26 case BCM47XX_BUS_TYPE_SSB: 27 if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) && 28 ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) 29 return -EINVAL; 30 31 if (ssb_extif_available(&bcm47xx_bus.ssb.extif) && 32 ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) 33 return -EINVAL; 34 35 if (test_and_set_bit(gpio, gpio_in_use)) 36 return -EBUSY; 37 38 return 0; 39#endif 40#ifdef CONFIG_BCM47XX_BCMA 41 case BCM47XX_BUS_TYPE_BCMA: 42 if (gpio >= BCM47XX_CHIPCO_GPIO_LINES) 43 return -EINVAL; 44 45 if (test_and_set_bit(gpio, gpio_in_use)) 46 return -EBUSY; 47 48 return 0; 49#endif 50 } 51 return -EINVAL; 52} 53EXPORT_SYMBOL(gpio_request); 54 55void gpio_free(unsigned gpio) 56{ 57 switch (bcm47xx_bus_type) { 58#ifdef CONFIG_BCM47XX_SSB 59 case BCM47XX_BUS_TYPE_SSB: 60 if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) && 61 ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) 62 return; 63 64 if (ssb_extif_available(&bcm47xx_bus.ssb.extif) && 65 ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) 66 return; 67 68 clear_bit(gpio, gpio_in_use); 69 return; 70#endif 71#ifdef CONFIG_BCM47XX_BCMA 72 case BCM47XX_BUS_TYPE_BCMA: 73 if (gpio >= BCM47XX_CHIPCO_GPIO_LINES) 74 return; 75 76 clear_bit(gpio, gpio_in_use); 77 return; 78#endif 79 } 80} 81EXPORT_SYMBOL(gpio_free); 82 83int gpio_to_irq(unsigned gpio) 84{ 85 switch (bcm47xx_bus_type) { 86#ifdef CONFIG_BCM47XX_SSB 87 case BCM47XX_BUS_TYPE_SSB: 88 if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco)) 89 return ssb_mips_irq(bcm47xx_bus.ssb.chipco.dev) + 2; 90 else if (ssb_extif_available(&bcm47xx_bus.ssb.extif)) 91 return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2; 92 else 93 return -EINVAL; 94#endif 95#ifdef CONFIG_BCM47XX_BCMA 96 case BCM47XX_BUS_TYPE_BCMA: 97 return bcma_core_mips_irq(bcm47xx_bus.bcma.bus.drv_cc.core) + 2; 98#endif 99 } 100 return -EINVAL; 101} 102EXPORT_SYMBOL_GPL(gpio_to_irq); 103