xref: /openbmc/linux/drivers/gpio/gpio-ich.c (revision 6ed9f9c405f97cb7cda485f589cfa6c2bb3fb78e)
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