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


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  Atheros AR71XX/AR724X/AR913X GPIO API support
      4 *
      5 *  Copyright (C) 2015 Alban Bedel <albeu@free.fr>
      6 *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
      7 *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
      8 *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
      9 */
     10
     11#include <linux/gpio/driver.h>
     12#include <linux/platform_data/gpio-ath79.h>
     13#include <linux/of_device.h>
     14#include <linux/interrupt.h>
     15#include <linux/module.h>
     16#include <linux/irq.h>
     17
     18#define AR71XX_GPIO_REG_OE		0x00
     19#define AR71XX_GPIO_REG_IN		0x04
     20#define AR71XX_GPIO_REG_SET		0x0c
     21#define AR71XX_GPIO_REG_CLEAR		0x10
     22
     23#define AR71XX_GPIO_REG_INT_ENABLE	0x14
     24#define AR71XX_GPIO_REG_INT_TYPE	0x18
     25#define AR71XX_GPIO_REG_INT_POLARITY	0x1c
     26#define AR71XX_GPIO_REG_INT_PENDING	0x20
     27#define AR71XX_GPIO_REG_INT_MASK	0x24
     28
     29struct ath79_gpio_ctrl {
     30	struct gpio_chip gc;
     31	void __iomem *base;
     32	raw_spinlock_t lock;
     33	unsigned long both_edges;
     34};
     35
     36static struct ath79_gpio_ctrl *irq_data_to_ath79_gpio(struct irq_data *data)
     37{
     38	struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
     39
     40	return container_of(gc, struct ath79_gpio_ctrl, gc);
     41}
     42
     43static u32 ath79_gpio_read(struct ath79_gpio_ctrl *ctrl, unsigned reg)
     44{
     45	return readl(ctrl->base + reg);
     46}
     47
     48static void ath79_gpio_write(struct ath79_gpio_ctrl *ctrl,
     49			unsigned reg, u32 val)
     50{
     51	writel(val, ctrl->base + reg);
     52}
     53
     54static bool ath79_gpio_update_bits(
     55	struct ath79_gpio_ctrl *ctrl, unsigned reg, u32 mask, u32 bits)
     56{
     57	u32 old_val, new_val;
     58
     59	old_val = ath79_gpio_read(ctrl, reg);
     60	new_val = (old_val & ~mask) | (bits & mask);
     61
     62	if (new_val != old_val)
     63		ath79_gpio_write(ctrl, reg, new_val);
     64
     65	return new_val != old_val;
     66}
     67
     68static void ath79_gpio_irq_unmask(struct irq_data *data)
     69{
     70	struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
     71	u32 mask = BIT(irqd_to_hwirq(data));
     72	unsigned long flags;
     73
     74	raw_spin_lock_irqsave(&ctrl->lock, flags);
     75	ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask);
     76	raw_spin_unlock_irqrestore(&ctrl->lock, flags);
     77}
     78
     79static void ath79_gpio_irq_mask(struct irq_data *data)
     80{
     81	struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
     82	u32 mask = BIT(irqd_to_hwirq(data));
     83	unsigned long flags;
     84
     85	raw_spin_lock_irqsave(&ctrl->lock, flags);
     86	ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0);
     87	raw_spin_unlock_irqrestore(&ctrl->lock, flags);
     88}
     89
     90static void ath79_gpio_irq_enable(struct irq_data *data)
     91{
     92	struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
     93	u32 mask = BIT(irqd_to_hwirq(data));
     94	unsigned long flags;
     95
     96	raw_spin_lock_irqsave(&ctrl->lock, flags);
     97	ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask);
     98	ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask);
     99	raw_spin_unlock_irqrestore(&ctrl->lock, flags);
    100}
    101
    102static void ath79_gpio_irq_disable(struct irq_data *data)
    103{
    104	struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
    105	u32 mask = BIT(irqd_to_hwirq(data));
    106	unsigned long flags;
    107
    108	raw_spin_lock_irqsave(&ctrl->lock, flags);
    109	ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0);
    110	ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, 0);
    111	raw_spin_unlock_irqrestore(&ctrl->lock, flags);
    112}
    113
    114static int ath79_gpio_irq_set_type(struct irq_data *data,
    115				unsigned int flow_type)
    116{
    117	struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
    118	u32 mask = BIT(irqd_to_hwirq(data));
    119	u32 type = 0, polarity = 0;
    120	unsigned long flags;
    121	bool disabled;
    122
    123	switch (flow_type) {
    124	case IRQ_TYPE_EDGE_RISING:
    125		polarity |= mask;
    126		fallthrough;
    127	case IRQ_TYPE_EDGE_FALLING:
    128	case IRQ_TYPE_EDGE_BOTH:
    129		break;
    130
    131	case IRQ_TYPE_LEVEL_HIGH:
    132		polarity |= mask;
    133		fallthrough;
    134	case IRQ_TYPE_LEVEL_LOW:
    135		type |= mask;
    136		break;
    137
    138	default:
    139		return -EINVAL;
    140	}
    141
    142	raw_spin_lock_irqsave(&ctrl->lock, flags);
    143
    144	if (flow_type == IRQ_TYPE_EDGE_BOTH) {
    145		ctrl->both_edges |= mask;
    146		polarity = ~ath79_gpio_read(ctrl, AR71XX_GPIO_REG_IN);
    147	} else {
    148		ctrl->both_edges &= ~mask;
    149	}
    150
    151	/* As the IRQ configuration can't be loaded atomically we
    152	 * have to disable the interrupt while the configuration state
    153	 * is invalid.
    154	 */
    155	disabled = ath79_gpio_update_bits(
    156		ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, 0);
    157
    158	ath79_gpio_update_bits(
    159		ctrl, AR71XX_GPIO_REG_INT_TYPE, mask, type);
    160	ath79_gpio_update_bits(
    161		ctrl, AR71XX_GPIO_REG_INT_POLARITY, mask, polarity);
    162
    163	if (disabled)
    164		ath79_gpio_update_bits(
    165			ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask);
    166
    167	raw_spin_unlock_irqrestore(&ctrl->lock, flags);
    168
    169	return 0;
    170}
    171
    172static struct irq_chip ath79_gpio_irqchip = {
    173	.name = "gpio-ath79",
    174	.irq_enable = ath79_gpio_irq_enable,
    175	.irq_disable = ath79_gpio_irq_disable,
    176	.irq_mask = ath79_gpio_irq_mask,
    177	.irq_unmask = ath79_gpio_irq_unmask,
    178	.irq_set_type = ath79_gpio_irq_set_type,
    179};
    180
    181static void ath79_gpio_irq_handler(struct irq_desc *desc)
    182{
    183	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
    184	struct irq_chip *irqchip = irq_desc_get_chip(desc);
    185	struct ath79_gpio_ctrl *ctrl =
    186		container_of(gc, struct ath79_gpio_ctrl, gc);
    187	unsigned long flags, pending;
    188	u32 both_edges, state;
    189	int irq;
    190
    191	chained_irq_enter(irqchip, desc);
    192
    193	raw_spin_lock_irqsave(&ctrl->lock, flags);
    194
    195	pending = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_INT_PENDING);
    196
    197	/* Update the polarity of the both edges irqs */
    198	both_edges = ctrl->both_edges & pending;
    199	if (both_edges) {
    200		state = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_IN);
    201		ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_POLARITY,
    202				both_edges, ~state);
    203	}
    204
    205	raw_spin_unlock_irqrestore(&ctrl->lock, flags);
    206
    207	for_each_set_bit(irq, &pending, gc->ngpio)
    208		generic_handle_domain_irq(gc->irq.domain, irq);
    209
    210	chained_irq_exit(irqchip, desc);
    211}
    212
    213static const struct of_device_id ath79_gpio_of_match[] = {
    214	{ .compatible = "qca,ar7100-gpio" },
    215	{ .compatible = "qca,ar9340-gpio" },
    216	{},
    217};
    218MODULE_DEVICE_TABLE(of, ath79_gpio_of_match);
    219
    220static int ath79_gpio_probe(struct platform_device *pdev)
    221{
    222	struct ath79_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
    223	struct device *dev = &pdev->dev;
    224	struct device_node *np = dev->of_node;
    225	struct ath79_gpio_ctrl *ctrl;
    226	struct gpio_irq_chip *girq;
    227	u32 ath79_gpio_count;
    228	bool oe_inverted;
    229	int err;
    230
    231	ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
    232	if (!ctrl)
    233		return -ENOMEM;
    234
    235	if (np) {
    236		err = of_property_read_u32(np, "ngpios", &ath79_gpio_count);
    237		if (err) {
    238			dev_err(dev, "ngpios property is not valid\n");
    239			return err;
    240		}
    241		oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio");
    242	} else if (pdata) {
    243		ath79_gpio_count = pdata->ngpios;
    244		oe_inverted = pdata->oe_inverted;
    245	} else {
    246		dev_err(dev, "No DT node or platform data found\n");
    247		return -EINVAL;
    248	}
    249
    250	if (ath79_gpio_count >= 32) {
    251		dev_err(dev, "ngpios must be less than 32\n");
    252		return -EINVAL;
    253	}
    254
    255	ctrl->base = devm_platform_ioremap_resource(pdev, 0);
    256	if (IS_ERR(ctrl->base))
    257		return PTR_ERR(ctrl->base);
    258
    259	raw_spin_lock_init(&ctrl->lock);
    260	err = bgpio_init(&ctrl->gc, dev, 4,
    261			ctrl->base + AR71XX_GPIO_REG_IN,
    262			ctrl->base + AR71XX_GPIO_REG_SET,
    263			ctrl->base + AR71XX_GPIO_REG_CLEAR,
    264			oe_inverted ? NULL : ctrl->base + AR71XX_GPIO_REG_OE,
    265			oe_inverted ? ctrl->base + AR71XX_GPIO_REG_OE : NULL,
    266			0);
    267	if (err) {
    268		dev_err(dev, "bgpio_init failed\n");
    269		return err;
    270	}
    271	/* Use base 0 to stay compatible with legacy platforms */
    272	ctrl->gc.base = 0;
    273
    274	/* Optional interrupt setup */
    275	if (!np || of_property_read_bool(np, "interrupt-controller")) {
    276		girq = &ctrl->gc.irq;
    277		girq->chip = &ath79_gpio_irqchip;
    278		girq->parent_handler = ath79_gpio_irq_handler;
    279		girq->num_parents = 1;
    280		girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
    281					     GFP_KERNEL);
    282		if (!girq->parents)
    283			return -ENOMEM;
    284		girq->parents[0] = platform_get_irq(pdev, 0);
    285		girq->default_type = IRQ_TYPE_NONE;
    286		girq->handler = handle_simple_irq;
    287	}
    288
    289	return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl);
    290}
    291
    292static struct platform_driver ath79_gpio_driver = {
    293	.driver = {
    294		.name = "ath79-gpio",
    295		.of_match_table	= ath79_gpio_of_match,
    296	},
    297	.probe = ath79_gpio_probe,
    298};
    299
    300module_platform_driver(ath79_gpio_driver);
    301
    302MODULE_DESCRIPTION("Atheros AR71XX/AR724X/AR913X GPIO API support");
    303MODULE_LICENSE("GPL v2");