This source file includes following definitions.
- int0002_gpio_get
- int0002_gpio_set
- int0002_gpio_direction_output
- int0002_irq_ack
- int0002_irq_unmask
- int0002_irq_mask
- int0002_irq_set_wake
- int0002_irq
- int0002_check_wake
- int0002_init_irq_valid_mask
- int0002_probe
- int0002_remove
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <linux/acpi.h>
31 #include <linux/bitmap.h>
32 #include <linux/gpio/driver.h>
33 #include <linux/interrupt.h>
34 #include <linux/io.h>
35 #include <linux/kernel.h>
36 #include <linux/module.h>
37 #include <linux/platform_device.h>
38 #include <linux/slab.h>
39 #include <linux/suspend.h>
40
41 #include <asm/cpu_device_id.h>
42 #include <asm/intel-family.h>
43
44 #define DRV_NAME "INT0002 Virtual GPIO"
45
46
47 #define GPE0A_PME_B0_VIRT_GPIO_PIN 2
48
49 #define GPE0A_PME_B0_STS_BIT BIT(13)
50 #define GPE0A_PME_B0_EN_BIT BIT(13)
51 #define GPE0A_STS_PORT 0x420
52 #define GPE0A_EN_PORT 0x428
53
54
55
56
57
58
59 static int int0002_gpio_get(struct gpio_chip *chip, unsigned int offset)
60 {
61 return 0;
62 }
63
64 static void int0002_gpio_set(struct gpio_chip *chip, unsigned int offset,
65 int value)
66 {
67 }
68
69 static int int0002_gpio_direction_output(struct gpio_chip *chip,
70 unsigned int offset, int value)
71 {
72 return 0;
73 }
74
75 static void int0002_irq_ack(struct irq_data *data)
76 {
77 outl(GPE0A_PME_B0_STS_BIT, GPE0A_STS_PORT);
78 }
79
80 static void int0002_irq_unmask(struct irq_data *data)
81 {
82 u32 gpe_en_reg;
83
84 gpe_en_reg = inl(GPE0A_EN_PORT);
85 gpe_en_reg |= GPE0A_PME_B0_EN_BIT;
86 outl(gpe_en_reg, GPE0A_EN_PORT);
87 }
88
89 static void int0002_irq_mask(struct irq_data *data)
90 {
91 u32 gpe_en_reg;
92
93 gpe_en_reg = inl(GPE0A_EN_PORT);
94 gpe_en_reg &= ~GPE0A_PME_B0_EN_BIT;
95 outl(gpe_en_reg, GPE0A_EN_PORT);
96 }
97
98 static int int0002_irq_set_wake(struct irq_data *data, unsigned int on)
99 {
100 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
101 struct platform_device *pdev = to_platform_device(chip->parent);
102 int irq = platform_get_irq(pdev, 0);
103
104
105 if (on)
106 enable_irq_wake(irq);
107 else
108 disable_irq_wake(irq);
109
110 return 0;
111 }
112
113 static irqreturn_t int0002_irq(int irq, void *data)
114 {
115 struct gpio_chip *chip = data;
116 u32 gpe_sts_reg;
117
118 gpe_sts_reg = inl(GPE0A_STS_PORT);
119 if (!(gpe_sts_reg & GPE0A_PME_B0_STS_BIT))
120 return IRQ_NONE;
121
122 generic_handle_irq(irq_find_mapping(chip->irq.domain,
123 GPE0A_PME_B0_VIRT_GPIO_PIN));
124
125 pm_wakeup_hard_event(chip->parent);
126
127 return IRQ_HANDLED;
128 }
129
130 static bool int0002_check_wake(void *data)
131 {
132 u32 gpe_sts_reg;
133
134 gpe_sts_reg = inl(GPE0A_STS_PORT);
135 return (gpe_sts_reg & GPE0A_PME_B0_STS_BIT);
136 }
137
138 static struct irq_chip int0002_byt_irqchip = {
139 .name = DRV_NAME,
140 .irq_ack = int0002_irq_ack,
141 .irq_mask = int0002_irq_mask,
142 .irq_unmask = int0002_irq_unmask,
143 .irq_set_wake = int0002_irq_set_wake,
144 };
145
146 static struct irq_chip int0002_cht_irqchip = {
147 .name = DRV_NAME,
148 .irq_ack = int0002_irq_ack,
149 .irq_mask = int0002_irq_mask,
150 .irq_unmask = int0002_irq_unmask,
151
152
153
154
155 .flags = IRQCHIP_SKIP_SET_WAKE,
156 };
157
158 static const struct x86_cpu_id int0002_cpu_ids[] = {
159 INTEL_CPU_FAM6(ATOM_SILVERMONT, int0002_byt_irqchip),
160 INTEL_CPU_FAM6(ATOM_AIRMONT, int0002_cht_irqchip),
161 {}
162 };
163
164 static void int0002_init_irq_valid_mask(struct gpio_chip *chip,
165 unsigned long *valid_mask,
166 unsigned int ngpios)
167 {
168 bitmap_clear(valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN);
169 }
170
171 static int int0002_probe(struct platform_device *pdev)
172 {
173 struct device *dev = &pdev->dev;
174 const struct x86_cpu_id *cpu_id;
175 struct irq_chip *irq_chip;
176 struct gpio_chip *chip;
177 int irq, ret;
178
179
180 cpu_id = x86_match_cpu(int0002_cpu_ids);
181 if (!cpu_id)
182 return -ENODEV;
183
184 irq = platform_get_irq(pdev, 0);
185 if (irq < 0)
186 return irq;
187
188 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
189 if (!chip)
190 return -ENOMEM;
191
192 chip->label = DRV_NAME;
193 chip->parent = dev;
194 chip->owner = THIS_MODULE;
195 chip->get = int0002_gpio_get;
196 chip->set = int0002_gpio_set;
197 chip->direction_input = int0002_gpio_get;
198 chip->direction_output = int0002_gpio_direction_output;
199 chip->base = -1;
200 chip->ngpio = GPE0A_PME_B0_VIRT_GPIO_PIN + 1;
201 chip->irq.init_valid_mask = int0002_init_irq_valid_mask;
202
203 ret = devm_gpiochip_add_data(&pdev->dev, chip, NULL);
204 if (ret) {
205 dev_err(dev, "Error adding gpio chip: %d\n", ret);
206 return ret;
207 }
208
209
210
211
212
213 ret = devm_request_irq(dev, irq, int0002_irq,
214 IRQF_SHARED, "INT0002", chip);
215 if (ret) {
216 dev_err(dev, "Error requesting IRQ %d: %d\n", irq, ret);
217 return ret;
218 }
219
220 irq_chip = (struct irq_chip *)cpu_id->driver_data;
221
222 ret = gpiochip_irqchip_add(chip, irq_chip, 0, handle_edge_irq,
223 IRQ_TYPE_NONE);
224 if (ret) {
225 dev_err(dev, "Error adding irqchip: %d\n", ret);
226 return ret;
227 }
228
229 gpiochip_set_chained_irqchip(chip, irq_chip, irq, NULL);
230
231 acpi_register_wakeup_handler(irq, int0002_check_wake, NULL);
232 device_init_wakeup(dev, true);
233 return 0;
234 }
235
236 static int int0002_remove(struct platform_device *pdev)
237 {
238 device_init_wakeup(&pdev->dev, false);
239 acpi_unregister_wakeup_handler(int0002_check_wake, NULL);
240 return 0;
241 }
242
243 static const struct acpi_device_id int0002_acpi_ids[] = {
244 { "INT0002", 0 },
245 { },
246 };
247 MODULE_DEVICE_TABLE(acpi, int0002_acpi_ids);
248
249 static struct platform_driver int0002_driver = {
250 .driver = {
251 .name = DRV_NAME,
252 .acpi_match_table = int0002_acpi_ids,
253 },
254 .probe = int0002_probe,
255 .remove = int0002_remove,
256 };
257
258 module_platform_driver(int0002_driver);
259
260 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
261 MODULE_DESCRIPTION("Intel INT0002 Virtual GPIO driver");
262 MODULE_LICENSE("GPL v2");