]>
Commit | Line | Data |
---|---|---|
fbb0efdd SG |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
3 | * Sandbox driver for interrupts | |
4 | * | |
5 | * Copyright 2019 Google LLC | |
6 | */ | |
7 | ||
8 | #include <common.h> | |
9 | #include <dm.h> | |
10 | #include <irq.h> | |
f4955137 | 11 | #include <acpi/acpi_device.h> |
02554355 SG |
12 | #include <asm/test.h> |
13 | ||
14 | /** | |
15 | * struct sandbox_irq_priv - private data for this driver | |
16 | * | |
17 | * @count: Counts the number calls to the read_and_clear() method | |
18 | * @pending: true if an interrupt is pending, else false | |
19 | */ | |
20 | struct sandbox_irq_priv { | |
21 | int count; | |
22 | bool pending; | |
23 | }; | |
fbb0efdd SG |
24 | |
25 | static int sandbox_set_polarity(struct udevice *dev, uint irq, bool active_low) | |
26 | { | |
27 | if (irq > 10) | |
28 | return -EINVAL; | |
29 | ||
30 | return 0; | |
31 | } | |
32 | ||
33 | static int sandbox_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num) | |
34 | { | |
35 | if (pmc_gpe_num > 10) | |
36 | return -ENOENT; | |
37 | ||
38 | return pmc_gpe_num + 1; | |
39 | } | |
40 | ||
41 | static int sandbox_snapshot_polarities(struct udevice *dev) | |
42 | { | |
43 | return 0; | |
44 | } | |
45 | ||
46 | static int sandbox_restore_polarities(struct udevice *dev) | |
47 | { | |
48 | return 0; | |
49 | } | |
50 | ||
02554355 SG |
51 | static int sandbox_irq_read_and_clear(struct irq *irq) |
52 | { | |
53 | struct sandbox_irq_priv *priv = dev_get_priv(irq->dev); | |
54 | ||
55 | if (irq->id != SANDBOX_IRQN_PEND) | |
56 | return -EINVAL; | |
57 | priv->count++; | |
58 | if (priv->pending) { | |
59 | priv->pending = false; | |
60 | return 1; | |
61 | } | |
62 | ||
63 | if (!(priv->count % 3)) | |
64 | priv->pending = true; | |
65 | ||
66 | return 0; | |
67 | } | |
68 | ||
69 | static int sandbox_irq_of_xlate(struct irq *irq, | |
70 | struct ofnode_phandle_args *args) | |
71 | { | |
72 | irq->id = args->args[0]; | |
73 | ||
74 | return 0; | |
75 | } | |
76 | ||
f4955137 SG |
77 | static __maybe_unused int sandbox_get_acpi(const struct irq *irq, |
78 | struct acpi_irq *acpi_irq) | |
79 | { | |
80 | acpi_irq->pin = irq->id; | |
81 | acpi_irq->mode = ACPI_IRQ_LEVEL_TRIGGERED; | |
82 | acpi_irq->polarity = ACPI_IRQ_ACTIVE_HIGH; | |
83 | acpi_irq->shared = ACPI_IRQ_SHARED; | |
84 | acpi_irq->wake = ACPI_IRQ_WAKE; | |
85 | ||
86 | return 0; | |
87 | } | |
88 | ||
fbb0efdd SG |
89 | static const struct irq_ops sandbox_irq_ops = { |
90 | .route_pmc_gpio_gpe = sandbox_route_pmc_gpio_gpe, | |
91 | .set_polarity = sandbox_set_polarity, | |
92 | .snapshot_polarities = sandbox_snapshot_polarities, | |
93 | .restore_polarities = sandbox_restore_polarities, | |
02554355 SG |
94 | .read_and_clear = sandbox_irq_read_and_clear, |
95 | .of_xlate = sandbox_irq_of_xlate, | |
f4955137 SG |
96 | #if CONFIG_IS_ENABLED(ACPIGEN) |
97 | .get_acpi = sandbox_get_acpi, | |
98 | #endif | |
fbb0efdd SG |
99 | }; |
100 | ||
101 | static const struct udevice_id sandbox_irq_ids[] = { | |
ba876079 | 102 | { .compatible = "sandbox,irq", SANDBOX_IRQT_BASE }, |
fbb0efdd SG |
103 | { } |
104 | }; | |
105 | ||
106 | U_BOOT_DRIVER(sandbox_irq_drv) = { | |
107 | .name = "sandbox_irq", | |
108 | .id = UCLASS_IRQ, | |
109 | .of_match = sandbox_irq_ids, | |
110 | .ops = &sandbox_irq_ops, | |
41575d8e | 111 | .priv_auto = sizeof(struct sandbox_irq_priv), |
fbb0efdd | 112 | }; |