linux/arch/mips/kernel/gpio_txx9.c
<<
>>
Prefs
   1/*
   2 * A gpio chip driver for TXx9 SoCs
   3 *
   4 * Copyright (C) 2008 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10
  11#include <linux/init.h>
  12#include <linux/spinlock.h>
  13#include <linux/gpio.h>
  14#include <linux/errno.h>
  15#include <linux/io.h>
  16#include <asm/txx9pio.h>
  17
  18static DEFINE_SPINLOCK(txx9_gpio_lock);
  19
  20static struct txx9_pio_reg __iomem *txx9_pioptr;
  21
  22static int txx9_gpio_get(struct gpio_chip *chip, unsigned int offset)
  23{
  24        return __raw_readl(&txx9_pioptr->din) & (1 << offset);
  25}
  26
  27static void txx9_gpio_set_raw(unsigned int offset, int value)
  28{
  29        u32 val;
  30        val = __raw_readl(&txx9_pioptr->dout);
  31        if (value)
  32                val |= 1 << offset;
  33        else
  34                val &= ~(1 << offset);
  35        __raw_writel(val, &txx9_pioptr->dout);
  36}
  37
  38static void txx9_gpio_set(struct gpio_chip *chip, unsigned int offset,
  39                          int value)
  40{
  41        unsigned long flags;
  42        spin_lock_irqsave(&txx9_gpio_lock, flags);
  43        txx9_gpio_set_raw(offset, value);
  44        mmiowb();
  45        spin_unlock_irqrestore(&txx9_gpio_lock, flags);
  46}
  47
  48static int txx9_gpio_dir_in(struct gpio_chip *chip, unsigned int offset)
  49{
  50        unsigned long flags;
  51        spin_lock_irqsave(&txx9_gpio_lock, flags);
  52        __raw_writel(__raw_readl(&txx9_pioptr->dir) & ~(1 << offset),
  53                     &txx9_pioptr->dir);
  54        mmiowb();
  55        spin_unlock_irqrestore(&txx9_gpio_lock, flags);
  56        return 0;
  57}
  58
  59static int txx9_gpio_dir_out(struct gpio_chip *chip, unsigned int offset,
  60                             int value)
  61{
  62        unsigned long flags;
  63        spin_lock_irqsave(&txx9_gpio_lock, flags);
  64        txx9_gpio_set_raw(offset, value);
  65        __raw_writel(__raw_readl(&txx9_pioptr->dir) | (1 << offset),
  66                     &txx9_pioptr->dir);
  67        mmiowb();
  68        spin_unlock_irqrestore(&txx9_gpio_lock, flags);
  69        return 0;
  70}
  71
  72static struct gpio_chip txx9_gpio_chip = {
  73        .get = txx9_gpio_get,
  74        .set = txx9_gpio_set,
  75        .direction_input = txx9_gpio_dir_in,
  76        .direction_output = txx9_gpio_dir_out,
  77        .label = "TXx9",
  78};
  79
  80int __init txx9_gpio_init(unsigned long baseaddr,
  81                          unsigned int base, unsigned int num)
  82{
  83        txx9_pioptr = ioremap(baseaddr, sizeof(struct txx9_pio_reg));
  84        if (!txx9_pioptr)
  85                return -ENODEV;
  86        txx9_gpio_chip.base = base;
  87        txx9_gpio_chip.ngpio = num;
  88        return gpiochip_add(&txx9_gpio_chip);
  89}
  90