cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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}