1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Sonics Silicon Backplane
3*4882a593Smuzhiyun * GPIO driver
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright 2011, Broadcom Corporation
6*4882a593Smuzhiyun * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Licensed under the GNU/GPL. See COPYING for details.
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include "ssb_private.h"
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include <linux/gpio/driver.h>
14*4882a593Smuzhiyun #include <linux/irq.h>
15*4882a593Smuzhiyun #include <linux/interrupt.h>
16*4882a593Smuzhiyun #include <linux/irqdomain.h>
17*4882a593Smuzhiyun #include <linux/export.h>
18*4882a593Smuzhiyun #include <linux/ssb/ssb.h>
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun /**************************************************
22*4882a593Smuzhiyun * Shared
23*4882a593Smuzhiyun **************************************************/
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SSB_EMBEDDED)
ssb_gpio_to_irq(struct gpio_chip * chip,unsigned int gpio)26*4882a593Smuzhiyun static int ssb_gpio_to_irq(struct gpio_chip *chip, unsigned int gpio)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun struct ssb_bus *bus = gpiochip_get_data(chip);
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun if (bus->bustype == SSB_BUSTYPE_SSB)
31*4882a593Smuzhiyun return irq_find_mapping(bus->irq_domain, gpio);
32*4882a593Smuzhiyun else
33*4882a593Smuzhiyun return -EINVAL;
34*4882a593Smuzhiyun }
35*4882a593Smuzhiyun #endif
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /**************************************************
38*4882a593Smuzhiyun * ChipCommon
39*4882a593Smuzhiyun **************************************************/
40*4882a593Smuzhiyun
ssb_gpio_chipco_get_value(struct gpio_chip * chip,unsigned int gpio)41*4882a593Smuzhiyun static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned int gpio)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun struct ssb_bus *bus = gpiochip_get_data(chip);
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun return !!ssb_chipco_gpio_in(&bus->chipco, 1 << gpio);
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun
ssb_gpio_chipco_set_value(struct gpio_chip * chip,unsigned int gpio,int value)48*4882a593Smuzhiyun static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned int gpio,
49*4882a593Smuzhiyun int value)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun struct ssb_bus *bus = gpiochip_get_data(chip);
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0);
54*4882a593Smuzhiyun }
55*4882a593Smuzhiyun
ssb_gpio_chipco_direction_input(struct gpio_chip * chip,unsigned int gpio)56*4882a593Smuzhiyun static int ssb_gpio_chipco_direction_input(struct gpio_chip *chip,
57*4882a593Smuzhiyun unsigned int gpio)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun struct ssb_bus *bus = gpiochip_get_data(chip);
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 0);
62*4882a593Smuzhiyun return 0;
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
ssb_gpio_chipco_direction_output(struct gpio_chip * chip,unsigned int gpio,int value)65*4882a593Smuzhiyun static int ssb_gpio_chipco_direction_output(struct gpio_chip *chip,
66*4882a593Smuzhiyun unsigned int gpio, int value)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun struct ssb_bus *bus = gpiochip_get_data(chip);
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 1 << gpio);
71*4882a593Smuzhiyun ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0);
72*4882a593Smuzhiyun return 0;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
ssb_gpio_chipco_request(struct gpio_chip * chip,unsigned int gpio)75*4882a593Smuzhiyun static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned int gpio)
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun struct ssb_bus *bus = gpiochip_get_data(chip);
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun ssb_chipco_gpio_control(&bus->chipco, 1 << gpio, 0);
80*4882a593Smuzhiyun /* clear pulldown */
81*4882a593Smuzhiyun ssb_chipco_gpio_pulldown(&bus->chipco, 1 << gpio, 0);
82*4882a593Smuzhiyun /* Set pullup */
83*4882a593Smuzhiyun ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 1 << gpio);
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun return 0;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
ssb_gpio_chipco_free(struct gpio_chip * chip,unsigned int gpio)88*4882a593Smuzhiyun static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned int gpio)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun struct ssb_bus *bus = gpiochip_get_data(chip);
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun /* clear pullup */
93*4882a593Smuzhiyun ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0);
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SSB_EMBEDDED)
ssb_gpio_irq_chipco_mask(struct irq_data * d)97*4882a593Smuzhiyun static void ssb_gpio_irq_chipco_mask(struct irq_data *d)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
100*4882a593Smuzhiyun int gpio = irqd_to_hwirq(d);
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), 0);
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun
ssb_gpio_irq_chipco_unmask(struct irq_data * d)105*4882a593Smuzhiyun static void ssb_gpio_irq_chipco_unmask(struct irq_data *d)
106*4882a593Smuzhiyun {
107*4882a593Smuzhiyun struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
108*4882a593Smuzhiyun int gpio = irqd_to_hwirq(d);
109*4882a593Smuzhiyun u32 val = ssb_chipco_gpio_in(&bus->chipco, BIT(gpio));
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun ssb_chipco_gpio_polarity(&bus->chipco, BIT(gpio), val);
112*4882a593Smuzhiyun ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), BIT(gpio));
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun static struct irq_chip ssb_gpio_irq_chipco_chip = {
116*4882a593Smuzhiyun .name = "SSB-GPIO-CC",
117*4882a593Smuzhiyun .irq_mask = ssb_gpio_irq_chipco_mask,
118*4882a593Smuzhiyun .irq_unmask = ssb_gpio_irq_chipco_unmask,
119*4882a593Smuzhiyun };
120*4882a593Smuzhiyun
ssb_gpio_irq_chipco_handler(int irq,void * dev_id)121*4882a593Smuzhiyun static irqreturn_t ssb_gpio_irq_chipco_handler(int irq, void *dev_id)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun struct ssb_bus *bus = dev_id;
124*4882a593Smuzhiyun struct ssb_chipcommon *chipco = &bus->chipco;
125*4882a593Smuzhiyun u32 val = chipco_read32(chipco, SSB_CHIPCO_GPIOIN);
126*4882a593Smuzhiyun u32 mask = chipco_read32(chipco, SSB_CHIPCO_GPIOIRQ);
127*4882a593Smuzhiyun u32 pol = chipco_read32(chipco, SSB_CHIPCO_GPIOPOL);
128*4882a593Smuzhiyun unsigned long irqs = (val ^ pol) & mask;
129*4882a593Smuzhiyun int gpio;
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun if (!irqs)
132*4882a593Smuzhiyun return IRQ_NONE;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun for_each_set_bit(gpio, &irqs, bus->gpio.ngpio)
135*4882a593Smuzhiyun generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio));
136*4882a593Smuzhiyun ssb_chipco_gpio_polarity(chipco, irqs, val & irqs);
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun return IRQ_HANDLED;
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun
ssb_gpio_irq_chipco_domain_init(struct ssb_bus * bus)141*4882a593Smuzhiyun static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun struct ssb_chipcommon *chipco = &bus->chipco;
144*4882a593Smuzhiyun struct gpio_chip *chip = &bus->gpio;
145*4882a593Smuzhiyun int gpio, hwirq, err;
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun if (bus->bustype != SSB_BUSTYPE_SSB)
148*4882a593Smuzhiyun return 0;
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
151*4882a593Smuzhiyun &irq_domain_simple_ops, chipco);
152*4882a593Smuzhiyun if (!bus->irq_domain) {
153*4882a593Smuzhiyun err = -ENODEV;
154*4882a593Smuzhiyun goto err_irq_domain;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun for (gpio = 0; gpio < chip->ngpio; gpio++) {
157*4882a593Smuzhiyun int irq = irq_create_mapping(bus->irq_domain, gpio);
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun irq_set_chip_data(irq, bus);
160*4882a593Smuzhiyun irq_set_chip_and_handler(irq, &ssb_gpio_irq_chipco_chip,
161*4882a593Smuzhiyun handle_simple_irq);
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun hwirq = ssb_mips_irq(bus->chipco.dev) + 2;
165*4882a593Smuzhiyun err = request_irq(hwirq, ssb_gpio_irq_chipco_handler, IRQF_SHARED,
166*4882a593Smuzhiyun "gpio", bus);
167*4882a593Smuzhiyun if (err)
168*4882a593Smuzhiyun goto err_req_irq;
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun ssb_chipco_gpio_intmask(&bus->chipco, ~0, 0);
171*4882a593Smuzhiyun chipco_set32(chipco, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO);
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun return 0;
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun err_req_irq:
176*4882a593Smuzhiyun for (gpio = 0; gpio < chip->ngpio; gpio++) {
177*4882a593Smuzhiyun int irq = irq_find_mapping(bus->irq_domain, gpio);
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun irq_dispose_mapping(irq);
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun irq_domain_remove(bus->irq_domain);
182*4882a593Smuzhiyun err_irq_domain:
183*4882a593Smuzhiyun return err;
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun
ssb_gpio_irq_chipco_domain_exit(struct ssb_bus * bus)186*4882a593Smuzhiyun static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun struct ssb_chipcommon *chipco = &bus->chipco;
189*4882a593Smuzhiyun struct gpio_chip *chip = &bus->gpio;
190*4882a593Smuzhiyun int gpio;
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun if (bus->bustype != SSB_BUSTYPE_SSB)
193*4882a593Smuzhiyun return;
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun chipco_mask32(chipco, SSB_CHIPCO_IRQMASK, ~SSB_CHIPCO_IRQ_GPIO);
196*4882a593Smuzhiyun free_irq(ssb_mips_irq(bus->chipco.dev) + 2, chipco);
197*4882a593Smuzhiyun for (gpio = 0; gpio < chip->ngpio; gpio++) {
198*4882a593Smuzhiyun int irq = irq_find_mapping(bus->irq_domain, gpio);
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun irq_dispose_mapping(irq);
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun irq_domain_remove(bus->irq_domain);
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun #else
ssb_gpio_irq_chipco_domain_init(struct ssb_bus * bus)205*4882a593Smuzhiyun static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun return 0;
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun
ssb_gpio_irq_chipco_domain_exit(struct ssb_bus * bus)210*4882a593Smuzhiyun static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus)
211*4882a593Smuzhiyun {
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun #endif
214*4882a593Smuzhiyun
ssb_gpio_chipco_init(struct ssb_bus * bus)215*4882a593Smuzhiyun static int ssb_gpio_chipco_init(struct ssb_bus *bus)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun struct gpio_chip *chip = &bus->gpio;
218*4882a593Smuzhiyun int err;
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun chip->label = "ssb_chipco_gpio";
221*4882a593Smuzhiyun chip->owner = THIS_MODULE;
222*4882a593Smuzhiyun chip->request = ssb_gpio_chipco_request;
223*4882a593Smuzhiyun chip->free = ssb_gpio_chipco_free;
224*4882a593Smuzhiyun chip->get = ssb_gpio_chipco_get_value;
225*4882a593Smuzhiyun chip->set = ssb_gpio_chipco_set_value;
226*4882a593Smuzhiyun chip->direction_input = ssb_gpio_chipco_direction_input;
227*4882a593Smuzhiyun chip->direction_output = ssb_gpio_chipco_direction_output;
228*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SSB_EMBEDDED)
229*4882a593Smuzhiyun chip->to_irq = ssb_gpio_to_irq;
230*4882a593Smuzhiyun #endif
231*4882a593Smuzhiyun chip->ngpio = 16;
232*4882a593Smuzhiyun /* There is just one SoC in one device and its GPIO addresses should be
233*4882a593Smuzhiyun * deterministic to address them more easily. The other buses could get
234*4882a593Smuzhiyun * a random base number. */
235*4882a593Smuzhiyun if (bus->bustype == SSB_BUSTYPE_SSB)
236*4882a593Smuzhiyun chip->base = 0;
237*4882a593Smuzhiyun else
238*4882a593Smuzhiyun chip->base = -1;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun err = ssb_gpio_irq_chipco_domain_init(bus);
241*4882a593Smuzhiyun if (err)
242*4882a593Smuzhiyun return err;
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun err = gpiochip_add_data(chip, bus);
245*4882a593Smuzhiyun if (err) {
246*4882a593Smuzhiyun ssb_gpio_irq_chipco_domain_exit(bus);
247*4882a593Smuzhiyun return err;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun return 0;
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun /**************************************************
254*4882a593Smuzhiyun * EXTIF
255*4882a593Smuzhiyun **************************************************/
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun #ifdef CONFIG_SSB_DRIVER_EXTIF
258*4882a593Smuzhiyun
ssb_gpio_extif_get_value(struct gpio_chip * chip,unsigned int gpio)259*4882a593Smuzhiyun static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned int gpio)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun struct ssb_bus *bus = gpiochip_get_data(chip);
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun return !!ssb_extif_gpio_in(&bus->extif, 1 << gpio);
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun
ssb_gpio_extif_set_value(struct gpio_chip * chip,unsigned int gpio,int value)266*4882a593Smuzhiyun static void ssb_gpio_extif_set_value(struct gpio_chip *chip, unsigned int gpio,
267*4882a593Smuzhiyun int value)
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun struct ssb_bus *bus = gpiochip_get_data(chip);
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
ssb_gpio_extif_direction_input(struct gpio_chip * chip,unsigned int gpio)274*4882a593Smuzhiyun static int ssb_gpio_extif_direction_input(struct gpio_chip *chip,
275*4882a593Smuzhiyun unsigned int gpio)
276*4882a593Smuzhiyun {
277*4882a593Smuzhiyun struct ssb_bus *bus = gpiochip_get_data(chip);
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 0);
280*4882a593Smuzhiyun return 0;
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun
ssb_gpio_extif_direction_output(struct gpio_chip * chip,unsigned int gpio,int value)283*4882a593Smuzhiyun static int ssb_gpio_extif_direction_output(struct gpio_chip *chip,
284*4882a593Smuzhiyun unsigned int gpio, int value)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun struct ssb_bus *bus = gpiochip_get_data(chip);
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 1 << gpio);
289*4882a593Smuzhiyun ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);
290*4882a593Smuzhiyun return 0;
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SSB_EMBEDDED)
ssb_gpio_irq_extif_mask(struct irq_data * d)294*4882a593Smuzhiyun static void ssb_gpio_irq_extif_mask(struct irq_data *d)
295*4882a593Smuzhiyun {
296*4882a593Smuzhiyun struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
297*4882a593Smuzhiyun int gpio = irqd_to_hwirq(d);
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), 0);
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun
ssb_gpio_irq_extif_unmask(struct irq_data * d)302*4882a593Smuzhiyun static void ssb_gpio_irq_extif_unmask(struct irq_data *d)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
305*4882a593Smuzhiyun int gpio = irqd_to_hwirq(d);
306*4882a593Smuzhiyun u32 val = ssb_extif_gpio_in(&bus->extif, BIT(gpio));
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun ssb_extif_gpio_polarity(&bus->extif, BIT(gpio), val);
309*4882a593Smuzhiyun ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), BIT(gpio));
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun static struct irq_chip ssb_gpio_irq_extif_chip = {
313*4882a593Smuzhiyun .name = "SSB-GPIO-EXTIF",
314*4882a593Smuzhiyun .irq_mask = ssb_gpio_irq_extif_mask,
315*4882a593Smuzhiyun .irq_unmask = ssb_gpio_irq_extif_unmask,
316*4882a593Smuzhiyun };
317*4882a593Smuzhiyun
ssb_gpio_irq_extif_handler(int irq,void * dev_id)318*4882a593Smuzhiyun static irqreturn_t ssb_gpio_irq_extif_handler(int irq, void *dev_id)
319*4882a593Smuzhiyun {
320*4882a593Smuzhiyun struct ssb_bus *bus = dev_id;
321*4882a593Smuzhiyun struct ssb_extif *extif = &bus->extif;
322*4882a593Smuzhiyun u32 val = ssb_read32(extif->dev, SSB_EXTIF_GPIO_IN);
323*4882a593Smuzhiyun u32 mask = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTMASK);
324*4882a593Smuzhiyun u32 pol = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTPOL);
325*4882a593Smuzhiyun unsigned long irqs = (val ^ pol) & mask;
326*4882a593Smuzhiyun int gpio;
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun if (!irqs)
329*4882a593Smuzhiyun return IRQ_NONE;
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun for_each_set_bit(gpio, &irqs, bus->gpio.ngpio)
332*4882a593Smuzhiyun generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio));
333*4882a593Smuzhiyun ssb_extif_gpio_polarity(extif, irqs, val & irqs);
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun return IRQ_HANDLED;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun
ssb_gpio_irq_extif_domain_init(struct ssb_bus * bus)338*4882a593Smuzhiyun static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun struct ssb_extif *extif = &bus->extif;
341*4882a593Smuzhiyun struct gpio_chip *chip = &bus->gpio;
342*4882a593Smuzhiyun int gpio, hwirq, err;
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun if (bus->bustype != SSB_BUSTYPE_SSB)
345*4882a593Smuzhiyun return 0;
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
348*4882a593Smuzhiyun &irq_domain_simple_ops, extif);
349*4882a593Smuzhiyun if (!bus->irq_domain) {
350*4882a593Smuzhiyun err = -ENODEV;
351*4882a593Smuzhiyun goto err_irq_domain;
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun for (gpio = 0; gpio < chip->ngpio; gpio++) {
354*4882a593Smuzhiyun int irq = irq_create_mapping(bus->irq_domain, gpio);
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun irq_set_chip_data(irq, bus);
357*4882a593Smuzhiyun irq_set_chip_and_handler(irq, &ssb_gpio_irq_extif_chip,
358*4882a593Smuzhiyun handle_simple_irq);
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun hwirq = ssb_mips_irq(bus->extif.dev) + 2;
362*4882a593Smuzhiyun err = request_irq(hwirq, ssb_gpio_irq_extif_handler, IRQF_SHARED,
363*4882a593Smuzhiyun "gpio", bus);
364*4882a593Smuzhiyun if (err)
365*4882a593Smuzhiyun goto err_req_irq;
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun ssb_extif_gpio_intmask(&bus->extif, ~0, 0);
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun return 0;
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun err_req_irq:
372*4882a593Smuzhiyun for (gpio = 0; gpio < chip->ngpio; gpio++) {
373*4882a593Smuzhiyun int irq = irq_find_mapping(bus->irq_domain, gpio);
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun irq_dispose_mapping(irq);
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun irq_domain_remove(bus->irq_domain);
378*4882a593Smuzhiyun err_irq_domain:
379*4882a593Smuzhiyun return err;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun
ssb_gpio_irq_extif_domain_exit(struct ssb_bus * bus)382*4882a593Smuzhiyun static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
383*4882a593Smuzhiyun {
384*4882a593Smuzhiyun struct ssb_extif *extif = &bus->extif;
385*4882a593Smuzhiyun struct gpio_chip *chip = &bus->gpio;
386*4882a593Smuzhiyun int gpio;
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun if (bus->bustype != SSB_BUSTYPE_SSB)
389*4882a593Smuzhiyun return;
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun free_irq(ssb_mips_irq(bus->extif.dev) + 2, extif);
392*4882a593Smuzhiyun for (gpio = 0; gpio < chip->ngpio; gpio++) {
393*4882a593Smuzhiyun int irq = irq_find_mapping(bus->irq_domain, gpio);
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun irq_dispose_mapping(irq);
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun irq_domain_remove(bus->irq_domain);
398*4882a593Smuzhiyun }
399*4882a593Smuzhiyun #else
ssb_gpio_irq_extif_domain_init(struct ssb_bus * bus)400*4882a593Smuzhiyun static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
401*4882a593Smuzhiyun {
402*4882a593Smuzhiyun return 0;
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun
ssb_gpio_irq_extif_domain_exit(struct ssb_bus * bus)405*4882a593Smuzhiyun static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun #endif
409*4882a593Smuzhiyun
ssb_gpio_extif_init(struct ssb_bus * bus)410*4882a593Smuzhiyun static int ssb_gpio_extif_init(struct ssb_bus *bus)
411*4882a593Smuzhiyun {
412*4882a593Smuzhiyun struct gpio_chip *chip = &bus->gpio;
413*4882a593Smuzhiyun int err;
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun chip->label = "ssb_extif_gpio";
416*4882a593Smuzhiyun chip->owner = THIS_MODULE;
417*4882a593Smuzhiyun chip->get = ssb_gpio_extif_get_value;
418*4882a593Smuzhiyun chip->set = ssb_gpio_extif_set_value;
419*4882a593Smuzhiyun chip->direction_input = ssb_gpio_extif_direction_input;
420*4882a593Smuzhiyun chip->direction_output = ssb_gpio_extif_direction_output;
421*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SSB_EMBEDDED)
422*4882a593Smuzhiyun chip->to_irq = ssb_gpio_to_irq;
423*4882a593Smuzhiyun #endif
424*4882a593Smuzhiyun chip->ngpio = 5;
425*4882a593Smuzhiyun /* There is just one SoC in one device and its GPIO addresses should be
426*4882a593Smuzhiyun * deterministic to address them more easily. The other buses could get
427*4882a593Smuzhiyun * a random base number. */
428*4882a593Smuzhiyun if (bus->bustype == SSB_BUSTYPE_SSB)
429*4882a593Smuzhiyun chip->base = 0;
430*4882a593Smuzhiyun else
431*4882a593Smuzhiyun chip->base = -1;
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun err = ssb_gpio_irq_extif_domain_init(bus);
434*4882a593Smuzhiyun if (err)
435*4882a593Smuzhiyun return err;
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun err = gpiochip_add_data(chip, bus);
438*4882a593Smuzhiyun if (err) {
439*4882a593Smuzhiyun ssb_gpio_irq_extif_domain_exit(bus);
440*4882a593Smuzhiyun return err;
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun return 0;
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun #else
ssb_gpio_extif_init(struct ssb_bus * bus)447*4882a593Smuzhiyun static int ssb_gpio_extif_init(struct ssb_bus *bus)
448*4882a593Smuzhiyun {
449*4882a593Smuzhiyun return -ENOTSUPP;
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun #endif
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun /**************************************************
454*4882a593Smuzhiyun * Init
455*4882a593Smuzhiyun **************************************************/
456*4882a593Smuzhiyun
ssb_gpio_init(struct ssb_bus * bus)457*4882a593Smuzhiyun int ssb_gpio_init(struct ssb_bus *bus)
458*4882a593Smuzhiyun {
459*4882a593Smuzhiyun if (ssb_chipco_available(&bus->chipco))
460*4882a593Smuzhiyun return ssb_gpio_chipco_init(bus);
461*4882a593Smuzhiyun else if (ssb_extif_available(&bus->extif))
462*4882a593Smuzhiyun return ssb_gpio_extif_init(bus);
463*4882a593Smuzhiyun return -1;
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun
ssb_gpio_unregister(struct ssb_bus * bus)466*4882a593Smuzhiyun int ssb_gpio_unregister(struct ssb_bus *bus)
467*4882a593Smuzhiyun {
468*4882a593Smuzhiyun if (ssb_chipco_available(&bus->chipco) ||
469*4882a593Smuzhiyun ssb_extif_available(&bus->extif)) {
470*4882a593Smuzhiyun gpiochip_remove(&bus->gpio);
471*4882a593Smuzhiyun return 0;
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun return -1;
474*4882a593Smuzhiyun }
475