linux/arch/powerpc/sysdev/cpm_common.c
<<
>>
Prefs
   1/*
   2 * Common CPM code
   3 *
   4 * Author: Scott Wood <scottwood@freescale.com>
   5 *
   6 * Copyright 2007-2008,2010 Freescale Semiconductor, Inc.
   7 *
   8 * Some parts derived from commproc.c/cpm2_common.c, which is:
   9 * Copyright (c) 1997 Dan error_act (dmalek@jlc.net)
  10 * Copyright (c) 1999-2001 Dan Malek <dan@embeddedalley.com>
  11 * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
  12 * 2006 (c) MontaVista Software, Inc.
  13 * Vitaly Bordug <vbordug@ru.mvista.com>
  14 *
  15 * This program is free software; you can redistribute it and/or modify
  16 * it under the terms of version 2 of the GNU General Public License as
  17 * published by the Free Software Foundation.
  18 */
  19
  20#include <linux/init.h>
  21#include <linux/of_device.h>
  22#include <linux/spinlock.h>
  23#include <linux/export.h>
  24#include <linux/of.h>
  25#include <linux/of_address.h>
  26#include <linux/slab.h>
  27
  28#include <asm/udbg.h>
  29#include <asm/io.h>
  30#include <asm/cpm.h>
  31#include <asm/fixmap.h>
  32#include <soc/fsl/qe/qe.h>
  33
  34#include <mm/mmu_decl.h>
  35
  36#if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO)
  37#include <linux/of_gpio.h>
  38#endif
  39
  40static int __init cpm_init(void)
  41{
  42        struct device_node *np;
  43
  44        np = of_find_compatible_node(NULL, NULL, "fsl,cpm1");
  45        if (!np)
  46                np = of_find_compatible_node(NULL, NULL, "fsl,cpm2");
  47        if (!np)
  48                return -ENODEV;
  49        cpm_muram_init();
  50        of_node_put(np);
  51        return 0;
  52}
  53subsys_initcall(cpm_init);
  54
  55#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
  56static u32 __iomem *cpm_udbg_txdesc;
  57static u8 __iomem *cpm_udbg_txbuf;
  58
  59static void udbg_putc_cpm(char c)
  60{
  61        if (c == '\n')
  62                udbg_putc_cpm('\r');
  63
  64        while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000)
  65                ;
  66
  67        out_8(cpm_udbg_txbuf, c);
  68        out_be32(&cpm_udbg_txdesc[0], 0xa0000001);
  69}
  70
  71void __init udbg_init_cpm(void)
  72{
  73#ifdef CONFIG_PPC_8xx
  74        cpm_udbg_txdesc = (u32 __iomem __force *)
  75                          (CONFIG_PPC_EARLY_DEBUG_CPM_ADDR - PHYS_IMMR_BASE +
  76                           VIRT_IMMR_BASE);
  77        cpm_udbg_txbuf = (u8 __iomem __force *)
  78                         (in_be32(&cpm_udbg_txdesc[1]) - PHYS_IMMR_BASE +
  79                          VIRT_IMMR_BASE);
  80#else
  81        cpm_udbg_txdesc = (u32 __iomem __force *)
  82                          CONFIG_PPC_EARLY_DEBUG_CPM_ADDR;
  83        cpm_udbg_txbuf = (u8 __iomem __force *)in_be32(&cpm_udbg_txdesc[1]);
  84#endif
  85
  86        if (cpm_udbg_txdesc) {
  87#ifdef CONFIG_CPM2
  88                setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG);
  89#endif
  90                udbg_putc = udbg_putc_cpm;
  91        }
  92}
  93#endif
  94
  95#if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO)
  96
  97struct cpm2_ioports {
  98        u32 dir, par, sor, odr, dat;
  99        u32 res[3];
 100};
 101
 102struct cpm2_gpio32_chip {
 103        struct of_mm_gpio_chip mm_gc;
 104        spinlock_t lock;
 105
 106        /* shadowed data register to clear/set bits safely */
 107        u32 cpdata;
 108};
 109
 110static void cpm2_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc)
 111{
 112        struct cpm2_gpio32_chip *cpm2_gc =
 113                container_of(mm_gc, struct cpm2_gpio32_chip, mm_gc);
 114        struct cpm2_ioports __iomem *iop = mm_gc->regs;
 115
 116        cpm2_gc->cpdata = in_be32(&iop->dat);
 117}
 118
 119static int cpm2_gpio32_get(struct gpio_chip *gc, unsigned int gpio)
 120{
 121        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 122        struct cpm2_ioports __iomem *iop = mm_gc->regs;
 123        u32 pin_mask;
 124
 125        pin_mask = 1 << (31 - gpio);
 126
 127        return !!(in_be32(&iop->dat) & pin_mask);
 128}
 129
 130static void __cpm2_gpio32_set(struct of_mm_gpio_chip *mm_gc, u32 pin_mask,
 131        int value)
 132{
 133        struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(&mm_gc->gc);
 134        struct cpm2_ioports __iomem *iop = mm_gc->regs;
 135
 136        if (value)
 137                cpm2_gc->cpdata |= pin_mask;
 138        else
 139                cpm2_gc->cpdata &= ~pin_mask;
 140
 141        out_be32(&iop->dat, cpm2_gc->cpdata);
 142}
 143
 144static void cpm2_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
 145{
 146        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 147        struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
 148        unsigned long flags;
 149        u32 pin_mask = 1 << (31 - gpio);
 150
 151        spin_lock_irqsave(&cpm2_gc->lock, flags);
 152
 153        __cpm2_gpio32_set(mm_gc, pin_mask, value);
 154
 155        spin_unlock_irqrestore(&cpm2_gc->lock, flags);
 156}
 157
 158static int cpm2_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 159{
 160        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 161        struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
 162        struct cpm2_ioports __iomem *iop = mm_gc->regs;
 163        unsigned long flags;
 164        u32 pin_mask = 1 << (31 - gpio);
 165
 166        spin_lock_irqsave(&cpm2_gc->lock, flags);
 167
 168        setbits32(&iop->dir, pin_mask);
 169        __cpm2_gpio32_set(mm_gc, pin_mask, val);
 170
 171        spin_unlock_irqrestore(&cpm2_gc->lock, flags);
 172
 173        return 0;
 174}
 175
 176static int cpm2_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
 177{
 178        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 179        struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
 180        struct cpm2_ioports __iomem *iop = mm_gc->regs;
 181        unsigned long flags;
 182        u32 pin_mask = 1 << (31 - gpio);
 183
 184        spin_lock_irqsave(&cpm2_gc->lock, flags);
 185
 186        clrbits32(&iop->dir, pin_mask);
 187
 188        spin_unlock_irqrestore(&cpm2_gc->lock, flags);
 189
 190        return 0;
 191}
 192
 193int cpm2_gpiochip_add32(struct device *dev)
 194{
 195        struct device_node *np = dev->of_node;
 196        struct cpm2_gpio32_chip *cpm2_gc;
 197        struct of_mm_gpio_chip *mm_gc;
 198        struct gpio_chip *gc;
 199
 200        cpm2_gc = kzalloc(sizeof(*cpm2_gc), GFP_KERNEL);
 201        if (!cpm2_gc)
 202                return -ENOMEM;
 203
 204        spin_lock_init(&cpm2_gc->lock);
 205
 206        mm_gc = &cpm2_gc->mm_gc;
 207        gc = &mm_gc->gc;
 208
 209        mm_gc->save_regs = cpm2_gpio32_save_regs;
 210        gc->ngpio = 32;
 211        gc->direction_input = cpm2_gpio32_dir_in;
 212        gc->direction_output = cpm2_gpio32_dir_out;
 213        gc->get = cpm2_gpio32_get;
 214        gc->set = cpm2_gpio32_set;
 215        gc->parent = dev;
 216        gc->owner = THIS_MODULE;
 217
 218        return of_mm_gpiochip_add_data(np, mm_gc, cpm2_gc);
 219}
 220#endif /* CONFIG_CPM2 || CONFIG_8xx_GPIO */
 221