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