Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.30-rc8 171 lines 4.0 kB view raw
1/* 2 * GPIOs on MPC8349/8572/8610 and compatible 3 * 4 * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk> 5 * 6 * This file is licensed under the terms of the GNU General Public License 7 * version 2. This program is licensed "as is" without any warranty of any 8 * kind, whether express or implied. 9 */ 10 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/spinlock.h> 14#include <linux/io.h> 15#include <linux/of.h> 16#include <linux/of_gpio.h> 17#include <linux/gpio.h> 18 19#define MPC8XXX_GPIO_PINS 32 20 21#define GPIO_DIR 0x00 22#define GPIO_ODR 0x04 23#define GPIO_DAT 0x08 24#define GPIO_IER 0x0c 25#define GPIO_IMR 0x10 26#define GPIO_ICR 0x14 27 28struct mpc8xxx_gpio_chip { 29 struct of_mm_gpio_chip mm_gc; 30 spinlock_t lock; 31 32 /* 33 * shadowed data register to be able to clear/set output pins in 34 * open drain mode safely 35 */ 36 u32 data; 37}; 38 39static inline u32 mpc8xxx_gpio2mask(unsigned int gpio) 40{ 41 return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio); 42} 43 44static inline struct mpc8xxx_gpio_chip * 45to_mpc8xxx_gpio_chip(struct of_mm_gpio_chip *mm) 46{ 47 return container_of(mm, struct mpc8xxx_gpio_chip, mm_gc); 48} 49 50static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm) 51{ 52 struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); 53 54 mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT); 55} 56 57static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) 58{ 59 struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); 60 61 return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio); 62} 63 64static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 65{ 66 struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); 67 struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); 68 unsigned long flags; 69 70 spin_lock_irqsave(&mpc8xxx_gc->lock, flags); 71 72 if (val) 73 mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio); 74 else 75 mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio); 76 77 out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data); 78 79 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); 80} 81 82static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 83{ 84 struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); 85 struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); 86 unsigned long flags; 87 88 spin_lock_irqsave(&mpc8xxx_gc->lock, flags); 89 90 clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio)); 91 92 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); 93 94 return 0; 95} 96 97static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 98{ 99 struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); 100 struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); 101 unsigned long flags; 102 103 mpc8xxx_gpio_set(gc, gpio, val); 104 105 spin_lock_irqsave(&mpc8xxx_gc->lock, flags); 106 107 setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio)); 108 109 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); 110 111 return 0; 112} 113 114static void __init mpc8xxx_add_controller(struct device_node *np) 115{ 116 struct mpc8xxx_gpio_chip *mpc8xxx_gc; 117 struct of_mm_gpio_chip *mm_gc; 118 struct of_gpio_chip *of_gc; 119 struct gpio_chip *gc; 120 int ret; 121 122 mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL); 123 if (!mpc8xxx_gc) { 124 ret = -ENOMEM; 125 goto err; 126 } 127 128 spin_lock_init(&mpc8xxx_gc->lock); 129 130 mm_gc = &mpc8xxx_gc->mm_gc; 131 of_gc = &mm_gc->of_gc; 132 gc = &of_gc->gc; 133 134 mm_gc->save_regs = mpc8xxx_gpio_save_regs; 135 of_gc->gpio_cells = 2; 136 gc->ngpio = MPC8XXX_GPIO_PINS; 137 gc->direction_input = mpc8xxx_gpio_dir_in; 138 gc->direction_output = mpc8xxx_gpio_dir_out; 139 gc->get = mpc8xxx_gpio_get; 140 gc->set = mpc8xxx_gpio_set; 141 142 ret = of_mm_gpiochip_add(np, mm_gc); 143 if (ret) 144 goto err; 145 146 return; 147 148err: 149 pr_err("%s: registration failed with status %d\n", 150 np->full_name, ret); 151 kfree(mpc8xxx_gc); 152 153 return; 154} 155 156static int __init mpc8xxx_add_gpiochips(void) 157{ 158 struct device_node *np; 159 160 for_each_compatible_node(np, NULL, "fsl,mpc8349-gpio") 161 mpc8xxx_add_controller(np); 162 163 for_each_compatible_node(np, NULL, "fsl,mpc8572-gpio") 164 mpc8xxx_add_controller(np); 165 166 for_each_compatible_node(np, NULL, "fsl,mpc8610-gpio") 167 mpc8xxx_add_controller(np); 168 169 return 0; 170} 171arch_initcall(mpc8xxx_add_gpiochips);