From 820c36ffa9717cc4a37d49afac6d1fbdbc4aa49f Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Mon, 24 Aug 2020 15:59:45 +0800 Subject: [PATCH] pinctrl: rockchip: remove gpiochip related codes Remove gpiochip related codes from pinctrl driver, but populate gpio platform devices from device tree data. Change-Id: I347acaac2998a972e4c3be5c8827f77f468a7ad2 Signed-off-by: Jianqun Xu --- drivers/pinctrl/pinctrl-rockchip.c | 859 +---------------------------- 1 file changed, 6 insertions(+), 853 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 7f0ac0012347..fe02d1192764 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -47,56 +47,6 @@ #include "core.h" #include "pinconf.h" -struct rockchip_gpio_regs { - u32 port_dr; - u32 port_ddr; - u32 int_en; - u32 int_mask; - u32 int_type; - u32 int_polarity; - u32 int_bothedge; - u32 int_status; - u32 int_rawstatus; - u32 debounce; - u32 dbclk_div_en; - u32 dbclk_div_con; - u32 port_eoi; - u32 ext_port; - u32 version_id; -}; - -static const struct rockchip_gpio_regs gpio_regs_v1 = { - .port_dr = 0x00, - .port_ddr = 0x04, - .int_en = 0x30, - .int_mask = 0x34, - .int_type = 0x38, - .int_polarity = 0x3c, - .int_status = 0x40, - .int_rawstatus = 0x44, - .debounce = 0x48, - .port_eoi = 0x4c, - .ext_port = 0x50, -}; - -static const struct rockchip_gpio_regs gpio_regs_v2 = { - .port_dr = 0x00, - .port_ddr = 0x08, - .int_en = 0x10, - .int_mask = 0x18, - .int_type = 0x20, - .int_polarity = 0x28, - .int_bothedge = 0x30, - .int_status = 0x50, - .int_rawstatus = 0x58, - .debounce = 0x38, - .dbclk_div_en = 0x40, - .dbclk_div_con = 0x48, - .port_eoi = 0x60, - .ext_port = 0x70, - .version_id = 0x78, -}; - enum rockchip_pinctrl_type { PX30, RV1108, @@ -115,9 +65,6 @@ enum rockchip_pinctrl_type { #define RK_GENMASK_VAL(h, l, v) \ (GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l)))) -#define GPIO_TYPE_V1 (0) /* GPIO Version ID reserved */ -#define GPIO_TYPE_V2 (0x01000C2B) /* GPIO Version ID 0x01000C2B */ - /** * Encode variants of iomux registers into a type variable */ @@ -519,81 +466,6 @@ static struct regmap_config rockchip_regmap_config = { .reg_stride = 4, }; -static inline void gpio_writel_v2(u32 val, void __iomem *reg) -{ - writel((val & 0xffff) | 0xffff0000, reg); - writel((val >> 16) | 0xffff0000, reg + 0x4); -} - -static inline u32 gpio_readl_v2(void __iomem *reg) -{ - return readl(reg + 0x4) << 16 | readl(reg); -} - -static inline void rockchip_gpio_writel(struct rockchip_pin_bank *bank, - u32 value, unsigned int offset) -{ - void __iomem *reg = bank->reg_base + offset; - - if (bank->gpio_type == GPIO_TYPE_V2) - gpio_writel_v2(value, reg); - else - writel(value, reg); -} - -static inline u32 rockchip_gpio_readl(struct rockchip_pin_bank *bank, - unsigned int offset) -{ - void __iomem *reg = bank->reg_base + offset; - u32 value; - - if (bank->gpio_type == GPIO_TYPE_V2) - value = gpio_readl_v2(reg); - else - value = readl(reg); - - return value; -} - -static inline void rockchip_gpio_writel_bit(struct rockchip_pin_bank *bank, - u32 bit, u32 value, - unsigned int offset) -{ - void __iomem *reg = bank->reg_base + offset; - u32 data; - - if (bank->gpio_type == GPIO_TYPE_V2) { - if (value) - data = BIT(bit % 16) | BIT(bit % 16 + 16); - else - data = BIT(bit % 16 + 16); - writel(data, bit >= 16 ? reg + 0x4 : reg); - } else { - data = readl(reg); - data &= ~BIT(bit); - if (value) - data |= BIT(bit); - writel(data, reg); - } -} - -static inline u32 rockchip_gpio_readl_bit(struct rockchip_pin_bank *bank, - u32 bit, unsigned int offset) -{ - void __iomem *reg = bank->reg_base + offset; - u32 data; - - if (bank->gpio_type == GPIO_TYPE_V2) { - data = readl(bit >= 16 ? reg + 0x4 : reg); - data >>= bit % 16; - } else { - data = readl(reg); - data >>= bit; - } - - return data & (0x1); -} - static inline const struct rockchip_pin_group *pinctrl_name_to_group( const struct rockchip_pinctrl *info, const char *name) @@ -1988,61 +1860,6 @@ rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, return data->route_type; } -static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) -{ - struct rockchip_pinctrl *info = bank->drvdata; - int iomux_num = (pin / 8); - struct regmap *regmap; - unsigned int val; - int reg, ret, mask, mux_type; - u8 bit; - - if (iomux_num > 3) - return -EINVAL; - - if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { - dev_err(info->dev, "pin %d is unrouted\n", pin); - return -EINVAL; - } - - if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) - return RK_FUNC_GPIO; - - if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) - regmap = info->regmap_pmu; - else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU) - regmap = (pin % 8 < 4) ? info->regmap_pmu : info->regmap_base; - else - regmap = info->regmap_base; - - /* get basic quadrupel of mux registers and the correct reg inside */ - mux_type = bank->iomux[iomux_num].type; - reg = bank->iomux[iomux_num].offset; - if (mux_type & IOMUX_WIDTH_4BIT) { - if ((pin % 8) >= 4) - reg += 0x4; - bit = (pin % 4) * 4; - mask = 0xf; - } else if (mux_type & IOMUX_WIDTH_3BIT) { - if ((pin % 8) >= 5) - reg += 0x4; - bit = (pin % 8 % 5) * 3; - mask = 0x7; - } else { - bit = (pin % 8) * 2; - mask = 0x3; - } - - if (bank->recalced_mask & BIT(pin)) - rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); - - ret = regmap_read(regmap, reg, &val); - if (ret) - return ret; - - return ((val >> bit) & mask); -} - static int rockchip_verify_mux(struct rockchip_pin_bank *bank, int pin, int mux) { @@ -3426,72 +3243,11 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -static int rockchip_gpio_get_direction(struct gpio_chip *chip, unsigned offset) -{ - struct rockchip_pin_bank *bank = gpiochip_get_data(chip); - u32 data; - - data = rockchip_gpio_readl_bit(bank, offset, bank->gpio_regs->port_ddr); - - return !data; -} - -/* - * The calls to gpio_direction_output() and gpio_direction_input() - * leads to this function call (via the pinctrl_gpio_direction_{input|output}() - * function called from the gpiolib interface). - */ -static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip, - int pin, bool input) -{ - struct rockchip_pin_bank *bank; - int ret; - unsigned long flags; - - bank = gpiochip_get_data(chip); - - ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO); - if (ret < 0) - return ret; - - raw_spin_lock_irqsave(&bank->slock, flags); - - /* set bit to 1 for output, 0 for input */ - rockchip_gpio_writel_bit(bank, pin, (u32)!input, - bank->gpio_regs->port_ddr); - - raw_spin_unlock_irqrestore(&bank->slock, flags); - - return 0; -} - -static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, - unsigned offset, bool input) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - struct rockchip_pin_bank *bank = &info->ctrl->pin_banks[offset / 32]; - struct gpio_chip *chip; - int pin; - - if (!bank || !bank->valid) - return 0; - - chip = range->gc; - pin = offset - chip->base; - dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", - offset, range->name, pin, input ? "input" : "output"); - - return _rockchip_pmx_gpio_set_direction(chip, offset - chip->base, - input); -} - static const struct pinmux_ops rockchip_pmx_ops = { .get_functions_count = rockchip_pmx_get_funcs_count, .get_function_name = rockchip_pmx_get_func_name, .get_function_groups = rockchip_pmx_get_groups, .set_mux = rockchip_pmx_set, - .gpio_set_direction = rockchip_pmx_gpio_set_direction, }; /* @@ -3523,9 +3279,6 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, return false; } -static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value); -static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset); - /* set the pin config settings for a specified pin */ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *configs, unsigned num_configs) @@ -3563,17 +3316,6 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, if (rc) return rc; break; - case PIN_CONFIG_OUTPUT: - if (!bank->valid) - return -ENOTSUPP; - - rockchip_gpio_set(&bank->gpio_chip, - pin - bank->pin_base, arg); - rc = _rockchip_pmx_gpio_set_direction(&bank->gpio_chip, - pin - bank->pin_base, false); - if (rc) - return rc; - break; case PIN_CONFIG_DRIVE_STRENGTH: /* rk3288 is the first with per-pin drive-strength */ if (!info->ctrl->drv_calc_reg) @@ -3639,20 +3381,6 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, arg = 1; break; - case PIN_CONFIG_OUTPUT: - if (!bank->valid) - return -ENOTSUPP; - - rc = rockchip_get_mux(bank, pin - bank->pin_base); - if (rc != RK_FUNC_GPIO) - return -EINVAL; - - rc = rockchip_gpio_get(&bank->gpio_chip, pin - bank->pin_base); - if (rc < 0) - return rc; - - arg = rc ? 1 : 0; - break; case PIN_CONFIG_DRIVE_STRENGTH: /* rk3288 is the first with per-pin drive-strength */ if (!info->ctrl->drv_calc_reg) @@ -3930,564 +3658,6 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, return 0; } -/* - * GPIO handling - */ - -static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value) -{ - struct rockchip_pin_bank *bank = gpiochip_get_data(gc); - unsigned long flags; - - raw_spin_lock_irqsave(&bank->slock, flags); - rockchip_gpio_writel_bit(bank, offset, value, bank->gpio_regs->port_dr); - raw_spin_unlock_irqrestore(&bank->slock, flags); -} - -/* - * Returns the level of the pin for input direction and setting of the DR - * register for output gpios. - */ -static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset) -{ - struct rockchip_pin_bank *bank = gpiochip_get_data(gc); - u32 data; - - data = readl(bank->reg_base + bank->gpio_regs->ext_port); - data >>= offset; - data &= 1; - return data; -} - -/* - * gpiolib gpio_direction_input callback function. The setting of the pin - * mux function as 'gpio input' will be handled by the pinctrl subsystem - * interface. - */ -static int rockchip_gpio_direction_input(struct gpio_chip *gc, unsigned offset) -{ - return pinctrl_gpio_direction_input(gc->base + offset); -} - -/* - * gpiolib gpio_direction_output callback function. The setting of the pin - * mux function as 'gpio output' will be handled by the pinctrl subsystem - * interface. - */ -static int rockchip_gpio_direction_output(struct gpio_chip *gc, - unsigned offset, int value) -{ - rockchip_gpio_set(gc, offset, value); - return pinctrl_gpio_direction_output(gc->base + offset); -} - -static int rockchip_gpio_set_debounce(struct gpio_chip *gc, - unsigned int offset, unsigned int debounce) -{ - struct rockchip_pin_bank *bank = gpiochip_get_data(gc); - const struct rockchip_gpio_regs *reg = bank->gpio_regs; - unsigned long flags, div_reg, freq, max_debounce; - bool div_debounce_support; - unsigned int cur_div_reg; - u64 div; - - if (!IS_ERR(bank->db_clk)) { - div_debounce_support = true; - freq = clk_get_rate(bank->db_clk); - max_debounce = (GENMASK(23, 0) + 1) * 2 * 1000000 / freq; - if (debounce > max_debounce) - return -EINVAL; - - div = debounce * freq; - div_reg = DIV_ROUND_CLOSEST_ULL(div, 2 * USEC_PER_SEC) - 1; - } else { - div_debounce_support = false; - } - - raw_spin_lock_irqsave(&bank->slock, flags); - - /* Only the v1 needs to configure div_en and div_con for dbclk */ - if (debounce) { - if (div_debounce_support) { - /* Configure the max debounce from consumers */ - cur_div_reg = readl(bank->reg_base + reg->dbclk_div_con); - if (cur_div_reg < div_reg) - writel(div_reg, bank->reg_base + reg->dbclk_div_con); - rockchip_gpio_writel_bit(bank, offset, 1, - reg->dbclk_div_en); - } - - rockchip_gpio_writel_bit(bank, offset, 1, reg->debounce); - } else { - if (div_debounce_support) - rockchip_gpio_writel_bit(bank, offset, 0, - reg->dbclk_div_en); - - rockchip_gpio_writel_bit(bank, offset, 0, reg->debounce); - } - - raw_spin_unlock_irqrestore(&bank->slock, flags); - - /* Enable or disable dbclk at last */ - if (div_debounce_support) { - if (debounce) - clk_enable(bank->db_clk); - else - clk_disable(bank->db_clk); - } - - return 0; -} - -/* - * gpiolib set_config callback function. The setting of the pin - * mux function as 'gpio output' will be handled by the pinctrl subsystem - * interface. - */ -static int rockchip_gpio_set_config(struct gpio_chip *gc, unsigned int offset, - unsigned long config) -{ - enum pin_config_param param = pinconf_to_config_param(config); - unsigned int debounce = pinconf_to_config_argument(config); - - switch (param) { - case PIN_CONFIG_INPUT_DEBOUNCE: - rockchip_gpio_set_debounce(gc, offset, debounce); - /* - * Rockchip's gpio could only support up to one period - * of the debounce clock(pclk), which is far away from - * satisftying the requirement, as pclk is usually near - * 100MHz shared by all peripherals. So the fact is it - * has crippled debounce capability could only be useful - * to prevent any spurious glitches from waking up the system - * if the gpio is conguired as wakeup interrupt source. Let's - * still return -ENOTSUPP as before, to make sure the caller - * of gpiod_set_debounce won't change its behaviour. - */ - default: - return -ENOTSUPP; - } -} - -/* - * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin - * and a virtual IRQ, if not already present. - */ -static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned offset) -{ - struct rockchip_pin_bank *bank = gpiochip_get_data(gc); - unsigned int virq; - - if (!bank->domain) - return -ENXIO; - - virq = irq_create_mapping(bank->domain, offset); - - return (virq) ? : -ENXIO; -} - -static const struct gpio_chip rockchip_gpiolib_chip = { - .request = gpiochip_generic_request, - .free = gpiochip_generic_free, - .set = rockchip_gpio_set, - .get = rockchip_gpio_get, - .get_direction = rockchip_gpio_get_direction, - .direction_input = rockchip_gpio_direction_input, - .direction_output = rockchip_gpio_direction_output, - .set_config = rockchip_gpio_set_config, - .to_irq = rockchip_gpio_to_irq, - .owner = THIS_MODULE, -}; - -/* - * Interrupt handling - */ - -static void rockchip_irq_demux(struct irq_desc *desc) -{ - struct irq_chip *chip = irq_desc_get_chip(desc); - struct rockchip_pin_bank *bank = irq_desc_get_handler_data(desc); - const struct rockchip_gpio_regs *reg = bank->gpio_regs; - u32 pend; - - dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); - - chained_irq_enter(chip, desc); - - pend = readl_relaxed(bank->reg_base + reg->int_status); - - while (pend) { - unsigned int irq, virq; - - irq = __ffs(pend); - pend &= ~BIT(irq); - virq = irq_find_mapping(bank->domain, irq); - - if (!virq) { - dev_err(bank->drvdata->dev, "unmapped irq %d\n", irq); - continue; - } - - dev_dbg(bank->drvdata->dev, "handling irq %d\n", irq); - - /* - * Triggering IRQ on both rising and falling edge - * needs manual intervention. - */ - if (bank->toggle_edge_mode & BIT(irq)) { - u32 data, data_old, polarity; - unsigned long flags; - - data = readl_relaxed(bank->reg_base + reg->ext_port); - do { - raw_spin_lock_irqsave(&bank->slock, flags); - - polarity = readl_relaxed(bank->reg_base + - reg->int_polarity); - if (data & BIT(irq)) - polarity &= ~BIT(irq); - else - polarity |= BIT(irq); - writel(polarity, bank->reg_base + - reg->int_polarity); - - raw_spin_unlock_irqrestore(&bank->slock, flags); - - data_old = data; - data = readl_relaxed(bank->reg_base + - reg->ext_port); - } while ((data & BIT(irq)) != (data_old & BIT(irq))); - } - - generic_handle_irq(virq); - } - - chained_irq_exit(chip, desc); -} - -static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - struct rockchip_pin_bank *bank = gc->private; - u32 mask = BIT(d->hwirq); - u32 polarity; - u32 level; - u32 data; - unsigned long flags; - int ret; - - /* make sure the pin is configured as gpio input */ - ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO); - if (ret < 0) - return ret; - - raw_spin_lock_irqsave(&bank->slock, flags); - - rockchip_gpio_writel_bit(bank, d->hwirq, 0, - bank->gpio_regs->port_ddr); - - raw_spin_unlock_irqrestore(&bank->slock, flags); - - if (type & IRQ_TYPE_EDGE_BOTH) - irq_set_handler_locked(d, handle_edge_irq); - else - irq_set_handler_locked(d, handle_level_irq); - - raw_spin_lock_irqsave(&bank->slock, flags); - irq_gc_lock(gc); - - level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type); - polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity); - - switch (type) { - case IRQ_TYPE_EDGE_BOTH: - if (bank->gpio_type == GPIO_TYPE_V2) { - bank->toggle_edge_mode &= ~mask; - rockchip_gpio_writel_bit(bank, d->hwirq, 1, - bank->gpio_regs->int_bothedge); - irq_gc_unlock(gc); - raw_spin_unlock_irqrestore(&bank->slock, flags); - - return 0; - } else { - bank->toggle_edge_mode |= mask; - level |= mask; - - /* - * Determine gpio state. If 1 next interrupt should be falling - * otherwise rising. - */ - data = readl(bank->reg_base + bank->gpio_regs->ext_port); - if (data & mask) - polarity &= ~mask; - else - polarity |= mask; - - break; - } - case IRQ_TYPE_EDGE_RISING: - bank->toggle_edge_mode &= ~mask; - level |= mask; - polarity |= mask; - break; - case IRQ_TYPE_EDGE_FALLING: - bank->toggle_edge_mode &= ~mask; - level |= mask; - polarity &= ~mask; - break; - case IRQ_TYPE_LEVEL_HIGH: - bank->toggle_edge_mode &= ~mask; - level &= ~mask; - polarity |= mask; - break; - case IRQ_TYPE_LEVEL_LOW: - bank->toggle_edge_mode &= ~mask; - level &= ~mask; - polarity &= ~mask; - break; - default: - irq_gc_unlock(gc); - raw_spin_unlock_irqrestore(&bank->slock, flags); - return -EINVAL; - } - - rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type); - rockchip_gpio_writel(bank, polarity, bank->gpio_regs->int_polarity); - - irq_gc_unlock(gc); - raw_spin_unlock_irqrestore(&bank->slock, flags); - - return 0; -} - -static void rockchip_irq_suspend(struct irq_data *d) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - struct rockchip_pin_bank *bank = gc->private; - - bank->saved_masks = irq_reg_readl(gc, bank->gpio_regs->int_mask); - irq_reg_writel(gc, ~gc->wake_active, bank->gpio_regs->int_mask); -} - -static void rockchip_irq_resume(struct irq_data *d) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - struct rockchip_pin_bank *bank = gc->private; - - irq_reg_writel(gc, bank->saved_masks, bank->gpio_regs->int_mask); -} - -static int rockchip_interrupts_register(struct platform_device *pdev, - struct rockchip_pinctrl *info) -{ - struct rockchip_pin_ctrl *ctrl = info->ctrl; - struct rockchip_pin_bank *bank = ctrl->pin_banks; - unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; - struct irq_chip_generic *gc; - int ret; - int i; - - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { - if (!bank->valid) { - dev_warn(&pdev->dev, "bank %s is not valid\n", - bank->name); - continue; - } - - bank->domain = irq_domain_add_linear(bank->of_node, 32, - &irq_generic_chip_ops, NULL); - if (!bank->domain) { - dev_warn(&pdev->dev, "could not initialize irq domain for bank %s\n", - bank->name); - continue; - } - - ret = irq_alloc_domain_generic_chips(bank->domain, 32, 1, - bank->name, handle_level_irq, - clr, 0, 0); - if (ret) { - dev_err(&pdev->dev, "could not alloc generic chips for bank %s\n", - bank->name); - irq_domain_remove(bank->domain); - continue; - } - - gc = irq_get_domain_generic_chip(bank->domain, 0); - if (bank->gpio_type == GPIO_TYPE_V2) { - gc->reg_writel = gpio_writel_v2; - gc->reg_readl = gpio_readl_v2; - } - gc->reg_base = bank->reg_base; - gc->private = bank; - gc->chip_types[0].regs.mask = bank->gpio_regs->int_mask; - gc->chip_types[0].regs.ack = bank->gpio_regs->port_eoi; - gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; - gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; - gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; - gc->chip_types[0].chip.irq_enable = irq_gc_mask_clr_bit; - gc->chip_types[0].chip.irq_disable = irq_gc_mask_set_bit; - gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; - gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend; - gc->chip_types[0].chip.irq_resume = rockchip_irq_resume; - gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; - gc->wake_enabled = IRQ_MSK(bank->nr_pins); - - /* - * Linux assumes that all interrupts start out disabled/masked. - * Our driver only uses the concept of masked and always keeps - * things enabled, so for us that's all masked and all enabled. - */ - rockchip_gpio_writel(bank, 0xffffffff, bank->gpio_regs->int_mask); - rockchip_gpio_writel(bank, 0xffffffff, bank->gpio_regs->int_en); - gc->mask_cache = 0xffffffff; - - irq_set_chained_handler_and_data(bank->irq, - rockchip_irq_demux, bank); - } - - return 0; -} - -static int rockchip_gpiolib_register(struct platform_device *pdev, - struct rockchip_pinctrl *info) -{ - struct rockchip_pin_ctrl *ctrl = info->ctrl; - struct rockchip_pin_bank *bank = ctrl->pin_banks; - struct gpio_chip *gc; - int ret; - int i; - - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { - if (!bank->valid) { - dev_warn(&pdev->dev, "bank %s is not valid\n", - bank->name); - continue; - } - - bank->gpio_chip = rockchip_gpiolib_chip; - - gc = &bank->gpio_chip; - gc->base = bank->pin_base; - gc->ngpio = bank->nr_pins; - gc->parent = &pdev->dev; - gc->of_node = bank->of_node; - gc->label = bank->name; - - ret = gpiochip_add_data(gc, bank); - if (ret) { - dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n", - gc->label, ret); - goto fail; - } - } - - rockchip_interrupts_register(pdev, info); - - return 0; - -fail: - for (--i, --bank; i >= 0; --i, --bank) { - if (!bank->valid) - continue; - gpiochip_remove(&bank->gpio_chip); - } - return ret; -} - -static int rockchip_gpiolib_unregister(struct platform_device *pdev, - struct rockchip_pinctrl *info) -{ - struct rockchip_pin_ctrl *ctrl = info->ctrl; - struct rockchip_pin_bank *bank = ctrl->pin_banks; - int i; - - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { - if (!bank->valid) - continue; - gpiochip_remove(&bank->gpio_chip); - } - - return 0; -} - -static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, - struct rockchip_pinctrl *info) -{ - struct resource res; - void __iomem *base; - u32 ver_reg; - - if (of_address_to_resource(bank->of_node, 0, &res)) { - dev_err(info->dev, "cannot find IO resource for bank\n"); - return -ENOENT; - } - - bank->reg_base = devm_ioremap_resource(info->dev, &res); - if (IS_ERR(bank->reg_base)) - return PTR_ERR(bank->reg_base); - - /* - * special case, where parts of the pull setting-registers are - * part of the PMU register space - */ - if (of_device_is_compatible(bank->of_node, - "rockchip,rk3188-gpio-bank0")) { - struct device_node *node; - - node = of_parse_phandle(bank->of_node->parent, - "rockchip,pmu", 0); - if (!node) { - if (of_address_to_resource(bank->of_node, 1, &res)) { - dev_err(info->dev, "cannot find IO resource for bank\n"); - return -ENOENT; - } - - base = devm_ioremap_resource(info->dev, &res); - if (IS_ERR(base)) - return PTR_ERR(base); - rockchip_regmap_config.max_register = - resource_size(&res) - 4; - rockchip_regmap_config.name = - "rockchip,rk3188-gpio-bank0-pull"; - bank->regmap_pull = devm_regmap_init_mmio(info->dev, - base, - &rockchip_regmap_config); - } - } - - bank->irq = irq_of_parse_and_map(bank->of_node, 0); - - bank->clk = of_clk_get(bank->of_node, 0); - if (IS_ERR(bank->clk)) { - dev_err(info->dev, "cannot find clk\n"); - - return PTR_ERR(bank->clk); - } - - clk_prepare_enable(bank->clk); - - /* If not gpio v2, that is default to v1. */ - ver_reg = gpio_regs_v2.version_id; - if (readl(bank->reg_base + ver_reg) == GPIO_TYPE_V2) { - bank->gpio_regs = &gpio_regs_v2; - bank->gpio_type = GPIO_TYPE_V2; - bank->db_clk = of_clk_get(bank->of_node, 1); - if (IS_ERR(bank->db_clk)) { - clk_disable_unprepare(bank->clk); - dev_err(info->dev, "cannot find debounce clk\n"); - - return PTR_ERR(bank->db_clk); - } - - clk_prepare(bank->db_clk); - } else { - bank->gpio_regs = &gpio_regs_v1; - bank->gpio_type = GPIO_TYPE_V1; - } - - return 0; -} - static const struct of_device_id rockchip_pinctrl_dt_match[]; /* Ctrl data specially handle */ @@ -4515,7 +3685,6 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( { const struct of_device_id *match; struct device_node *node = pdev->dev.of_node; - struct device_node *np; struct rockchip_pin_ctrl *ctrl; struct rockchip_pin_bank *bank; int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j; @@ -4523,23 +3692,6 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( match = of_match_node(rockchip_pinctrl_dt_match, node); ctrl = (struct rockchip_pin_ctrl *)match->data; - for_each_child_of_node(node, np) { - if (!of_find_property(np, "gpio-controller", NULL)) - continue; - - bank = ctrl->pin_banks; - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { - if (!strcmp(bank->name, np->name)) { - bank->of_node = np; - - if (!rockchip_get_bank_data(bank, d)) - bank->valid = true; - - break; - } - } - } - /* Ctrl data re-initialize for some Socs */ if (ctrl->ctrl_data_re_init) { if (ctrl->ctrl_data_re_init(ctrl)) @@ -4813,17 +3965,18 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev) return ret; } - ret = rockchip_gpiolib_register(pdev, info); + ret = rockchip_pinctrl_register(pdev, info); if (ret) return ret; - ret = rockchip_pinctrl_register(pdev, info); + platform_set_drvdata(pdev, info); + + ret = of_platform_populate(np, rockchip_bank_match, NULL, NULL); if (ret) { - rockchip_gpiolib_unregister(pdev, info); + dev_err(&pdev->dev, "failed to register gpio device\n"); return ret; } - - platform_set_drvdata(pdev, info); + dev_info(dev, "probed %s\n", dev_name(dev)); return 0; }