11d2a22faSKrzysztof Kozlowski // SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
2cd33f216SAsmaa Mnebhi /* Copyright (C) 2022 NVIDIA CORPORATION & AFFILIATES */
3cd33f216SAsmaa Mnebhi
4cd33f216SAsmaa Mnebhi #include <linux/bitfield.h>
5cd33f216SAsmaa Mnebhi #include <linux/bitops.h>
6cd33f216SAsmaa Mnebhi #include <linux/device.h>
7cd33f216SAsmaa Mnebhi #include <linux/err.h>
8cd33f216SAsmaa Mnebhi #include <linux/gpio/driver.h>
9cd33f216SAsmaa Mnebhi #include <linux/interrupt.h>
10cd33f216SAsmaa Mnebhi #include <linux/io.h>
11cd33f216SAsmaa Mnebhi #include <linux/module.h>
12cd33f216SAsmaa Mnebhi #include <linux/platform_device.h>
13cd33f216SAsmaa Mnebhi #include <linux/spinlock.h>
14cd33f216SAsmaa Mnebhi #include <linux/types.h>
15cd33f216SAsmaa Mnebhi
16cd33f216SAsmaa Mnebhi /*
17cd33f216SAsmaa Mnebhi * There are 2 YU GPIO blocks:
18cd33f216SAsmaa Mnebhi * gpio[0]: HOST_GPIO0->HOST_GPIO31
19cd33f216SAsmaa Mnebhi * gpio[1]: HOST_GPIO32->HOST_GPIO55
20cd33f216SAsmaa Mnebhi */
21cd33f216SAsmaa Mnebhi #define MLXBF3_GPIO_MAX_PINS_PER_BLOCK 32
2238a700efSAsmaa Mnebhi #define MLXBF3_GPIO_MAX_PINS_BLOCK0 32
2338a700efSAsmaa Mnebhi #define MLXBF3_GPIO_MAX_PINS_BLOCK1 24
24cd33f216SAsmaa Mnebhi
25cd33f216SAsmaa Mnebhi /*
26cd33f216SAsmaa Mnebhi * fw_gpio[x] block registers and their offset
27cd33f216SAsmaa Mnebhi */
28cd33f216SAsmaa Mnebhi #define MLXBF_GPIO_FW_OUTPUT_ENABLE_SET 0x00
29cd33f216SAsmaa Mnebhi #define MLXBF_GPIO_FW_DATA_OUT_SET 0x04
30cd33f216SAsmaa Mnebhi
31cd33f216SAsmaa Mnebhi #define MLXBF_GPIO_FW_OUTPUT_ENABLE_CLEAR 0x00
32cd33f216SAsmaa Mnebhi #define MLXBF_GPIO_FW_DATA_OUT_CLEAR 0x04
33cd33f216SAsmaa Mnebhi
34cd33f216SAsmaa Mnebhi #define MLXBF_GPIO_CAUSE_RISE_EN 0x00
35cd33f216SAsmaa Mnebhi #define MLXBF_GPIO_CAUSE_FALL_EN 0x04
36cd33f216SAsmaa Mnebhi #define MLXBF_GPIO_READ_DATA_IN 0x08
37cd33f216SAsmaa Mnebhi
38cd33f216SAsmaa Mnebhi #define MLXBF_GPIO_CAUSE_OR_CAUSE_EVTEN0 0x00
39cd33f216SAsmaa Mnebhi #define MLXBF_GPIO_CAUSE_OR_EVTEN0 0x14
40cd33f216SAsmaa Mnebhi #define MLXBF_GPIO_CAUSE_OR_CLRCAUSE 0x18
41cd33f216SAsmaa Mnebhi
42*aad41832SAsmaa Mnebhi #define MLXBF_GPIO_CLR_ALL_INTS GENMASK(31, 0)
43*aad41832SAsmaa Mnebhi
44cd33f216SAsmaa Mnebhi struct mlxbf3_gpio_context {
45cd33f216SAsmaa Mnebhi struct gpio_chip gc;
46cd33f216SAsmaa Mnebhi
47cd33f216SAsmaa Mnebhi /* YU GPIO block address */
48cd33f216SAsmaa Mnebhi void __iomem *gpio_set_io;
49cd33f216SAsmaa Mnebhi void __iomem *gpio_clr_io;
50cd33f216SAsmaa Mnebhi void __iomem *gpio_io;
51cd33f216SAsmaa Mnebhi
52cd33f216SAsmaa Mnebhi /* YU GPIO cause block address */
53cd33f216SAsmaa Mnebhi void __iomem *gpio_cause_io;
54cd33f216SAsmaa Mnebhi };
55cd33f216SAsmaa Mnebhi
mlxbf3_gpio_irq_enable(struct irq_data * irqd)56cd33f216SAsmaa Mnebhi static void mlxbf3_gpio_irq_enable(struct irq_data *irqd)
57cd33f216SAsmaa Mnebhi {
58cd33f216SAsmaa Mnebhi struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
59cd33f216SAsmaa Mnebhi struct mlxbf3_gpio_context *gs = gpiochip_get_data(gc);
60cd33f216SAsmaa Mnebhi irq_hw_number_t offset = irqd_to_hwirq(irqd);
61cd33f216SAsmaa Mnebhi unsigned long flags;
62cd33f216SAsmaa Mnebhi u32 val;
63cd33f216SAsmaa Mnebhi
64cd33f216SAsmaa Mnebhi gpiochip_enable_irq(gc, offset);
65cd33f216SAsmaa Mnebhi
66cd33f216SAsmaa Mnebhi raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
67cd33f216SAsmaa Mnebhi writel(BIT(offset), gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
68cd33f216SAsmaa Mnebhi
69cd33f216SAsmaa Mnebhi val = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
70cd33f216SAsmaa Mnebhi val |= BIT(offset);
71cd33f216SAsmaa Mnebhi writel(val, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
72cd33f216SAsmaa Mnebhi raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
73cd33f216SAsmaa Mnebhi }
74cd33f216SAsmaa Mnebhi
mlxbf3_gpio_irq_disable(struct irq_data * irqd)75cd33f216SAsmaa Mnebhi static void mlxbf3_gpio_irq_disable(struct irq_data *irqd)
76cd33f216SAsmaa Mnebhi {
77cd33f216SAsmaa Mnebhi struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
78cd33f216SAsmaa Mnebhi struct mlxbf3_gpio_context *gs = gpiochip_get_data(gc);
79cd33f216SAsmaa Mnebhi irq_hw_number_t offset = irqd_to_hwirq(irqd);
80cd33f216SAsmaa Mnebhi unsigned long flags;
81cd33f216SAsmaa Mnebhi u32 val;
82cd33f216SAsmaa Mnebhi
83cd33f216SAsmaa Mnebhi raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
84cd33f216SAsmaa Mnebhi val = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
85cd33f216SAsmaa Mnebhi val &= ~BIT(offset);
86cd33f216SAsmaa Mnebhi writel(val, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
87*aad41832SAsmaa Mnebhi
88*aad41832SAsmaa Mnebhi writel(BIT(offset), gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
89cd33f216SAsmaa Mnebhi raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
90cd33f216SAsmaa Mnebhi
91cd33f216SAsmaa Mnebhi gpiochip_disable_irq(gc, offset);
92cd33f216SAsmaa Mnebhi }
93cd33f216SAsmaa Mnebhi
mlxbf3_gpio_irq_handler(int irq,void * ptr)94cd33f216SAsmaa Mnebhi static irqreturn_t mlxbf3_gpio_irq_handler(int irq, void *ptr)
95cd33f216SAsmaa Mnebhi {
96cd33f216SAsmaa Mnebhi struct mlxbf3_gpio_context *gs = ptr;
97cd33f216SAsmaa Mnebhi struct gpio_chip *gc = &gs->gc;
98cd33f216SAsmaa Mnebhi unsigned long pending;
99cd33f216SAsmaa Mnebhi u32 level;
100cd33f216SAsmaa Mnebhi
101cd33f216SAsmaa Mnebhi pending = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CAUSE_EVTEN0);
102cd33f216SAsmaa Mnebhi writel(pending, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
103cd33f216SAsmaa Mnebhi
104cd33f216SAsmaa Mnebhi for_each_set_bit(level, &pending, gc->ngpio)
105cd33f216SAsmaa Mnebhi generic_handle_domain_irq(gc->irq.domain, level);
106cd33f216SAsmaa Mnebhi
107cd33f216SAsmaa Mnebhi return IRQ_RETVAL(pending);
108cd33f216SAsmaa Mnebhi }
109cd33f216SAsmaa Mnebhi
110cd33f216SAsmaa Mnebhi static int
mlxbf3_gpio_irq_set_type(struct irq_data * irqd,unsigned int type)111cd33f216SAsmaa Mnebhi mlxbf3_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
112cd33f216SAsmaa Mnebhi {
113cd33f216SAsmaa Mnebhi struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
114cd33f216SAsmaa Mnebhi struct mlxbf3_gpio_context *gs = gpiochip_get_data(gc);
115cd33f216SAsmaa Mnebhi irq_hw_number_t offset = irqd_to_hwirq(irqd);
116cd33f216SAsmaa Mnebhi unsigned long flags;
117cd33f216SAsmaa Mnebhi u32 val;
118cd33f216SAsmaa Mnebhi
119cd33f216SAsmaa Mnebhi raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
120cd33f216SAsmaa Mnebhi
121cd33f216SAsmaa Mnebhi switch (type & IRQ_TYPE_SENSE_MASK) {
122cd33f216SAsmaa Mnebhi case IRQ_TYPE_EDGE_BOTH:
123cd33f216SAsmaa Mnebhi val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
124cd33f216SAsmaa Mnebhi val |= BIT(offset);
125cd33f216SAsmaa Mnebhi writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
126cd33f216SAsmaa Mnebhi val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
127cd33f216SAsmaa Mnebhi val |= BIT(offset);
128cd33f216SAsmaa Mnebhi writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
129cd33f216SAsmaa Mnebhi break;
130cd33f216SAsmaa Mnebhi case IRQ_TYPE_EDGE_RISING:
131cd33f216SAsmaa Mnebhi val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
132cd33f216SAsmaa Mnebhi val |= BIT(offset);
133cd33f216SAsmaa Mnebhi writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
134cd33f216SAsmaa Mnebhi break;
135cd33f216SAsmaa Mnebhi case IRQ_TYPE_EDGE_FALLING:
136cd33f216SAsmaa Mnebhi val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
137cd33f216SAsmaa Mnebhi val |= BIT(offset);
138cd33f216SAsmaa Mnebhi writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
139cd33f216SAsmaa Mnebhi break;
140cd33f216SAsmaa Mnebhi default:
141cd33f216SAsmaa Mnebhi raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
142cd33f216SAsmaa Mnebhi return -EINVAL;
143cd33f216SAsmaa Mnebhi }
144cd33f216SAsmaa Mnebhi
145cd33f216SAsmaa Mnebhi raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
146cd33f216SAsmaa Mnebhi
147cd33f216SAsmaa Mnebhi irq_set_handler_locked(irqd, handle_edge_irq);
148cd33f216SAsmaa Mnebhi
149cd33f216SAsmaa Mnebhi return 0;
150cd33f216SAsmaa Mnebhi }
151cd33f216SAsmaa Mnebhi
152cd33f216SAsmaa Mnebhi /* This function needs to be defined for handle_edge_irq() */
mlxbf3_gpio_irq_ack(struct irq_data * data)153cd33f216SAsmaa Mnebhi static void mlxbf3_gpio_irq_ack(struct irq_data *data)
154cd33f216SAsmaa Mnebhi {
155cd33f216SAsmaa Mnebhi }
156cd33f216SAsmaa Mnebhi
157cd33f216SAsmaa Mnebhi static const struct irq_chip gpio_mlxbf3_irqchip = {
158cd33f216SAsmaa Mnebhi .name = "MLNXBF33",
159cd33f216SAsmaa Mnebhi .irq_ack = mlxbf3_gpio_irq_ack,
160cd33f216SAsmaa Mnebhi .irq_set_type = mlxbf3_gpio_irq_set_type,
161cd33f216SAsmaa Mnebhi .irq_enable = mlxbf3_gpio_irq_enable,
162cd33f216SAsmaa Mnebhi .irq_disable = mlxbf3_gpio_irq_disable,
163cd33f216SAsmaa Mnebhi .flags = IRQCHIP_IMMUTABLE,
164cd33f216SAsmaa Mnebhi GPIOCHIP_IRQ_RESOURCE_HELPERS,
165cd33f216SAsmaa Mnebhi };
166cd33f216SAsmaa Mnebhi
mlxbf3_gpio_add_pin_ranges(struct gpio_chip * chip)16738a700efSAsmaa Mnebhi static int mlxbf3_gpio_add_pin_ranges(struct gpio_chip *chip)
16838a700efSAsmaa Mnebhi {
16938a700efSAsmaa Mnebhi unsigned int id;
17038a700efSAsmaa Mnebhi
17138a700efSAsmaa Mnebhi switch(chip->ngpio) {
17238a700efSAsmaa Mnebhi case MLXBF3_GPIO_MAX_PINS_BLOCK0:
17338a700efSAsmaa Mnebhi id = 0;
17438a700efSAsmaa Mnebhi break;
17538a700efSAsmaa Mnebhi case MLXBF3_GPIO_MAX_PINS_BLOCK1:
17638a700efSAsmaa Mnebhi id = 1;
17738a700efSAsmaa Mnebhi break;
17838a700efSAsmaa Mnebhi default:
17938a700efSAsmaa Mnebhi return -EINVAL;
18038a700efSAsmaa Mnebhi }
18138a700efSAsmaa Mnebhi
18238a700efSAsmaa Mnebhi return gpiochip_add_pin_range(chip, "MLNXBF34:00",
18338a700efSAsmaa Mnebhi chip->base, id * MLXBF3_GPIO_MAX_PINS_PER_BLOCK,
18438a700efSAsmaa Mnebhi chip->ngpio);
18538a700efSAsmaa Mnebhi }
18638a700efSAsmaa Mnebhi
mlxbf3_gpio_probe(struct platform_device * pdev)187cd33f216SAsmaa Mnebhi static int mlxbf3_gpio_probe(struct platform_device *pdev)
188cd33f216SAsmaa Mnebhi {
189cd33f216SAsmaa Mnebhi struct device *dev = &pdev->dev;
190cd33f216SAsmaa Mnebhi struct mlxbf3_gpio_context *gs;
191cd33f216SAsmaa Mnebhi struct gpio_irq_chip *girq;
192cd33f216SAsmaa Mnebhi struct gpio_chip *gc;
193cd33f216SAsmaa Mnebhi int ret, irq;
194cd33f216SAsmaa Mnebhi
195cd33f216SAsmaa Mnebhi gs = devm_kzalloc(dev, sizeof(*gs), GFP_KERNEL);
196cd33f216SAsmaa Mnebhi if (!gs)
197cd33f216SAsmaa Mnebhi return -ENOMEM;
198cd33f216SAsmaa Mnebhi
199cd33f216SAsmaa Mnebhi gs->gpio_io = devm_platform_ioremap_resource(pdev, 0);
200cd33f216SAsmaa Mnebhi if (IS_ERR(gs->gpio_io))
201cd33f216SAsmaa Mnebhi return PTR_ERR(gs->gpio_io);
202cd33f216SAsmaa Mnebhi
203cd33f216SAsmaa Mnebhi gs->gpio_cause_io = devm_platform_ioremap_resource(pdev, 1);
204cd33f216SAsmaa Mnebhi if (IS_ERR(gs->gpio_cause_io))
205cd33f216SAsmaa Mnebhi return PTR_ERR(gs->gpio_cause_io);
206cd33f216SAsmaa Mnebhi
207cd33f216SAsmaa Mnebhi gs->gpio_set_io = devm_platform_ioremap_resource(pdev, 2);
208cd33f216SAsmaa Mnebhi if (IS_ERR(gs->gpio_set_io))
209cd33f216SAsmaa Mnebhi return PTR_ERR(gs->gpio_set_io);
210cd33f216SAsmaa Mnebhi
211cd33f216SAsmaa Mnebhi gs->gpio_clr_io = devm_platform_ioremap_resource(pdev, 3);
212cd33f216SAsmaa Mnebhi if (IS_ERR(gs->gpio_clr_io))
213cd33f216SAsmaa Mnebhi return PTR_ERR(gs->gpio_clr_io);
214cd33f216SAsmaa Mnebhi gc = &gs->gc;
215cd33f216SAsmaa Mnebhi
216cd33f216SAsmaa Mnebhi ret = bgpio_init(gc, dev, 4,
217cd33f216SAsmaa Mnebhi gs->gpio_io + MLXBF_GPIO_READ_DATA_IN,
218cd33f216SAsmaa Mnebhi gs->gpio_set_io + MLXBF_GPIO_FW_DATA_OUT_SET,
219cd33f216SAsmaa Mnebhi gs->gpio_clr_io + MLXBF_GPIO_FW_DATA_OUT_CLEAR,
220cd33f216SAsmaa Mnebhi gs->gpio_set_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_SET,
221cd33f216SAsmaa Mnebhi gs->gpio_clr_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_CLEAR, 0);
222d460e9c2SSu Hui if (ret)
223d460e9c2SSu Hui return dev_err_probe(dev, ret, "%s: bgpio_init() failed", __func__);
224cd33f216SAsmaa Mnebhi
225cd33f216SAsmaa Mnebhi gc->request = gpiochip_generic_request;
226cd33f216SAsmaa Mnebhi gc->free = gpiochip_generic_free;
227cd33f216SAsmaa Mnebhi gc->owner = THIS_MODULE;
22838a700efSAsmaa Mnebhi gc->add_pin_ranges = mlxbf3_gpio_add_pin_ranges;
229cd33f216SAsmaa Mnebhi
230cd33f216SAsmaa Mnebhi irq = platform_get_irq(pdev, 0);
231cd33f216SAsmaa Mnebhi if (irq >= 0) {
232cd33f216SAsmaa Mnebhi girq = &gs->gc.irq;
233cd33f216SAsmaa Mnebhi gpio_irq_chip_set_chip(girq, &gpio_mlxbf3_irqchip);
234cd33f216SAsmaa Mnebhi girq->default_type = IRQ_TYPE_NONE;
235cd33f216SAsmaa Mnebhi /* This will let us handle the parent IRQ in the driver */
236cd33f216SAsmaa Mnebhi girq->num_parents = 0;
237cd33f216SAsmaa Mnebhi girq->parents = NULL;
238cd33f216SAsmaa Mnebhi girq->parent_handler = NULL;
239cd33f216SAsmaa Mnebhi girq->handler = handle_bad_irq;
240cd33f216SAsmaa Mnebhi
241cd33f216SAsmaa Mnebhi /*
242cd33f216SAsmaa Mnebhi * Directly request the irq here instead of passing
243cd33f216SAsmaa Mnebhi * a flow-handler because the irq is shared.
244cd33f216SAsmaa Mnebhi */
245cd33f216SAsmaa Mnebhi ret = devm_request_irq(dev, irq, mlxbf3_gpio_irq_handler,
246cd33f216SAsmaa Mnebhi IRQF_SHARED, dev_name(dev), gs);
247cd33f216SAsmaa Mnebhi if (ret)
248cd33f216SAsmaa Mnebhi return dev_err_probe(dev, ret, "failed to request IRQ");
249cd33f216SAsmaa Mnebhi }
250cd33f216SAsmaa Mnebhi
251cd33f216SAsmaa Mnebhi platform_set_drvdata(pdev, gs);
252cd33f216SAsmaa Mnebhi
253cd33f216SAsmaa Mnebhi ret = devm_gpiochip_add_data(dev, &gs->gc, gs);
254cd33f216SAsmaa Mnebhi if (ret)
255cd33f216SAsmaa Mnebhi dev_err_probe(dev, ret, "Failed adding memory mapped gpiochip\n");
256cd33f216SAsmaa Mnebhi
257cd33f216SAsmaa Mnebhi return 0;
258cd33f216SAsmaa Mnebhi }
259cd33f216SAsmaa Mnebhi
mlxbf3_gpio_shutdown(struct platform_device * pdev)260*aad41832SAsmaa Mnebhi static void mlxbf3_gpio_shutdown(struct platform_device *pdev)
261*aad41832SAsmaa Mnebhi {
262*aad41832SAsmaa Mnebhi struct mlxbf3_gpio_context *gs = platform_get_drvdata(pdev);
263*aad41832SAsmaa Mnebhi
264*aad41832SAsmaa Mnebhi /* Disable and clear all interrupts */
265*aad41832SAsmaa Mnebhi writel(0, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
266*aad41832SAsmaa Mnebhi writel(MLXBF_GPIO_CLR_ALL_INTS, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
267*aad41832SAsmaa Mnebhi }
268*aad41832SAsmaa Mnebhi
269cd33f216SAsmaa Mnebhi static const struct acpi_device_id mlxbf3_gpio_acpi_match[] = {
270cd33f216SAsmaa Mnebhi { "MLNXBF33", 0 },
271cd33f216SAsmaa Mnebhi {}
272cd33f216SAsmaa Mnebhi };
273cd33f216SAsmaa Mnebhi MODULE_DEVICE_TABLE(acpi, mlxbf3_gpio_acpi_match);
274cd33f216SAsmaa Mnebhi
275cd33f216SAsmaa Mnebhi static struct platform_driver mlxbf3_gpio_driver = {
276cd33f216SAsmaa Mnebhi .driver = {
277cd33f216SAsmaa Mnebhi .name = "mlxbf3_gpio",
278cd33f216SAsmaa Mnebhi .acpi_match_table = mlxbf3_gpio_acpi_match,
279cd33f216SAsmaa Mnebhi },
280cd33f216SAsmaa Mnebhi .probe = mlxbf3_gpio_probe,
281*aad41832SAsmaa Mnebhi .shutdown = mlxbf3_gpio_shutdown,
282cd33f216SAsmaa Mnebhi };
283cd33f216SAsmaa Mnebhi module_platform_driver(mlxbf3_gpio_driver);
284cd33f216SAsmaa Mnebhi
28538a700efSAsmaa Mnebhi MODULE_SOFTDEP("pre: pinctrl-mlxbf3");
286cd33f216SAsmaa Mnebhi MODULE_DESCRIPTION("NVIDIA BlueField-3 GPIO Driver");
287cd33f216SAsmaa Mnebhi MODULE_AUTHOR("Asmaa Mnebhi <asmaa@nvidia.com>");
288cd33f216SAsmaa Mnebhi MODULE_LICENSE("Dual BSD/GPL");
289