Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }