--- zzzz-none-000/linux-3.10.107/drivers/pinctrl/pinctrl-coh901.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/pinctrl/pinctrl-coh901.c 2021-02-04 17:41:59.000000000 +0000 @@ -8,21 +8,17 @@ * Author: Jonas Aaberg */ #include -#include #include #include #include #include -#include #include #include #include #include -#include #include #include #include -#include #include "pinctrl-coh901.h" #define U300_GPIO_PORT_STRIDE (0x30) @@ -58,12 +54,21 @@ #define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL) /* 8 bits per port, no version has more than 7 ports */ +#define U300_GPIO_NUM_PORTS 7 #define U300_GPIO_PINS_PER_PORT 8 -#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * 7) +#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS) + +struct u300_gpio_port { + struct u300_gpio *gpio; + char name[8]; + int irq; + int number; + u8 toggle_edge_mode; +}; struct u300_gpio { struct gpio_chip chip; - struct list_head port_list; + struct u300_gpio_port ports[U300_GPIO_NUM_PORTS]; struct clk *clk; void __iomem *base; struct device *dev; @@ -78,16 +83,6 @@ u32 iev; }; -struct u300_gpio_port { - struct list_head node; - struct u300_gpio *gpio; - char name[8]; - struct irq_domain *domain; - int irq; - int number; - u8 toggle_edge_mode; -}; - /* * Macro to expand to read a specific register found in the "gpio" * struct. It requires the struct u300_gpio *gpio variable to exist in @@ -111,9 +106,6 @@ int outval; }; -/* BS335 has seven ports of 8 bits each = GPIO pins 0..55 */ -#define BS335_GPIO_NUM_PORTS 7 - #define U300_FLOATING_INPUT { \ .bias_mode = PIN_CONFIG_BIAS_HIGH_IMPEDANCE, \ .output = false, \ @@ -136,7 +128,7 @@ /* Initial configuration */ static const struct __initconst u300_gpio_confdata -bs335_gpio_config[BS335_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { +bs335_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { /* Port 0, pins 0-7 */ { U300_FLOATING_INPUT, @@ -225,24 +217,6 @@ return container_of(chip, struct u300_gpio, chip); } -static int u300_gpio_request(struct gpio_chip *chip, unsigned offset) -{ - /* - * Map back to global GPIO space and request muxing, the direction - * parameter does not matter for this controller. - */ - int gpio = chip->base + offset; - - return pinctrl_request_gpio(gpio); -} - -static void u300_gpio_free(struct gpio_chip *chip, unsigned offset) -{ - int gpio = chip->base + offset; - - pinctrl_free_gpio(gpio); -} - static int u300_gpio_get(struct gpio_chip *chip, unsigned offset) { struct u300_gpio *gpio = to_u300_gpio(chip); @@ -311,39 +285,6 @@ return 0; } -static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct u300_gpio *gpio = to_u300_gpio(chip); - int portno = offset >> 3; - struct u300_gpio_port *port = NULL; - struct list_head *p; - int retirq; - bool found = false; - - list_for_each(p, &gpio->port_list) { - port = list_entry(p, struct u300_gpio_port, node); - if (port->number == portno) { - found = true; - break; - } - } - if (!found) { - dev_err(gpio->dev, "could not locate port for GPIO %d IRQ\n", - offset); - return -EINVAL; - } - - /* - * The local hwirqs on the port are the lower three bits, there - * are exactly 8 IRQs per port since they are 8-bit - */ - retirq = irq_find_mapping(port->domain, (offset & 0x7)); - - dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d from port %d\n", - offset, retirq, port->number); - return retirq; -} - /* Returning -EINVAL means "supported but not available" */ int u300_gpio_config_get(struct gpio_chip *chip, unsigned offset, @@ -458,13 +399,12 @@ static struct gpio_chip u300_gpio_chip = { .label = "u300-gpio-chip", .owner = THIS_MODULE, - .request = u300_gpio_request, - .free = u300_gpio_free, + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, .get = u300_gpio_get, .set = u300_gpio_set, .direction_input = u300_gpio_direction_input, .direction_output = u300_gpio_direction_output, - .to_irq = u300_gpio_to_irq, }; static void u300_toggle_trigger(struct u300_gpio *gpio, unsigned offset) @@ -488,9 +428,10 @@ static int u300_gpio_irq_type(struct irq_data *d, unsigned trigger) { - struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); - struct u300_gpio *gpio = port->gpio; - int offset = (port->number << 3) + d->hwirq; + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + struct u300_gpio *gpio = to_u300_gpio(chip); + struct u300_gpio_port *port = &gpio->ports[d->hwirq >> 3]; + int offset = d->hwirq; u32 val; if ((trigger & IRQF_TRIGGER_RISING) && @@ -524,9 +465,10 @@ static void u300_gpio_irq_enable(struct irq_data *d) { - struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); - struct u300_gpio *gpio = port->gpio; - int offset = (port->number << 3) + d->hwirq; + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + struct u300_gpio *gpio = to_u300_gpio(chip); + struct u300_gpio_port *port = &gpio->ports[d->hwirq >> 3]; + int offset = d->hwirq; u32 val; unsigned long flags; @@ -540,9 +482,9 @@ static void u300_gpio_irq_disable(struct irq_data *d) { - struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); - struct u300_gpio *gpio = port->gpio; - int offset = (port->number << 3) + d->hwirq; + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + struct u300_gpio *gpio = to_u300_gpio(chip); + int offset = d->hwirq; u32 val; unsigned long flags; @@ -557,17 +499,20 @@ .irq_enable = u300_gpio_irq_enable, .irq_disable = u300_gpio_irq_disable, .irq_set_type = u300_gpio_irq_type, - }; -static void u300_gpio_irq_handler(unsigned irq, struct irq_desc *desc) +static void u300_gpio_irq_handler(struct irq_desc *desc) { - struct u300_gpio_port *port = irq_get_handler_data(irq); - struct u300_gpio *gpio = port->gpio; + unsigned int irq = irq_desc_get_irq(desc); + struct irq_chip *parent_chip = irq_desc_get_chip(desc); + struct gpio_chip *chip = irq_desc_get_handler_data(desc); + struct u300_gpio *gpio = to_u300_gpio(chip); + struct u300_gpio_port *port = &gpio->ports[irq - chip->base]; int pinoffset = port->number << 3; /* get the right stride */ unsigned long val; - desc->irq_data.chip->irq_ack(&desc->irq_data); + chained_irq_enter(parent_chip, desc); + /* Read event register */ val = readl(U300_PIN_REG(pinoffset, iev)); /* Mask relevant bits */ @@ -580,8 +525,8 @@ int irqoffset; for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) { - int pin_irq = irq_find_mapping(port->domain, irqoffset); int offset = pinoffset + irqoffset; + int pin_irq = irq_find_mapping(chip->irqdomain, offset); dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n", pin_irq, offset); @@ -595,7 +540,7 @@ } } - desc->irq_data.chip->irq_unmask(&desc->irq_data); + chained_irq_exit(parent_chip, desc); } static void __init u300_gpio_init_pin(struct u300_gpio *gpio, @@ -630,13 +575,12 @@ } } -static void __init u300_gpio_init_coh901571(struct u300_gpio *gpio, - struct u300_gpio_platform *plat) +static void __init u300_gpio_init_coh901571(struct u300_gpio *gpio) { int i, j; /* Write default config and values to all pins */ - for (i = 0; i < plat->ports; i++) { + for (i = 0; i < U300_GPIO_NUM_PORTS; i++) { for (j = 0; j < 8; j++) { const struct u300_gpio_confdata *conf; int offset = (i*8) + j; @@ -647,20 +591,6 @@ } } -static inline void u300_gpio_free_ports(struct u300_gpio *gpio) -{ - struct u300_gpio_port *port; - struct list_head *p, *n; - - list_for_each_safe(p, n, &gpio->port_list) { - port = list_entry(p, struct u300_gpio_port, node); - list_del(&port->node); - if (port->domain) - irq_domain_remove(port->domain); - kfree(port); - } -} - /* * Here we map a GPIO in the local gpio_chip pin space to a pin in * the local pinctrl pin space. The pin controller used is @@ -693,7 +623,6 @@ static int __init u300_gpio_probe(struct platform_device *pdev) { - struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); struct u300_gpio *gpio; struct resource *memres; int err = 0; @@ -707,9 +636,9 @@ return -ENOMEM; gpio->chip = u300_gpio_chip; - gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT; + gpio->chip.ngpio = U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT; gpio->chip.dev = &pdev->dev; - gpio->chip.base = plat->gpio_base; + gpio->chip.base = 0; gpio->dev = &pdev->dev; memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -750,68 +679,47 @@ ((val & 0x0000FE00) >> 9) * 8); writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, gpio->base + U300_GPIO_CR); - u300_gpio_init_coh901571(gpio, plat); + u300_gpio_init_coh901571(gpio); + +#ifdef CONFIG_OF_GPIO + gpio->chip.of_node = pdev->dev.of_node; +#endif + err = gpiochip_add(&gpio->chip); + if (err) { + dev_err(gpio->dev, "unable to add gpiochip: %d\n", err); + goto err_no_chip; + } + + err = gpiochip_irqchip_add(&gpio->chip, + &u300_gpio_irqchip, + 0, + handle_simple_irq, + IRQ_TYPE_EDGE_FALLING); + if (err) { + dev_err(gpio->dev, "no GPIO irqchip\n"); + goto err_no_irqchip; + } /* Add each port with its IRQ separately */ - INIT_LIST_HEAD(&gpio->port_list); - for (portno = 0 ; portno < plat->ports; portno++) { - struct u300_gpio_port *port = - kmalloc(sizeof(struct u300_gpio_port), GFP_KERNEL); - - if (!port) { - dev_err(gpio->dev, "out of memory\n"); - err = -ENOMEM; - goto err_no_port; - } + for (portno = 0 ; portno < U300_GPIO_NUM_PORTS; portno++) { + struct u300_gpio_port *port = &gpio->ports[portno]; snprintf(port->name, 8, "gpio%d", portno); port->number = portno; port->gpio = gpio; - port->irq = platform_get_irq_byname(pdev, - port->name); - - dev_dbg(gpio->dev, "register IRQ %d for port %s\n", port->irq, - port->name); - - port->domain = irq_domain_add_linear(pdev->dev.of_node, - U300_GPIO_PINS_PER_PORT, - &irq_domain_simple_ops, - port); - if (!port->domain) { - err = -ENOMEM; - goto err_no_domain; - } - - irq_set_chained_handler(port->irq, u300_gpio_irq_handler); - irq_set_handler_data(port->irq, port); + port->irq = platform_get_irq(pdev, portno); - /* For each GPIO pin set the unique IRQ handler */ - for (i = 0; i < U300_GPIO_PINS_PER_PORT; i++) { - int irqno = irq_create_mapping(port->domain, i); - - dev_dbg(gpio->dev, "GPIO%d on port %s gets IRQ %d\n", - gpio->chip.base + (port->number << 3) + i, - port->name, irqno); - irq_set_chip_and_handler(irqno, &u300_gpio_irqchip, - handle_simple_irq); - set_irq_flags(irqno, IRQF_VALID); - irq_set_chip_data(irqno, port); - } + gpiochip_set_chained_irqchip(&gpio->chip, + &u300_gpio_irqchip, + port->irq, + u300_gpio_irq_handler); /* Turns off irq force (test register) for this port */ writel(0x0, gpio->base + portno * gpio->stride + ifr); - - list_add_tail(&port->node, &gpio->port_list); } dev_dbg(gpio->dev, "initialized %d GPIO ports\n", portno); - err = gpiochip_add(&gpio->chip); - if (err) { - dev_err(gpio->dev, "unable to add gpiochip: %d\n", err); - goto err_no_chip; - } - /* * Add pinctrl pin ranges, the pin controller must be registered * at this point @@ -830,12 +738,9 @@ return 0; err_no_range: - if (gpiochip_remove(&gpio->chip)) - dev_err(&pdev->dev, "failed to remove gpio chip\n"); +err_no_irqchip: + gpiochip_remove(&gpio->chip); err_no_chip: -err_no_domain: -err_no_port: - u300_gpio_free_ports(gpio); clk_disable_unprepare(gpio->clk); dev_err(&pdev->dev, "module ERROR:%d\n", err); return err; @@ -844,25 +749,24 @@ static int __exit u300_gpio_remove(struct platform_device *pdev) { struct u300_gpio *gpio = platform_get_drvdata(pdev); - int err; /* Turn off the GPIO block */ writel(0x00000000U, gpio->base + U300_GPIO_CR); - err = gpiochip_remove(&gpio->chip); - if (err < 0) { - dev_err(gpio->dev, "unable to remove gpiochip: %d\n", err); - return err; - } - u300_gpio_free_ports(gpio); + gpiochip_remove(&gpio->chip); clk_disable_unprepare(gpio->clk); - platform_set_drvdata(pdev, NULL); return 0; } +static const struct of_device_id u300_gpio_match[] = { + { .compatible = "stericsson,gpio-coh901" }, + {}, +}; + static struct platform_driver u300_gpio_driver = { .driver = { .name = "u300-gpio", + .of_match_table = u300_gpio_match, }, .remove = __exit_p(u300_gpio_remove), };