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