aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/cs5535-gpio.c
diff options
context:
space:
mode:
authorAndres Salomon <dilinger@queued.net>2011-01-12 20:00:10 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-13 11:03:13 -0500
commit1b912c1bca5c162e611384fe7d39c916e081701a (patch)
treeae3a1c48954cec0a7f9d0b16207e9bfe6c4d22e6 /drivers/gpio/cs5535-gpio.c
parent5f003feba2a8761d2ee7b367df5a0fe6b729dc8f (diff)
drivers/gpio/cs5535-gpio.c: add some additional cs5535-specific GPIO functionality
This adds (well, re-adds actually) handling for events/IRQs through cs5535 GPIOs. In the wild and wooly world of CS5535, setup_event() is for assigning an IRQ to a GPIO filter/event pair, and set_irq() sets up the pair to trigger IRQs. These should really only be used in highly platform-specific drivers (such as OLPC's DCON driver). Sadly, because set_irq() uses MSRs, this causes the driver to become X86-specific. Signed-off-by: Andres Salomon <dilinger@queued.net> Signed-off-by: Daniel Drake <dsd@laptop.org> Cc: Grant Likely <grant.likely@secretlab.ca> Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/gpio/cs5535-gpio.c')
-rw-r--r--drivers/gpio/cs5535-gpio.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c
index d3e55a0ae92b..815d98b2c1ba 100644
--- a/drivers/gpio/cs5535-gpio.c
+++ b/drivers/gpio/cs5535-gpio.c
@@ -15,6 +15,7 @@
15#include <linux/gpio.h> 15#include <linux/gpio.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/cs5535.h> 17#include <linux/cs5535.h>
18#include <asm/msr.h>
18 19
19#define DRV_NAME "cs5535-gpio" 20#define DRV_NAME "cs5535-gpio"
20#define GPIO_BAR 1 21#define GPIO_BAR 1
@@ -144,6 +145,57 @@ int cs5535_gpio_isset(unsigned offset, unsigned int reg)
144} 145}
145EXPORT_SYMBOL_GPL(cs5535_gpio_isset); 146EXPORT_SYMBOL_GPL(cs5535_gpio_isset);
146 147
148int cs5535_gpio_set_irq(unsigned group, unsigned irq)
149{
150 uint32_t lo, hi;
151
152 if (group > 7 || irq > 15)
153 return -EINVAL;
154
155 rdmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
156
157 lo &= ~(0xF << (group * 4));
158 lo |= (irq & 0xF) << (group * 4);
159
160 wrmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
161 return 0;
162}
163EXPORT_SYMBOL_GPL(cs5535_gpio_set_irq);
164
165void cs5535_gpio_setup_event(unsigned offset, int pair, int pme)
166{
167 struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
168 uint32_t shift = (offset % 8) * 4;
169 unsigned long flags;
170 uint32_t val;
171
172 if (offset >= 24)
173 offset = GPIO_MAP_W;
174 else if (offset >= 16)
175 offset = GPIO_MAP_Z;
176 else if (offset >= 8)
177 offset = GPIO_MAP_Y;
178 else
179 offset = GPIO_MAP_X;
180
181 spin_lock_irqsave(&chip->lock, flags);
182 val = inl(chip->base + offset);
183
184 /* Clear whatever was there before */
185 val &= ~(0xF << shift);
186
187 /* Set the new value */
188 val |= ((pair & 7) << shift);
189
190 /* Set the PME bit if this is a PME event */
191 if (pme)
192 val |= (1 << (shift + 3));
193
194 outl(val, chip->base + offset);
195 spin_unlock_irqrestore(&chip->lock, flags);
196}
197EXPORT_SYMBOL_GPL(cs5535_gpio_setup_event);
198
147/* 199/*
148 * Generic gpio_chip API support. 200 * Generic gpio_chip API support.
149 */ 201 */