aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/langwell_gpio.c83
1 files changed, 82 insertions, 1 deletions
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c
index 222de1292e2b..64db9dc3a275 100644
--- a/drivers/gpio/langwell_gpio.c
+++ b/drivers/gpio/langwell_gpio.c
@@ -18,10 +18,12 @@
18/* Supports: 18/* Supports:
19 * Moorestown platform Langwell chip. 19 * Moorestown platform Langwell chip.
20 * Medfield platform Penwell chip. 20 * Medfield platform Penwell chip.
21 * Whitney point.
21 */ 22 */
22 23
23#include <linux/module.h> 24#include <linux/module.h>
24#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/platform_device.h>
25#include <linux/kernel.h> 27#include <linux/kernel.h>
26#include <linux/delay.h> 28#include <linux/delay.h>
27#include <linux/stddef.h> 29#include <linux/stddef.h>
@@ -300,9 +302,88 @@ static struct pci_driver lnw_gpio_driver = {
300 .probe = lnw_gpio_probe, 302 .probe = lnw_gpio_probe,
301}; 303};
302 304
305
306static int __devinit wp_gpio_probe(struct platform_device *pdev)
307{
308 struct lnw_gpio *lnw;
309 struct gpio_chip *gc;
310 struct resource *rc;
311 int retval = 0;
312
313 rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
314 if (!rc)
315 return -EINVAL;
316
317 lnw = kzalloc(sizeof(struct lnw_gpio), GFP_KERNEL);
318 if (!lnw) {
319 dev_err(&pdev->dev,
320 "can't allocate whitneypoint_gpio chip data\n");
321 return -ENOMEM;
322 }
323 lnw->reg_base = ioremap_nocache(rc->start, resource_size(rc));
324 if (lnw->reg_base == NULL) {
325 retval = -EINVAL;
326 goto err_kmalloc;
327 }
328 spin_lock_init(&lnw->lock);
329 gc = &lnw->chip;
330 gc->label = dev_name(&pdev->dev);
331 gc->owner = THIS_MODULE;
332 gc->direction_input = lnw_gpio_direction_input;
333 gc->direction_output = lnw_gpio_direction_output;
334 gc->get = lnw_gpio_get;
335 gc->set = lnw_gpio_set;
336 gc->to_irq = NULL;
337 gc->base = 0;
338 gc->ngpio = 64;
339 gc->can_sleep = 0;
340 retval = gpiochip_add(gc);
341 if (retval) {
342 dev_err(&pdev->dev, "whitneypoint gpiochip_add error %d\n",
343 retval);
344 goto err_ioremap;
345 }
346 platform_set_drvdata(pdev, lnw);
347 return 0;
348err_ioremap:
349 iounmap(lnw->reg_base);
350err_kmalloc:
351 kfree(lnw);
352 return retval;
353}
354
355static int __devexit wp_gpio_remove(struct platform_device *pdev)
356{
357 struct lnw_gpio *lnw = platform_get_drvdata(pdev);
358 int err;
359 err = gpiochip_remove(&lnw->chip);
360 if (err)
361 dev_err(&pdev->dev, "failed to remove gpio_chip.\n");
362 iounmap(lnw->reg_base);
363 kfree(lnw);
364 platform_set_drvdata(pdev, NULL);
365 return 0;
366}
367
368static struct platform_driver wp_gpio_driver = {
369 .probe = wp_gpio_probe,
370 .remove = __devexit_p(wp_gpio_remove),
371 .driver = {
372 .name = "wp_gpio",
373 .owner = THIS_MODULE,
374 },
375};
376
303static int __init lnw_gpio_init(void) 377static int __init lnw_gpio_init(void)
304{ 378{
305 return pci_register_driver(&lnw_gpio_driver); 379 int ret;
380 ret = pci_register_driver(&lnw_gpio_driver);
381 if (ret < 0)
382 return ret;
383 ret = platform_driver_register(&wp_gpio_driver);
384 if (ret < 0)
385 pci_unregister_driver(&lnw_gpio_driver);
386 return ret;
306} 387}
307 388
308device_initcall(lnw_gpio_init); 389device_initcall(lnw_gpio_init);