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.c (4507B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * PPC4xx gpio driver
      4 *
      5 * Copyright (c) 2008 Harris Corporation
      6 * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
      7 * Copyright (c) MontaVista Software, Inc. 2008.
      8 *
      9 * Author: Steve Falco <sfalco@harris.com>
     10 */
     11
     12#include <linux/kernel.h>
     13#include <linux/init.h>
     14#include <linux/spinlock.h>
     15#include <linux/io.h>
     16#include <linux/of.h>
     17#include <linux/of_gpio.h>
     18#include <linux/gpio/driver.h>
     19#include <linux/types.h>
     20#include <linux/slab.h>
     21
     22#define GPIO_MASK(gpio)		(0x80000000 >> (gpio))
     23#define GPIO_MASK2(gpio)	(0xc0000000 >> ((gpio) * 2))
     24
     25/* Physical GPIO register layout */
     26struct ppc4xx_gpio {
     27	__be32 or;
     28	__be32 tcr;
     29	__be32 osrl;
     30	__be32 osrh;
     31	__be32 tsrl;
     32	__be32 tsrh;
     33	__be32 odr;
     34	__be32 ir;
     35	__be32 rr1;
     36	__be32 rr2;
     37	__be32 rr3;
     38	__be32 reserved1;
     39	__be32 isr1l;
     40	__be32 isr1h;
     41	__be32 isr2l;
     42	__be32 isr2h;
     43	__be32 isr3l;
     44	__be32 isr3h;
     45};
     46
     47struct ppc4xx_gpio_chip {
     48	struct of_mm_gpio_chip mm_gc;
     49	spinlock_t lock;
     50};
     51
     52/*
     53 * GPIO LIB API implementation for GPIOs
     54 *
     55 * There are a maximum of 32 gpios in each gpio controller.
     56 */
     57
     58static int ppc4xx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
     59{
     60	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
     61	struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
     62
     63	return !!(in_be32(&regs->ir) & GPIO_MASK(gpio));
     64}
     65
     66static inline void
     67__ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
     68{
     69	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
     70	struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
     71
     72	if (val)
     73		setbits32(&regs->or, GPIO_MASK(gpio));
     74	else
     75		clrbits32(&regs->or, GPIO_MASK(gpio));
     76}
     77
     78static void
     79ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
     80{
     81	struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
     82	unsigned long flags;
     83
     84	spin_lock_irqsave(&chip->lock, flags);
     85
     86	__ppc4xx_gpio_set(gc, gpio, val);
     87
     88	spin_unlock_irqrestore(&chip->lock, flags);
     89
     90	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
     91}
     92
     93static int ppc4xx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
     94{
     95	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
     96	struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
     97	struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
     98	unsigned long flags;
     99
    100	spin_lock_irqsave(&chip->lock, flags);
    101
    102	/* Disable open-drain function */
    103	clrbits32(&regs->odr, GPIO_MASK(gpio));
    104
    105	/* Float the pin */
    106	clrbits32(&regs->tcr, GPIO_MASK(gpio));
    107
    108	/* Bits 0-15 use TSRL/OSRL, bits 16-31 use TSRH/OSRH */
    109	if (gpio < 16) {
    110		clrbits32(&regs->osrl, GPIO_MASK2(gpio));
    111		clrbits32(&regs->tsrl, GPIO_MASK2(gpio));
    112	} else {
    113		clrbits32(&regs->osrh, GPIO_MASK2(gpio));
    114		clrbits32(&regs->tsrh, GPIO_MASK2(gpio));
    115	}
    116
    117	spin_unlock_irqrestore(&chip->lock, flags);
    118
    119	return 0;
    120}
    121
    122static int
    123ppc4xx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
    124{
    125	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
    126	struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
    127	struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
    128	unsigned long flags;
    129
    130	spin_lock_irqsave(&chip->lock, flags);
    131
    132	/* First set initial value */
    133	__ppc4xx_gpio_set(gc, gpio, val);
    134
    135	/* Disable open-drain function */
    136	clrbits32(&regs->odr, GPIO_MASK(gpio));
    137
    138	/* Drive the pin */
    139	setbits32(&regs->tcr, GPIO_MASK(gpio));
    140
    141	/* Bits 0-15 use TSRL, bits 16-31 use TSRH */
    142	if (gpio < 16) {
    143		clrbits32(&regs->osrl, GPIO_MASK2(gpio));
    144		clrbits32(&regs->tsrl, GPIO_MASK2(gpio));
    145	} else {
    146		clrbits32(&regs->osrh, GPIO_MASK2(gpio));
    147		clrbits32(&regs->tsrh, GPIO_MASK2(gpio));
    148	}
    149
    150	spin_unlock_irqrestore(&chip->lock, flags);
    151
    152	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
    153
    154	return 0;
    155}
    156
    157static int __init ppc4xx_add_gpiochips(void)
    158{
    159	struct device_node *np;
    160
    161	for_each_compatible_node(np, NULL, "ibm,ppc4xx-gpio") {
    162		int ret;
    163		struct ppc4xx_gpio_chip *ppc4xx_gc;
    164		struct of_mm_gpio_chip *mm_gc;
    165		struct gpio_chip *gc;
    166
    167		ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL);
    168		if (!ppc4xx_gc) {
    169			ret = -ENOMEM;
    170			goto err;
    171		}
    172
    173		spin_lock_init(&ppc4xx_gc->lock);
    174
    175		mm_gc = &ppc4xx_gc->mm_gc;
    176		gc = &mm_gc->gc;
    177
    178		gc->ngpio = 32;
    179		gc->direction_input = ppc4xx_gpio_dir_in;
    180		gc->direction_output = ppc4xx_gpio_dir_out;
    181		gc->get = ppc4xx_gpio_get;
    182		gc->set = ppc4xx_gpio_set;
    183
    184		ret = of_mm_gpiochip_add_data(np, mm_gc, ppc4xx_gc);
    185		if (ret)
    186			goto err;
    187		continue;
    188err:
    189		pr_err("%pOF: registration failed with status %d\n", np, ret);
    190		kfree(ppc4xx_gc);
    191		/* try others anyway */
    192	}
    193	return 0;
    194}
    195arch_initcall(ppc4xx_add_gpiochips);