simple_gpio.c revision 3d64de9c50619d32eb71d993d23a50b98d12d3c0
1/* 2 * Simple Memory-Mapped GPIOs 3 * 4 * Copyright (c) MontaVista Software, Inc. 2008. 5 * 6 * Author: Anton Vorontsov <avorontsov@ru.mvista.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 */ 13 14#include <linux/init.h> 15#include <linux/kernel.h> 16#include <linux/module.h> 17#include <linux/spinlock.h> 18#include <linux/types.h> 19#include <linux/ioport.h> 20#include <linux/io.h> 21#include <linux/of.h> 22#include <linux/of_gpio.h> 23#include <linux/gpio.h> 24#include <asm/prom.h> 25#include "simple_gpio.h" 26 27struct u8_gpio_chip { 28 struct of_mm_gpio_chip mm_gc; 29 spinlock_t lock; 30 31 /* shadowed data register to clear/set bits safely */ 32 u8 data; 33}; 34 35static struct u8_gpio_chip *to_u8_gpio_chip(struct of_mm_gpio_chip *mm_gc) 36{ 37 return container_of(mm_gc, struct u8_gpio_chip, mm_gc); 38} 39 40static u8 u8_pin2mask(unsigned int pin) 41{ 42 return 1 << (8 - 1 - pin); 43} 44 45static int u8_gpio_get(struct gpio_chip *gc, unsigned int gpio) 46{ 47 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 48 49 return in_8(mm_gc->regs) & u8_pin2mask(gpio); 50} 51 52static void u8_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 53{ 54 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 55 struct u8_gpio_chip *u8_gc = to_u8_gpio_chip(mm_gc); 56 unsigned long flags; 57 58 spin_lock_irqsave(&u8_gc->lock, flags); 59 60 if (val) 61 u8_gc->data |= u8_pin2mask(gpio); 62 else 63 u8_gc->data &= ~u8_pin2mask(gpio); 64 65 out_8(mm_gc->regs, u8_gc->data); 66 67 spin_unlock_irqrestore(&u8_gc->lock, flags); 68} 69 70static int u8_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 71{ 72 return 0; 73} 74 75static int u8_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 76{ 77 u8_gpio_set(gc, gpio, val); 78 return 0; 79} 80 81static void u8_gpio_save_regs(struct of_mm_gpio_chip *mm_gc) 82{ 83 struct u8_gpio_chip *u8_gc = to_u8_gpio_chip(mm_gc); 84 85 u8_gc->data = in_8(mm_gc->regs); 86} 87 88static int __init u8_simple_gpiochip_add(struct device_node *np) 89{ 90 int ret; 91 struct u8_gpio_chip *u8_gc; 92 struct of_mm_gpio_chip *mm_gc; 93 struct of_gpio_chip *of_gc; 94 struct gpio_chip *gc; 95 96 u8_gc = kzalloc(sizeof(*u8_gc), GFP_KERNEL); 97 if (!u8_gc) 98 return -ENOMEM; 99 100 spin_lock_init(&u8_gc->lock); 101 102 mm_gc = &u8_gc->mm_gc; 103 of_gc = &mm_gc->of_gc; 104 gc = &of_gc->gc; 105 106 mm_gc->save_regs = u8_gpio_save_regs; 107 of_gc->gpio_cells = 2; 108 gc->ngpio = 8; 109 gc->direction_input = u8_gpio_dir_in; 110 gc->direction_output = u8_gpio_dir_out; 111 gc->get = u8_gpio_get; 112 gc->set = u8_gpio_set; 113 114 ret = of_mm_gpiochip_add(np, mm_gc); 115 if (ret) 116 goto err; 117 return 0; 118err: 119 kfree(u8_gc); 120 return ret; 121} 122 123void __init simple_gpiochip_init(const char *compatible) 124{ 125 struct device_node *np; 126 127 for_each_compatible_node(np, NULL, compatible) { 128 int ret; 129 struct resource r; 130 131 ret = of_address_to_resource(np, 0, &r); 132 if (ret) 133 goto err; 134 135 switch (resource_size(&r)) { 136 case 1: 137 ret = u8_simple_gpiochip_add(np); 138 if (ret) 139 goto err; 140 break; 141 default: 142 /* 143 * Whenever you need support for GPIO bank width > 1, 144 * please just turn u8_ code into huge macros, and 145 * construct needed uX_ code with it. 146 */ 147 ret = -ENOSYS; 148 goto err; 149 } 150 continue; 151err: 152 pr_err("%s: registration failed, status %d\n", 153 np->full_name, ret); 154 } 155} 156