1*6ed9f9c4SPeter Tyser /* 2*6ed9f9c4SPeter Tyser * Intel ICH6-10, Series 5 and 6 GPIO driver 3*6ed9f9c4SPeter Tyser * 4*6ed9f9c4SPeter Tyser * Copyright (C) 2010 Extreme Engineering Solutions. 5*6ed9f9c4SPeter Tyser * 6*6ed9f9c4SPeter Tyser * This program is free software; you can redistribute it and/or modify 7*6ed9f9c4SPeter Tyser * it under the terms of the GNU General Public License as published by 8*6ed9f9c4SPeter Tyser * the Free Software Foundation; either version 2 of the License, or 9*6ed9f9c4SPeter Tyser * (at your option) any later version. 10*6ed9f9c4SPeter Tyser * 11*6ed9f9c4SPeter Tyser * This program is distributed in the hope that it will be useful, 12*6ed9f9c4SPeter Tyser * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*6ed9f9c4SPeter Tyser * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*6ed9f9c4SPeter Tyser * GNU General Public License for more details. 15*6ed9f9c4SPeter Tyser * 16*6ed9f9c4SPeter Tyser * You should have received a copy of the GNU General Public License 17*6ed9f9c4SPeter Tyser * along with this program; if not, write to the Free Software 18*6ed9f9c4SPeter Tyser * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19*6ed9f9c4SPeter Tyser */ 20*6ed9f9c4SPeter Tyser 21*6ed9f9c4SPeter Tyser #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22*6ed9f9c4SPeter Tyser 23*6ed9f9c4SPeter Tyser #include <linux/module.h> 24*6ed9f9c4SPeter Tyser #include <linux/pci.h> 25*6ed9f9c4SPeter Tyser #include <linux/gpio.h> 26*6ed9f9c4SPeter Tyser #include <linux/platform_device.h> 27*6ed9f9c4SPeter Tyser #include <linux/mfd/lpc_ich.h> 28*6ed9f9c4SPeter Tyser 29*6ed9f9c4SPeter Tyser #define DRV_NAME "gpio_ich" 30*6ed9f9c4SPeter Tyser 31*6ed9f9c4SPeter Tyser /* 32*6ed9f9c4SPeter Tyser * GPIO register offsets in GPIO I/O space. 33*6ed9f9c4SPeter Tyser * Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and 34*6ed9f9c4SPeter Tyser * LVLx registers. Logic in the read/write functions takes a register and 35*6ed9f9c4SPeter Tyser * an absolute bit number and determines the proper register offset and bit 36*6ed9f9c4SPeter Tyser * number in that register. For example, to read the value of GPIO bit 50 37*6ed9f9c4SPeter Tyser * the code would access offset ichx_regs[2(=GPIO_LVL)][1(=50/32)], 38*6ed9f9c4SPeter Tyser * bit 18 (50%32). 39*6ed9f9c4SPeter Tyser */ 40*6ed9f9c4SPeter Tyser enum GPIO_REG { 41*6ed9f9c4SPeter Tyser GPIO_USE_SEL = 0, 42*6ed9f9c4SPeter Tyser GPIO_IO_SEL, 43*6ed9f9c4SPeter Tyser GPIO_LVL, 44*6ed9f9c4SPeter Tyser }; 45*6ed9f9c4SPeter Tyser 46*6ed9f9c4SPeter Tyser static const u8 ichx_regs[3][3] = { 47*6ed9f9c4SPeter Tyser {0x00, 0x30, 0x40}, /* USE_SEL[1-3] offsets */ 48*6ed9f9c4SPeter Tyser {0x04, 0x34, 0x44}, /* IO_SEL[1-3] offsets */ 49*6ed9f9c4SPeter Tyser {0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */ 50*6ed9f9c4SPeter Tyser }; 51*6ed9f9c4SPeter Tyser 52*6ed9f9c4SPeter Tyser #define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start) 53*6ed9f9c4SPeter Tyser #define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start) 54*6ed9f9c4SPeter Tyser 55*6ed9f9c4SPeter Tyser struct ichx_desc { 56*6ed9f9c4SPeter Tyser /* Max GPIO pins the chipset can have */ 57*6ed9f9c4SPeter Tyser uint ngpio; 58*6ed9f9c4SPeter Tyser 59*6ed9f9c4SPeter Tyser /* Whether the chipset has GPIO in GPE0_STS in the PM IO region */ 60*6ed9f9c4SPeter Tyser bool uses_gpe0; 61*6ed9f9c4SPeter Tyser 62*6ed9f9c4SPeter Tyser /* USE_SEL is bogus on some chipsets, eg 3100 */ 63*6ed9f9c4SPeter Tyser u32 use_sel_ignore[3]; 64*6ed9f9c4SPeter Tyser 65*6ed9f9c4SPeter Tyser /* Some chipsets have quirks, let these use their own request/get */ 66*6ed9f9c4SPeter Tyser int (*request)(struct gpio_chip *chip, unsigned offset); 67*6ed9f9c4SPeter Tyser int (*get)(struct gpio_chip *chip, unsigned offset); 68*6ed9f9c4SPeter Tyser }; 69*6ed9f9c4SPeter Tyser 70*6ed9f9c4SPeter Tyser static struct { 71*6ed9f9c4SPeter Tyser spinlock_t lock; 72*6ed9f9c4SPeter Tyser struct platform_device *dev; 73*6ed9f9c4SPeter Tyser struct gpio_chip chip; 74*6ed9f9c4SPeter Tyser struct resource *gpio_base; /* GPIO IO base */ 75*6ed9f9c4SPeter Tyser struct resource *pm_base; /* Power Mangagment IO base */ 76*6ed9f9c4SPeter Tyser struct ichx_desc *desc; /* Pointer to chipset-specific description */ 77*6ed9f9c4SPeter Tyser u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */ 78*6ed9f9c4SPeter Tyser } ichx_priv; 79*6ed9f9c4SPeter Tyser 80*6ed9f9c4SPeter Tyser static int modparam_gpiobase = -1; /* dynamic */ 81*6ed9f9c4SPeter Tyser module_param_named(gpiobase, modparam_gpiobase, int, 0444); 82*6ed9f9c4SPeter Tyser MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, " 83*6ed9f9c4SPeter Tyser "which is the default."); 84*6ed9f9c4SPeter Tyser 85*6ed9f9c4SPeter Tyser static int ichx_write_bit(int reg, unsigned nr, int val, int verify) 86*6ed9f9c4SPeter Tyser { 87*6ed9f9c4SPeter Tyser unsigned long flags; 88*6ed9f9c4SPeter Tyser u32 data, tmp; 89*6ed9f9c4SPeter Tyser int reg_nr = nr / 32; 90*6ed9f9c4SPeter Tyser int bit = nr & 0x1f; 91*6ed9f9c4SPeter Tyser int ret = 0; 92*6ed9f9c4SPeter Tyser 93*6ed9f9c4SPeter Tyser spin_lock_irqsave(&ichx_priv.lock, flags); 94*6ed9f9c4SPeter Tyser 95*6ed9f9c4SPeter Tyser data = ICHX_READ(ichx_regs[reg][reg_nr], ichx_priv.gpio_base); 96*6ed9f9c4SPeter Tyser if (val) 97*6ed9f9c4SPeter Tyser data |= 1 << bit; 98*6ed9f9c4SPeter Tyser else 99*6ed9f9c4SPeter Tyser data &= ~(1 << bit); 100*6ed9f9c4SPeter Tyser ICHX_WRITE(data, ichx_regs[reg][reg_nr], ichx_priv.gpio_base); 101*6ed9f9c4SPeter Tyser tmp = ICHX_READ(ichx_regs[reg][reg_nr], ichx_priv.gpio_base); 102*6ed9f9c4SPeter Tyser if (verify && data != tmp) 103*6ed9f9c4SPeter Tyser ret = -EPERM; 104*6ed9f9c4SPeter Tyser 105*6ed9f9c4SPeter Tyser spin_unlock_irqrestore(&ichx_priv.lock, flags); 106*6ed9f9c4SPeter Tyser 107*6ed9f9c4SPeter Tyser return ret; 108*6ed9f9c4SPeter Tyser } 109*6ed9f9c4SPeter Tyser 110*6ed9f9c4SPeter Tyser static int ichx_read_bit(int reg, unsigned nr) 111*6ed9f9c4SPeter Tyser { 112*6ed9f9c4SPeter Tyser unsigned long flags; 113*6ed9f9c4SPeter Tyser u32 data; 114*6ed9f9c4SPeter Tyser int reg_nr = nr / 32; 115*6ed9f9c4SPeter Tyser int bit = nr & 0x1f; 116*6ed9f9c4SPeter Tyser 117*6ed9f9c4SPeter Tyser spin_lock_irqsave(&ichx_priv.lock, flags); 118*6ed9f9c4SPeter Tyser 119*6ed9f9c4SPeter Tyser data = ICHX_READ(ichx_regs[reg][reg_nr], ichx_priv.gpio_base); 120*6ed9f9c4SPeter Tyser 121*6ed9f9c4SPeter Tyser spin_unlock_irqrestore(&ichx_priv.lock, flags); 122*6ed9f9c4SPeter Tyser 123*6ed9f9c4SPeter Tyser return data & (1 << bit) ? 1 : 0; 124*6ed9f9c4SPeter Tyser } 125*6ed9f9c4SPeter Tyser 126*6ed9f9c4SPeter Tyser static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) 127*6ed9f9c4SPeter Tyser { 128*6ed9f9c4SPeter Tyser /* 129*6ed9f9c4SPeter Tyser * Try setting pin as an input and verify it worked since many pins 130*6ed9f9c4SPeter Tyser * are output-only. 131*6ed9f9c4SPeter Tyser */ 132*6ed9f9c4SPeter Tyser if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1)) 133*6ed9f9c4SPeter Tyser return -EINVAL; 134*6ed9f9c4SPeter Tyser 135*6ed9f9c4SPeter Tyser return 0; 136*6ed9f9c4SPeter Tyser } 137*6ed9f9c4SPeter Tyser 138*6ed9f9c4SPeter Tyser static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, 139*6ed9f9c4SPeter Tyser int val) 140*6ed9f9c4SPeter Tyser { 141*6ed9f9c4SPeter Tyser /* Set GPIO output value. */ 142*6ed9f9c4SPeter Tyser ichx_write_bit(GPIO_LVL, nr, val, 0); 143*6ed9f9c4SPeter Tyser 144*6ed9f9c4SPeter Tyser /* 145*6ed9f9c4SPeter Tyser * Try setting pin as an output and verify it worked since many pins 146*6ed9f9c4SPeter Tyser * are input-only. 147*6ed9f9c4SPeter Tyser */ 148*6ed9f9c4SPeter Tyser if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1)) 149*6ed9f9c4SPeter Tyser return -EINVAL; 150*6ed9f9c4SPeter Tyser 151*6ed9f9c4SPeter Tyser return 0; 152*6ed9f9c4SPeter Tyser } 153*6ed9f9c4SPeter Tyser 154*6ed9f9c4SPeter Tyser static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr) 155*6ed9f9c4SPeter Tyser { 156*6ed9f9c4SPeter Tyser return ichx_read_bit(GPIO_LVL, nr); 157*6ed9f9c4SPeter Tyser } 158*6ed9f9c4SPeter Tyser 159*6ed9f9c4SPeter Tyser static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr) 160*6ed9f9c4SPeter Tyser { 161*6ed9f9c4SPeter Tyser unsigned long flags; 162*6ed9f9c4SPeter Tyser u32 data; 163*6ed9f9c4SPeter Tyser 164*6ed9f9c4SPeter Tyser /* 165*6ed9f9c4SPeter Tyser * GPI 0 - 15 need to be read from the power management registers on 166*6ed9f9c4SPeter Tyser * a ICH6/3100 bridge. 167*6ed9f9c4SPeter Tyser */ 168*6ed9f9c4SPeter Tyser if (nr < 16) { 169*6ed9f9c4SPeter Tyser if (!ichx_priv.pm_base) 170*6ed9f9c4SPeter Tyser return -ENXIO; 171*6ed9f9c4SPeter Tyser 172*6ed9f9c4SPeter Tyser spin_lock_irqsave(&ichx_priv.lock, flags); 173*6ed9f9c4SPeter Tyser 174*6ed9f9c4SPeter Tyser /* GPI 0 - 15 are latched, write 1 to clear*/ 175*6ed9f9c4SPeter Tyser ICHX_WRITE(1 << (16 + nr), 0, ichx_priv.pm_base); 176*6ed9f9c4SPeter Tyser data = ICHX_READ(0, ichx_priv.pm_base); 177*6ed9f9c4SPeter Tyser 178*6ed9f9c4SPeter Tyser spin_unlock_irqrestore(&ichx_priv.lock, flags); 179*6ed9f9c4SPeter Tyser 180*6ed9f9c4SPeter Tyser return (data >> 16) & (1 << nr) ? 1 : 0; 181*6ed9f9c4SPeter Tyser } else { 182*6ed9f9c4SPeter Tyser return ichx_gpio_get(chip, nr); 183*6ed9f9c4SPeter Tyser } 184*6ed9f9c4SPeter Tyser } 185*6ed9f9c4SPeter Tyser 186*6ed9f9c4SPeter Tyser static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr) 187*6ed9f9c4SPeter Tyser { 188*6ed9f9c4SPeter Tyser /* 189*6ed9f9c4SPeter Tyser * Note we assume the BIOS properly set a bridge's USE value. Some 190*6ed9f9c4SPeter Tyser * chips (eg Intel 3100) have bogus USE values though, so first see if 191*6ed9f9c4SPeter Tyser * the chipset's USE value can be trusted for this specific bit. 192*6ed9f9c4SPeter Tyser * If it can't be trusted, assume that the pin can be used as a GPIO. 193*6ed9f9c4SPeter Tyser */ 194*6ed9f9c4SPeter Tyser if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f))) 195*6ed9f9c4SPeter Tyser return 1; 196*6ed9f9c4SPeter Tyser 197*6ed9f9c4SPeter Tyser return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV; 198*6ed9f9c4SPeter Tyser } 199*6ed9f9c4SPeter Tyser 200*6ed9f9c4SPeter Tyser static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr) 201*6ed9f9c4SPeter Tyser { 202*6ed9f9c4SPeter Tyser /* 203*6ed9f9c4SPeter Tyser * Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100 204*6ed9f9c4SPeter Tyser * bridge as they are controlled by USE register bits 0 and 1. See 205*6ed9f9c4SPeter Tyser * "Table 704 GPIO_USE_SEL1 register" in the i3100 datasheet for 206*6ed9f9c4SPeter Tyser * additional info. 207*6ed9f9c4SPeter Tyser */ 208*6ed9f9c4SPeter Tyser if (nr == 16 || nr == 17) 209*6ed9f9c4SPeter Tyser nr -= 16; 210*6ed9f9c4SPeter Tyser 211*6ed9f9c4SPeter Tyser return ichx_gpio_request(chip, nr); 212*6ed9f9c4SPeter Tyser } 213*6ed9f9c4SPeter Tyser 214*6ed9f9c4SPeter Tyser static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val) 215*6ed9f9c4SPeter Tyser { 216*6ed9f9c4SPeter Tyser ichx_write_bit(GPIO_LVL, nr, val, 0); 217*6ed9f9c4SPeter Tyser } 218*6ed9f9c4SPeter Tyser 219*6ed9f9c4SPeter Tyser static void __devinit ichx_gpiolib_setup(struct gpio_chip *chip) 220*6ed9f9c4SPeter Tyser { 221*6ed9f9c4SPeter Tyser chip->owner = THIS_MODULE; 222*6ed9f9c4SPeter Tyser chip->label = DRV_NAME; 223*6ed9f9c4SPeter Tyser chip->dev = &ichx_priv.dev->dev; 224*6ed9f9c4SPeter Tyser 225*6ed9f9c4SPeter Tyser /* Allow chip-specific overrides of request()/get() */ 226*6ed9f9c4SPeter Tyser chip->request = ichx_priv.desc->request ? 227*6ed9f9c4SPeter Tyser ichx_priv.desc->request : ichx_gpio_request; 228*6ed9f9c4SPeter Tyser chip->get = ichx_priv.desc->get ? 229*6ed9f9c4SPeter Tyser ichx_priv.desc->get : ichx_gpio_get; 230*6ed9f9c4SPeter Tyser 231*6ed9f9c4SPeter Tyser chip->set = ichx_gpio_set; 232*6ed9f9c4SPeter Tyser chip->direction_input = ichx_gpio_direction_input; 233*6ed9f9c4SPeter Tyser chip->direction_output = ichx_gpio_direction_output; 234*6ed9f9c4SPeter Tyser chip->base = modparam_gpiobase; 235*6ed9f9c4SPeter Tyser chip->ngpio = ichx_priv.desc->ngpio; 236*6ed9f9c4SPeter Tyser chip->can_sleep = 0; 237*6ed9f9c4SPeter Tyser chip->dbg_show = NULL; 238*6ed9f9c4SPeter Tyser } 239*6ed9f9c4SPeter Tyser 240*6ed9f9c4SPeter Tyser /* ICH6-based, 631xesb-based */ 241*6ed9f9c4SPeter Tyser static struct ichx_desc ich6_desc = { 242*6ed9f9c4SPeter Tyser /* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */ 243*6ed9f9c4SPeter Tyser .request = ich6_gpio_request, 244*6ed9f9c4SPeter Tyser .get = ich6_gpio_get, 245*6ed9f9c4SPeter Tyser 246*6ed9f9c4SPeter Tyser /* GPIO 0-15 are read in the GPE0_STS PM register */ 247*6ed9f9c4SPeter Tyser .uses_gpe0 = true, 248*6ed9f9c4SPeter Tyser 249*6ed9f9c4SPeter Tyser .ngpio = 50, 250*6ed9f9c4SPeter Tyser }; 251*6ed9f9c4SPeter Tyser 252*6ed9f9c4SPeter Tyser /* Intel 3100 */ 253*6ed9f9c4SPeter Tyser static struct ichx_desc i3100_desc = { 254*6ed9f9c4SPeter Tyser /* 255*6ed9f9c4SPeter Tyser * Bits 16,17, 20 of USE_SEL and bit 16 of USE_SEL2 always read 0 on 256*6ed9f9c4SPeter Tyser * the Intel 3100. See "Table 712. GPIO Summary Table" of 3100 257*6ed9f9c4SPeter Tyser * Datasheet for more info. 258*6ed9f9c4SPeter Tyser */ 259*6ed9f9c4SPeter Tyser .use_sel_ignore = {0x00130000, 0x00010000, 0x0}, 260*6ed9f9c4SPeter Tyser 261*6ed9f9c4SPeter Tyser /* The 3100 needs fixups for GPIO 0 - 17 */ 262*6ed9f9c4SPeter Tyser .request = ich6_gpio_request, 263*6ed9f9c4SPeter Tyser .get = ich6_gpio_get, 264*6ed9f9c4SPeter Tyser 265*6ed9f9c4SPeter Tyser /* GPIO 0-15 are read in the GPE0_STS PM register */ 266*6ed9f9c4SPeter Tyser .uses_gpe0 = true, 267*6ed9f9c4SPeter Tyser 268*6ed9f9c4SPeter Tyser .ngpio = 50, 269*6ed9f9c4SPeter Tyser }; 270*6ed9f9c4SPeter Tyser 271*6ed9f9c4SPeter Tyser /* ICH7 and ICH8-based */ 272*6ed9f9c4SPeter Tyser static struct ichx_desc ich7_desc = { 273*6ed9f9c4SPeter Tyser .ngpio = 50, 274*6ed9f9c4SPeter Tyser }; 275*6ed9f9c4SPeter Tyser 276*6ed9f9c4SPeter Tyser /* ICH9-based */ 277*6ed9f9c4SPeter Tyser static struct ichx_desc ich9_desc = { 278*6ed9f9c4SPeter Tyser .ngpio = 61, 279*6ed9f9c4SPeter Tyser }; 280*6ed9f9c4SPeter Tyser 281*6ed9f9c4SPeter Tyser /* ICH10-based - Consumer/corporate versions have different amount of GPIO */ 282*6ed9f9c4SPeter Tyser static struct ichx_desc ich10_cons_desc = { 283*6ed9f9c4SPeter Tyser .ngpio = 61, 284*6ed9f9c4SPeter Tyser }; 285*6ed9f9c4SPeter Tyser static struct ichx_desc ich10_corp_desc = { 286*6ed9f9c4SPeter Tyser .ngpio = 72, 287*6ed9f9c4SPeter Tyser }; 288*6ed9f9c4SPeter Tyser 289*6ed9f9c4SPeter Tyser /* Intel 5 series, 6 series, 3400 series, and C200 series */ 290*6ed9f9c4SPeter Tyser static struct ichx_desc intel5_desc = { 291*6ed9f9c4SPeter Tyser .ngpio = 76, 292*6ed9f9c4SPeter Tyser }; 293*6ed9f9c4SPeter Tyser 294*6ed9f9c4SPeter Tyser static int __devinit ichx_gpio_probe(struct platform_device *pdev) 295*6ed9f9c4SPeter Tyser { 296*6ed9f9c4SPeter Tyser struct resource *res_base, *res_pm; 297*6ed9f9c4SPeter Tyser int err; 298*6ed9f9c4SPeter Tyser struct lpc_ich_info *ich_info = pdev->dev.platform_data; 299*6ed9f9c4SPeter Tyser 300*6ed9f9c4SPeter Tyser if (!ich_info) 301*6ed9f9c4SPeter Tyser return -ENODEV; 302*6ed9f9c4SPeter Tyser 303*6ed9f9c4SPeter Tyser ichx_priv.dev = pdev; 304*6ed9f9c4SPeter Tyser 305*6ed9f9c4SPeter Tyser switch (ich_info->gpio_version) { 306*6ed9f9c4SPeter Tyser case ICH_I3100_GPIO: 307*6ed9f9c4SPeter Tyser ichx_priv.desc = &i3100_desc; 308*6ed9f9c4SPeter Tyser break; 309*6ed9f9c4SPeter Tyser case ICH_V5_GPIO: 310*6ed9f9c4SPeter Tyser ichx_priv.desc = &intel5_desc; 311*6ed9f9c4SPeter Tyser break; 312*6ed9f9c4SPeter Tyser case ICH_V6_GPIO: 313*6ed9f9c4SPeter Tyser ichx_priv.desc = &ich6_desc; 314*6ed9f9c4SPeter Tyser break; 315*6ed9f9c4SPeter Tyser case ICH_V7_GPIO: 316*6ed9f9c4SPeter Tyser ichx_priv.desc = &ich7_desc; 317*6ed9f9c4SPeter Tyser break; 318*6ed9f9c4SPeter Tyser case ICH_V9_GPIO: 319*6ed9f9c4SPeter Tyser ichx_priv.desc = &ich9_desc; 320*6ed9f9c4SPeter Tyser break; 321*6ed9f9c4SPeter Tyser case ICH_V10CORP_GPIO: 322*6ed9f9c4SPeter Tyser ichx_priv.desc = &ich10_corp_desc; 323*6ed9f9c4SPeter Tyser break; 324*6ed9f9c4SPeter Tyser case ICH_V10CONS_GPIO: 325*6ed9f9c4SPeter Tyser ichx_priv.desc = &ich10_cons_desc; 326*6ed9f9c4SPeter Tyser break; 327*6ed9f9c4SPeter Tyser default: 328*6ed9f9c4SPeter Tyser return -ENODEV; 329*6ed9f9c4SPeter Tyser } 330*6ed9f9c4SPeter Tyser 331*6ed9f9c4SPeter Tyser res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); 332*6ed9f9c4SPeter Tyser if (!res_base || !res_base->start || !res_base->end) 333*6ed9f9c4SPeter Tyser return -ENODEV; 334*6ed9f9c4SPeter Tyser 335*6ed9f9c4SPeter Tyser if (!request_region(res_base->start, resource_size(res_base), 336*6ed9f9c4SPeter Tyser pdev->name)) 337*6ed9f9c4SPeter Tyser return -EBUSY; 338*6ed9f9c4SPeter Tyser 339*6ed9f9c4SPeter Tyser ichx_priv.gpio_base = res_base; 340*6ed9f9c4SPeter Tyser 341*6ed9f9c4SPeter Tyser /* 342*6ed9f9c4SPeter Tyser * If necessary, determine the I/O address of ACPI/power management 343*6ed9f9c4SPeter Tyser * registers which are needed to read the the GPE0 register for GPI pins 344*6ed9f9c4SPeter Tyser * 0 - 15 on some chipsets. 345*6ed9f9c4SPeter Tyser */ 346*6ed9f9c4SPeter Tyser if (!ichx_priv.desc->uses_gpe0) 347*6ed9f9c4SPeter Tyser goto init; 348*6ed9f9c4SPeter Tyser 349*6ed9f9c4SPeter Tyser res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0); 350*6ed9f9c4SPeter Tyser if (!res_pm) { 351*6ed9f9c4SPeter Tyser pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n"); 352*6ed9f9c4SPeter Tyser goto init; 353*6ed9f9c4SPeter Tyser } 354*6ed9f9c4SPeter Tyser 355*6ed9f9c4SPeter Tyser if (!request_region(res_pm->start, resource_size(res_pm), 356*6ed9f9c4SPeter Tyser pdev->name)) { 357*6ed9f9c4SPeter Tyser pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n"); 358*6ed9f9c4SPeter Tyser goto init; 359*6ed9f9c4SPeter Tyser } 360*6ed9f9c4SPeter Tyser 361*6ed9f9c4SPeter Tyser ichx_priv.pm_base = res_pm; 362*6ed9f9c4SPeter Tyser 363*6ed9f9c4SPeter Tyser init: 364*6ed9f9c4SPeter Tyser ichx_gpiolib_setup(&ichx_priv.chip); 365*6ed9f9c4SPeter Tyser err = gpiochip_add(&ichx_priv.chip); 366*6ed9f9c4SPeter Tyser if (err) { 367*6ed9f9c4SPeter Tyser pr_err("Failed to register GPIOs\n"); 368*6ed9f9c4SPeter Tyser goto add_err; 369*6ed9f9c4SPeter Tyser } 370*6ed9f9c4SPeter Tyser 371*6ed9f9c4SPeter Tyser pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base, 372*6ed9f9c4SPeter Tyser ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME); 373*6ed9f9c4SPeter Tyser 374*6ed9f9c4SPeter Tyser return 0; 375*6ed9f9c4SPeter Tyser 376*6ed9f9c4SPeter Tyser add_err: 377*6ed9f9c4SPeter Tyser release_region(ichx_priv.gpio_base->start, 378*6ed9f9c4SPeter Tyser resource_size(ichx_priv.gpio_base)); 379*6ed9f9c4SPeter Tyser if (ichx_priv.pm_base) 380*6ed9f9c4SPeter Tyser release_region(ichx_priv.pm_base->start, 381*6ed9f9c4SPeter Tyser resource_size(ichx_priv.pm_base)); 382*6ed9f9c4SPeter Tyser return err; 383*6ed9f9c4SPeter Tyser } 384*6ed9f9c4SPeter Tyser 385*6ed9f9c4SPeter Tyser static int __devexit ichx_gpio_remove(struct platform_device *pdev) 386*6ed9f9c4SPeter Tyser { 387*6ed9f9c4SPeter Tyser int err; 388*6ed9f9c4SPeter Tyser 389*6ed9f9c4SPeter Tyser err = gpiochip_remove(&ichx_priv.chip); 390*6ed9f9c4SPeter Tyser if (err) { 391*6ed9f9c4SPeter Tyser dev_err(&pdev->dev, "%s failed, %d\n", 392*6ed9f9c4SPeter Tyser "gpiochip_remove()", err); 393*6ed9f9c4SPeter Tyser return err; 394*6ed9f9c4SPeter Tyser } 395*6ed9f9c4SPeter Tyser 396*6ed9f9c4SPeter Tyser release_region(ichx_priv.gpio_base->start, 397*6ed9f9c4SPeter Tyser resource_size(ichx_priv.gpio_base)); 398*6ed9f9c4SPeter Tyser if (ichx_priv.pm_base) 399*6ed9f9c4SPeter Tyser release_region(ichx_priv.pm_base->start, 400*6ed9f9c4SPeter Tyser resource_size(ichx_priv.pm_base)); 401*6ed9f9c4SPeter Tyser 402*6ed9f9c4SPeter Tyser return 0; 403*6ed9f9c4SPeter Tyser } 404*6ed9f9c4SPeter Tyser 405*6ed9f9c4SPeter Tyser static struct platform_driver ichx_gpio_driver = { 406*6ed9f9c4SPeter Tyser .driver = { 407*6ed9f9c4SPeter Tyser .owner = THIS_MODULE, 408*6ed9f9c4SPeter Tyser .name = DRV_NAME, 409*6ed9f9c4SPeter Tyser }, 410*6ed9f9c4SPeter Tyser .probe = ichx_gpio_probe, 411*6ed9f9c4SPeter Tyser .remove = __devexit_p(ichx_gpio_remove), 412*6ed9f9c4SPeter Tyser }; 413*6ed9f9c4SPeter Tyser 414*6ed9f9c4SPeter Tyser module_platform_driver(ichx_gpio_driver); 415*6ed9f9c4SPeter Tyser 416*6ed9f9c4SPeter Tyser MODULE_AUTHOR("Peter Tyser <ptyser@xes-inc.com>"); 417*6ed9f9c4SPeter Tyser MODULE_DESCRIPTION("GPIO interface for Intel ICH series"); 418*6ed9f9c4SPeter Tyser MODULE_LICENSE("GPL"); 419*6ed9f9c4SPeter Tyser MODULE_ALIAS("platform:"DRV_NAME); 420