diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-08-21 07:28:24 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-08-21 07:28:24 -0400 |
| commit | 470fba7ebe60ad9185056b080b331abad24b4df9 (patch) | |
| tree | f83bc13d97adaf5dd0e0f1d6a157b890f868577f /arch/powerpc/sysdev/cpm_common.c | |
| parent | 7225e75144b9718cbbe1820d9c011c809d5773fd (diff) | |
| parent | 6a55617ed5d1aa62b850de2cf66f5ede2eef4825 (diff) | |
Merge branch 'linus' into x86/doc
Diffstat (limited to 'arch/powerpc/sysdev/cpm_common.c')
| -rw-r--r-- | arch/powerpc/sysdev/cpm_common.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index e4b7296acb2c..53da8a079f96 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | 19 | ||
| 20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
| 21 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
| 22 | #include <linux/spinlock.h> | ||
| 23 | #include <linux/of.h> | ||
| 22 | 24 | ||
| 23 | #include <asm/udbg.h> | 25 | #include <asm/udbg.h> |
| 24 | #include <asm/io.h> | 26 | #include <asm/io.h> |
| @@ -28,6 +30,10 @@ | |||
| 28 | 30 | ||
| 29 | #include <mm/mmu_decl.h> | 31 | #include <mm/mmu_decl.h> |
| 30 | 32 | ||
| 33 | #if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO) | ||
| 34 | #include <linux/of_gpio.h> | ||
| 35 | #endif | ||
| 36 | |||
| 31 | #ifdef CONFIG_PPC_EARLY_DEBUG_CPM | 37 | #ifdef CONFIG_PPC_EARLY_DEBUG_CPM |
| 32 | static u32 __iomem *cpm_udbg_txdesc = | 38 | static u32 __iomem *cpm_udbg_txdesc = |
| 33 | (u32 __iomem __force *)CONFIG_PPC_EARLY_DEBUG_CPM_ADDR; | 39 | (u32 __iomem __force *)CONFIG_PPC_EARLY_DEBUG_CPM_ADDR; |
| @@ -207,3 +213,120 @@ dma_addr_t cpm_muram_dma(void __iomem *addr) | |||
| 207 | return muram_pbase + ((u8 __iomem *)addr - muram_vbase); | 213 | return muram_pbase + ((u8 __iomem *)addr - muram_vbase); |
| 208 | } | 214 | } |
| 209 | EXPORT_SYMBOL(cpm_muram_dma); | 215 | EXPORT_SYMBOL(cpm_muram_dma); |
| 216 | |||
| 217 | #if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO) | ||
| 218 | |||
| 219 | struct cpm2_ioports { | ||
| 220 | u32 dir, par, sor, odr, dat; | ||
| 221 | u32 res[3]; | ||
| 222 | }; | ||
| 223 | |||
| 224 | struct cpm2_gpio32_chip { | ||
| 225 | struct of_mm_gpio_chip mm_gc; | ||
| 226 | spinlock_t lock; | ||
| 227 | |||
| 228 | /* shadowed data register to clear/set bits safely */ | ||
| 229 | u32 cpdata; | ||
| 230 | }; | ||
| 231 | |||
| 232 | static inline struct cpm2_gpio32_chip * | ||
| 233 | to_cpm2_gpio32_chip(struct of_mm_gpio_chip *mm_gc) | ||
| 234 | { | ||
| 235 | return container_of(mm_gc, struct cpm2_gpio32_chip, mm_gc); | ||
| 236 | } | ||
| 237 | |||
| 238 | static void cpm2_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc) | ||
| 239 | { | ||
| 240 | struct cpm2_gpio32_chip *cpm2_gc = to_cpm2_gpio32_chip(mm_gc); | ||
| 241 | struct cpm2_ioports __iomem *iop = mm_gc->regs; | ||
| 242 | |||
| 243 | cpm2_gc->cpdata = in_be32(&iop->dat); | ||
| 244 | } | ||
| 245 | |||
| 246 | static int cpm2_gpio32_get(struct gpio_chip *gc, unsigned int gpio) | ||
| 247 | { | ||
| 248 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
| 249 | struct cpm2_ioports __iomem *iop = mm_gc->regs; | ||
| 250 | u32 pin_mask; | ||
| 251 | |||
| 252 | pin_mask = 1 << (31 - gpio); | ||
| 253 | |||
| 254 | return !!(in_be32(&iop->dat) & pin_mask); | ||
| 255 | } | ||
| 256 | |||
| 257 | static void cpm2_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value) | ||
| 258 | { | ||
| 259 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
| 260 | struct cpm2_gpio32_chip *cpm2_gc = to_cpm2_gpio32_chip(mm_gc); | ||
| 261 | struct cpm2_ioports __iomem *iop = mm_gc->regs; | ||
| 262 | unsigned long flags; | ||
| 263 | u32 pin_mask = 1 << (31 - gpio); | ||
| 264 | |||
| 265 | spin_lock_irqsave(&cpm2_gc->lock, flags); | ||
| 266 | |||
| 267 | if (value) | ||
| 268 | cpm2_gc->cpdata |= pin_mask; | ||
| 269 | else | ||
| 270 | cpm2_gc->cpdata &= ~pin_mask; | ||
| 271 | |||
| 272 | out_be32(&iop->dat, cpm2_gc->cpdata); | ||
| 273 | |||
| 274 | spin_unlock_irqrestore(&cpm2_gc->lock, flags); | ||
| 275 | } | ||
| 276 | |||
| 277 | static int cpm2_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | ||
| 278 | { | ||
| 279 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
| 280 | struct cpm2_ioports __iomem *iop = mm_gc->regs; | ||
| 281 | u32 pin_mask; | ||
| 282 | |||
| 283 | pin_mask = 1 << (31 - gpio); | ||
| 284 | |||
| 285 | setbits32(&iop->dir, pin_mask); | ||
| 286 | |||
| 287 | cpm2_gpio32_set(gc, gpio, val); | ||
| 288 | |||
| 289 | return 0; | ||
| 290 | } | ||
| 291 | |||
| 292 | static int cpm2_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio) | ||
| 293 | { | ||
| 294 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
| 295 | struct cpm2_ioports __iomem *iop = mm_gc->regs; | ||
| 296 | u32 pin_mask; | ||
| 297 | |||
| 298 | pin_mask = 1 << (31 - gpio); | ||
| 299 | |||
| 300 | clrbits32(&iop->dir, pin_mask); | ||
| 301 | |||
| 302 | return 0; | ||
| 303 | } | ||
| 304 | |||
| 305 | int cpm2_gpiochip_add32(struct device_node *np) | ||
| 306 | { | ||
| 307 | struct cpm2_gpio32_chip *cpm2_gc; | ||
| 308 | struct of_mm_gpio_chip *mm_gc; | ||
| 309 | struct of_gpio_chip *of_gc; | ||
| 310 | struct gpio_chip *gc; | ||
| 311 | |||
| 312 | cpm2_gc = kzalloc(sizeof(*cpm2_gc), GFP_KERNEL); | ||
| 313 | if (!cpm2_gc) | ||
| 314 | return -ENOMEM; | ||
| 315 | |||
| 316 | spin_lock_init(&cpm2_gc->lock); | ||
| 317 | |||
| 318 | mm_gc = &cpm2_gc->mm_gc; | ||
| 319 | of_gc = &mm_gc->of_gc; | ||
| 320 | gc = &of_gc->gc; | ||
| 321 | |||
| 322 | mm_gc->save_regs = cpm2_gpio32_save_regs; | ||
| 323 | of_gc->gpio_cells = 2; | ||
| 324 | gc->ngpio = 32; | ||
| 325 | gc->direction_input = cpm2_gpio32_dir_in; | ||
| 326 | gc->direction_output = cpm2_gpio32_dir_out; | ||
| 327 | gc->get = cpm2_gpio32_get; | ||
| 328 | gc->set = cpm2_gpio32_set; | ||
| 329 | |||
| 330 | return of_mm_gpiochip_add(np, mm_gc); | ||
| 331 | } | ||
| 332 | #endif /* CONFIG_CPM2 || CONFIG_8xx_GPIO */ | ||
