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-xgs-iproc.c (8675B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2017 Broadcom
      4 */
      5
      6#include <linux/gpio/driver.h>
      7#include <linux/init.h>
      8#include <linux/interrupt.h>
      9#include <linux/io.h>
     10#include <linux/irq.h>
     11#include <linux/kernel.h>
     12#include <linux/module.h>
     13#include <linux/platform_device.h>
     14#include <linux/spinlock.h>
     15
     16#define IPROC_CCA_INT_F_GPIOINT		BIT(0)
     17#define IPROC_CCA_INT_STS		0x20
     18#define IPROC_CCA_INT_MASK		0x24
     19
     20#define IPROC_GPIO_CCA_DIN		0x0
     21#define IPROC_GPIO_CCA_DOUT		0x4
     22#define IPROC_GPIO_CCA_OUT_EN		0x8
     23#define IPROC_GPIO_CCA_INT_LEVEL	0x10
     24#define IPROC_GPIO_CCA_INT_LEVEL_MASK	0x14
     25#define IPROC_GPIO_CCA_INT_EVENT	0x18
     26#define IPROC_GPIO_CCA_INT_EVENT_MASK	0x1C
     27#define IPROC_GPIO_CCA_INT_EDGE		0x24
     28
     29struct iproc_gpio_chip {
     30	struct irq_chip irqchip;
     31	struct gpio_chip gc;
     32	spinlock_t lock;
     33	struct device *dev;
     34	void __iomem *base;
     35	void __iomem *intr;
     36};
     37
     38static inline struct iproc_gpio_chip *
     39to_iproc_gpio(struct gpio_chip *gc)
     40{
     41	return container_of(gc, struct iproc_gpio_chip, gc);
     42}
     43
     44static void iproc_gpio_irq_ack(struct irq_data *d)
     45{
     46	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
     47	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
     48	int pin = d->hwirq;
     49	unsigned long flags;
     50	u32 irq = d->irq;
     51	u32 irq_type, event_status = 0;
     52
     53	spin_lock_irqsave(&chip->lock, flags);
     54	irq_type = irq_get_trigger_type(irq);
     55	if (irq_type & IRQ_TYPE_EDGE_BOTH) {
     56		event_status |= BIT(pin);
     57		writel_relaxed(event_status,
     58			       chip->base + IPROC_GPIO_CCA_INT_EVENT);
     59	}
     60	spin_unlock_irqrestore(&chip->lock, flags);
     61}
     62
     63static void iproc_gpio_irq_unmask(struct irq_data *d)
     64{
     65	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
     66	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
     67	int pin = d->hwirq;
     68	unsigned long flags;
     69	u32 irq = d->irq;
     70	u32 int_mask, irq_type, event_mask;
     71
     72	spin_lock_irqsave(&chip->lock, flags);
     73	irq_type = irq_get_trigger_type(irq);
     74	event_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
     75	int_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
     76
     77	if (irq_type & IRQ_TYPE_EDGE_BOTH) {
     78		event_mask |= 1 << pin;
     79		writel_relaxed(event_mask,
     80			       chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
     81	} else {
     82		int_mask |= 1 << pin;
     83		writel_relaxed(int_mask,
     84			       chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
     85	}
     86	spin_unlock_irqrestore(&chip->lock, flags);
     87}
     88
     89static void iproc_gpio_irq_mask(struct irq_data *d)
     90{
     91	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
     92	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
     93	int pin = d->hwirq;
     94	unsigned long flags;
     95	u32 irq = d->irq;
     96	u32 irq_type, int_mask, event_mask;
     97
     98	spin_lock_irqsave(&chip->lock, flags);
     99	irq_type = irq_get_trigger_type(irq);
    100	event_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
    101	int_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
    102
    103	if (irq_type & IRQ_TYPE_EDGE_BOTH) {
    104		event_mask &= ~BIT(pin);
    105		writel_relaxed(event_mask,
    106			       chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
    107	} else {
    108		int_mask &= ~BIT(pin);
    109		writel_relaxed(int_mask,
    110			       chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
    111	}
    112	spin_unlock_irqrestore(&chip->lock, flags);
    113}
    114
    115static int iproc_gpio_irq_set_type(struct irq_data *d, u32 type)
    116{
    117	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
    118	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
    119	int pin = d->hwirq;
    120	unsigned long flags;
    121	u32 irq = d->irq;
    122	u32 event_pol, int_pol;
    123	int ret = 0;
    124
    125	spin_lock_irqsave(&chip->lock, flags);
    126	switch (type & IRQ_TYPE_SENSE_MASK) {
    127	case IRQ_TYPE_EDGE_RISING:
    128		event_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EDGE);
    129		event_pol &= ~BIT(pin);
    130		writel_relaxed(event_pol, chip->base + IPROC_GPIO_CCA_INT_EDGE);
    131		break;
    132	case IRQ_TYPE_EDGE_FALLING:
    133		event_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EDGE);
    134		event_pol |= BIT(pin);
    135		writel_relaxed(event_pol, chip->base + IPROC_GPIO_CCA_INT_EDGE);
    136		break;
    137	case IRQ_TYPE_LEVEL_HIGH:
    138		int_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);
    139		int_pol &= ~BIT(pin);
    140		writel_relaxed(int_pol, chip->base + IPROC_GPIO_CCA_INT_LEVEL);
    141		break;
    142	case IRQ_TYPE_LEVEL_LOW:
    143		int_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);
    144		int_pol |= BIT(pin);
    145		writel_relaxed(int_pol, chip->base + IPROC_GPIO_CCA_INT_LEVEL);
    146		break;
    147	default:
    148		/* should not come here */
    149		ret = -EINVAL;
    150		goto out_unlock;
    151	}
    152
    153	if (type & IRQ_TYPE_LEVEL_MASK)
    154		irq_set_handler_locked(irq_get_irq_data(irq), handle_level_irq);
    155	else if (type & IRQ_TYPE_EDGE_BOTH)
    156		irq_set_handler_locked(irq_get_irq_data(irq), handle_edge_irq);
    157
    158out_unlock:
    159	spin_unlock_irqrestore(&chip->lock, flags);
    160
    161	return ret;
    162}
    163
    164static irqreturn_t iproc_gpio_irq_handler(int irq, void *data)
    165{
    166	struct gpio_chip *gc = (struct gpio_chip *)data;
    167	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
    168	int bit;
    169	unsigned long int_bits = 0;
    170	u32 int_status;
    171
    172	/* go through the entire GPIOs and handle all interrupts */
    173	int_status = readl_relaxed(chip->intr + IPROC_CCA_INT_STS);
    174	if (int_status & IPROC_CCA_INT_F_GPIOINT) {
    175		u32 event, level;
    176
    177		/* Get level and edge interrupts */
    178		event =
    179		    readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
    180		event &= readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT);
    181		level = readl_relaxed(chip->base + IPROC_GPIO_CCA_DIN);
    182		level ^= readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);
    183		level &=
    184		    readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
    185		int_bits = level | event;
    186
    187		for_each_set_bit(bit, &int_bits, gc->ngpio)
    188			generic_handle_domain_irq(gc->irq.domain, bit);
    189	}
    190
    191	return int_bits ? IRQ_HANDLED : IRQ_NONE;
    192}
    193
    194static int iproc_gpio_probe(struct platform_device *pdev)
    195{
    196	struct device *dev = &pdev->dev;
    197	struct device_node *dn = pdev->dev.of_node;
    198	struct iproc_gpio_chip *chip;
    199	u32 num_gpios;
    200	int irq, ret;
    201
    202	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
    203	if (!chip)
    204		return -ENOMEM;
    205
    206	chip->dev = dev;
    207	platform_set_drvdata(pdev, chip);
    208	spin_lock_init(&chip->lock);
    209
    210	chip->base = devm_platform_ioremap_resource(pdev, 0);
    211	if (IS_ERR(chip->base))
    212		return PTR_ERR(chip->base);
    213
    214	ret = bgpio_init(&chip->gc, dev, 4,
    215			 chip->base + IPROC_GPIO_CCA_DIN,
    216			 chip->base + IPROC_GPIO_CCA_DOUT,
    217			 NULL,
    218			 chip->base + IPROC_GPIO_CCA_OUT_EN,
    219			 NULL,
    220			 0);
    221	if (ret) {
    222		dev_err(dev, "unable to init GPIO chip\n");
    223		return ret;
    224	}
    225
    226	chip->gc.label = dev_name(dev);
    227	if (!of_property_read_u32(dn, "ngpios", &num_gpios))
    228		chip->gc.ngpio = num_gpios;
    229
    230	irq = platform_get_irq(pdev, 0);
    231	if (irq > 0) {
    232		struct gpio_irq_chip *girq;
    233		struct irq_chip *irqc;
    234		u32 val;
    235
    236		irqc = &chip->irqchip;
    237		irqc->name = dev_name(dev);
    238		irqc->irq_ack = iproc_gpio_irq_ack;
    239		irqc->irq_mask = iproc_gpio_irq_mask;
    240		irqc->irq_unmask = iproc_gpio_irq_unmask;
    241		irqc->irq_set_type = iproc_gpio_irq_set_type;
    242
    243		chip->intr = devm_platform_ioremap_resource(pdev, 1);
    244		if (IS_ERR(chip->intr))
    245			return PTR_ERR(chip->intr);
    246
    247		/* Enable GPIO interrupts for CCA GPIO */
    248		val = readl_relaxed(chip->intr + IPROC_CCA_INT_MASK);
    249		val |= IPROC_CCA_INT_F_GPIOINT;
    250		writel_relaxed(val, chip->intr + IPROC_CCA_INT_MASK);
    251
    252		/*
    253		 * Directly request the irq here instead of passing
    254		 * a flow-handler because the irq is shared.
    255		 */
    256		ret = devm_request_irq(dev, irq, iproc_gpio_irq_handler,
    257				       IRQF_SHARED, chip->gc.label, &chip->gc);
    258		if (ret) {
    259			dev_err(dev, "Fail to request IRQ%d: %d\n", irq, ret);
    260			return ret;
    261		}
    262
    263		girq = &chip->gc.irq;
    264		girq->chip = irqc;
    265		/* This will let us handle the parent IRQ in the driver */
    266		girq->parent_handler = NULL;
    267		girq->num_parents = 0;
    268		girq->parents = NULL;
    269		girq->default_type = IRQ_TYPE_NONE;
    270		girq->handler = handle_simple_irq;
    271	}
    272
    273	ret = devm_gpiochip_add_data(dev, &chip->gc, chip);
    274	if (ret) {
    275		dev_err(dev, "unable to add GPIO chip\n");
    276		return ret;
    277	}
    278
    279	return 0;
    280}
    281
    282static int iproc_gpio_remove(struct platform_device *pdev)
    283{
    284	struct iproc_gpio_chip *chip;
    285
    286	chip = platform_get_drvdata(pdev);
    287	if (!chip)
    288		return -ENODEV;
    289
    290	if (chip->intr) {
    291		u32 val;
    292
    293		val = readl_relaxed(chip->intr + IPROC_CCA_INT_MASK);
    294		val &= ~IPROC_CCA_INT_F_GPIOINT;
    295		writel_relaxed(val, chip->intr + IPROC_CCA_INT_MASK);
    296	}
    297
    298	return 0;
    299}
    300
    301static const struct of_device_id bcm_iproc_gpio_of_match[] = {
    302	{ .compatible = "brcm,iproc-gpio-cca" },
    303	{}
    304};
    305MODULE_DEVICE_TABLE(of, bcm_iproc_gpio_of_match);
    306
    307static struct platform_driver bcm_iproc_gpio_driver = {
    308	.driver = {
    309		.name = "iproc-xgs-gpio",
    310		.of_match_table = bcm_iproc_gpio_of_match,
    311	},
    312	.probe = iproc_gpio_probe,
    313	.remove = iproc_gpio_remove,
    314};
    315
    316module_platform_driver(bcm_iproc_gpio_driver);
    317
    318MODULE_DESCRIPTION("XGS IPROC GPIO driver");
    319MODULE_LICENSE("GPL v2");