static int gb_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); return gb_gpio_direction_out_operation(ggc, (u8)offset, !!value); }
static void gb_gpio_irq_bus_lock(struct irq_data *d) { struct gpio_chip *chip = irq_data_to_gpio_chip(d); struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); mutex_lock(&ggc->irq_lock); }
static void gb_gpio_irq_unmask(struct irq_data *d) { struct gpio_chip *chip = irq_data_to_gpio_chip(d); struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); struct gb_gpio_line *line = &ggc->lines[d->hwirq]; line->masked = false; line->masked_pending = true; }
static int gb_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, unsigned debounce) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); u16 usec; if (debounce > U16_MAX) return -EINVAL; usec = (u16)debounce; return gb_gpio_set_debounce_operation(ggc, (u8)offset, usec); }
static int gb_gpio_get(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); u8 which; int ret; which = (u8)offset; ret = gb_gpio_get_value_operation(ggc, which); if (ret) return ret; return ggc->lines[which].value; }
static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); u8 which; int ret; which = (u8)offset; ret = gb_gpio_get_direction_operation(ggc, which); if (ret) return ret; return ggc->lines[which].direction ? 1 : 0; }
static int gb_gpio_set_config(struct gpio_chip *chip, unsigned int offset, unsigned long config) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); u32 debounce; if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) return -ENOTSUPP; debounce = pinconf_to_config_argument(config); if (debounce > U16_MAX) return -EINVAL; return gb_gpio_set_debounce_operation(ggc, (u8)offset, (u16)debounce); }
/** * gb_gpio_irq_map() - maps an IRQ into a GB gpio irqchip * @d: the irqdomain used by this irqchip * @irq: the global irq number used by this GB gpio irqchip irq * @hwirq: the local IRQ/GPIO line offset on this GB gpio * * This function will set up the mapping for a certain IRQ line on a * GB gpio by assigning the GB gpio as chip data, and using the irqchip * stored inside the GB gpio. */ static int gb_gpio_irq_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq) { struct gpio_chip *chip = domain->host_data; struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); irq_set_chip_data(irq, ggc); irq_set_chip_and_handler(irq, ggc->irqchip, ggc->irq_handler); irq_set_noprobe(irq); /* * No set-up of the hardware will happen if IRQ_TYPE_NONE * is passed as default type. */ if (ggc->irq_default_type != IRQ_TYPE_NONE) irq_set_irq_type(irq, ggc->irq_default_type); return 0; }
static void gb_gpio_irq_bus_sync_unlock(struct irq_data *d) { struct gpio_chip *chip = irq_data_to_gpio_chip(d); struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); struct gb_gpio_line *line = &ggc->lines[d->hwirq]; if (line->irq_type_pending) { _gb_gpio_irq_set_type(ggc, d->hwirq, line->irq_type); line->irq_type_pending = false; } if (line->masked_pending) { if (line->masked) _gb_gpio_irq_mask(ggc, d->hwirq); else _gb_gpio_irq_unmask(ggc, d->hwirq); line->masked_pending = false; } mutex_unlock(&ggc->irq_lock); }
/** * gb_gpio_irqchip_add() - adds an irqchip to a gpio chip * @chip: the gpio chip to add the irqchip to * @irqchip: the irqchip to add to the adapter * @first_irq: if not dynamically assigned, the base (first) IRQ to * allocate gpio irqs from * @handler: the irq handler to use (often a predefined irq core function) * @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE * to have the core avoid setting up any default type in the hardware. * * This function closely associates a certain irqchip with a certain * gpio chip, providing an irq domain to translate the local IRQs to * global irqs, and making sure that the gpio chip * is passed as chip data to all related functions. Driver callbacks * need to use container_of() to get their local state containers back * from the gpio chip passed as chip data. An irqdomain will be stored * in the gpio chip that shall be used by the driver to handle IRQ number * translation. The gpio chip will need to be initialized and registered * before calling this function. */ static int gb_gpio_irqchip_add(struct gpio_chip *chip, struct irq_chip *irqchip, unsigned int first_irq, irq_flow_handler_t handler, unsigned int type) { struct gb_gpio_controller *ggc; unsigned int offset; unsigned int irq_base; if (!chip || !irqchip) return -EINVAL; ggc = gpio_chip_to_gb_gpio_controller(chip); ggc->irqchip = irqchip; ggc->irq_handler = handler; ggc->irq_default_type = type; ggc->irqdomain = irq_domain_add_simple(NULL, ggc->line_max + 1, first_irq, &gb_gpio_domain_ops, chip); if (!ggc->irqdomain) { ggc->irqchip = NULL; return -EINVAL; } /* * Prepare the mapping since the irqchip shall be orthogonal to * any gpio calls. If the first_irq was zero, this is * necessary to allocate descriptors for all IRQs. */ for (offset = 0; offset < (ggc->line_max + 1); offset++) { irq_base = irq_create_mapping(ggc->irqdomain, offset); if (offset == 0) ggc->irq_base = irq_base; } return 0; }
static int gb_gpio_irq_set_type(struct irq_data *d, unsigned int type) { struct gpio_chip *chip = irq_data_to_gpio_chip(d); struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); struct gb_gpio_line *line = &ggc->lines[d->hwirq]; struct device *dev = &ggc->gbphy_dev->dev; u8 irq_type; switch (type) { case IRQ_TYPE_NONE: irq_type = GB_GPIO_IRQ_TYPE_NONE; break; case IRQ_TYPE_EDGE_RISING: irq_type = GB_GPIO_IRQ_TYPE_EDGE_RISING; break; case IRQ_TYPE_EDGE_FALLING: irq_type = GB_GPIO_IRQ_TYPE_EDGE_FALLING; break; case IRQ_TYPE_EDGE_BOTH: irq_type = GB_GPIO_IRQ_TYPE_EDGE_BOTH; break; case IRQ_TYPE_LEVEL_LOW: irq_type = GB_GPIO_IRQ_TYPE_LEVEL_LOW; break; case IRQ_TYPE_LEVEL_HIGH: irq_type = GB_GPIO_IRQ_TYPE_LEVEL_HIGH; break; default: dev_err(dev, "unsupported irq type: %u\n", type); return -EINVAL; } line->irq_type = irq_type; line->irq_type_pending = true; return 0; }
static int gb_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); return irq_find_mapping(ggc->irqdomain, offset); }
static void gb_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); gb_gpio_set_value_operation(ggc, (u8)offset, !!value); }
static int gb_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); return gb_gpio_direction_in_operation(ggc, (u8)offset); }
static void gb_gpio_free(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); gb_gpio_deactivate_operation(ggc, (u8)offset); }
static int gb_gpio_request(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); return gb_gpio_activate_operation(ggc, (u8)offset); }