linux/drivers/pinctrl/meson/pinctrl-meson.c
<<
>>
Prefs
   1/*
   2 * Pin controller and GPIO driver for Amlogic Meson SoCs
   3 *
   4 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * version 2 as published by the Free Software Foundation.
   9 *
  10 * You should have received a copy of the GNU General Public License
  11 * along with this program. If not, see <http://www.gnu.org/licenses/>.
  12 */
  13
  14/*
  15 * The available pins are organized in banks (A,B,C,D,E,X,Y,Z,AO,
  16 * BOOT,CARD for meson6, X,Y,DV,H,Z,AO,BOOT,CARD for meson8 and
  17 * X,Y,DV,H,AO,BOOT,CARD,DIF for meson8b) and each bank has a
  18 * variable number of pins.
  19 *
  20 * The AO bank is special because it belongs to the Always-On power
  21 * domain which can't be powered off; the bank also uses a set of
  22 * registers different from the other banks.
  23 *
  24 * For each of the two power domains (regular and always-on) there are
  25 * 4 different register ranges that control the following properties
  26 * of the pins:
  27 *  1) pin muxing
  28 *  2) pull enable/disable
  29 *  3) pull up/down
  30 *  4) GPIO direction, output value, input value
  31 *
  32 * In some cases the register ranges for pull enable and pull
  33 * direction are the same and thus there are only 3 register ranges.
  34 *
  35 * Every pinmux group can be enabled by a specific bit in the first
  36 * register range of the domain; when all groups for a given pin are
  37 * disabled the pin acts as a GPIO.
  38 *
  39 * For the pull and GPIO configuration every bank uses a contiguous
  40 * set of bits in the register sets described above; the same register
  41 * can be shared by more banks with different offsets.
  42 *
  43 * In addition to this there are some registers shared between all
  44 * banks that control the IRQ functionality. This feature is not
  45 * supported at the moment by the driver.
  46 */
  47
  48#include <linux/device.h>
  49#include <linux/gpio.h>
  50#include <linux/init.h>
  51#include <linux/io.h>
  52#include <linux/module.h>
  53#include <linux/of.h>
  54#include <linux/of_address.h>
  55#include <linux/pinctrl/pinconf-generic.h>
  56#include <linux/pinctrl/pinconf.h>
  57#include <linux/pinctrl/pinctrl.h>
  58#include <linux/pinctrl/pinmux.h>
  59#include <linux/platform_device.h>
  60#include <linux/regmap.h>
  61#include <linux/seq_file.h>
  62
  63#include "../core.h"
  64#include "../pinctrl-utils.h"
  65#include "pinctrl-meson.h"
  66
  67/**
  68 * meson_get_bank() - find the bank containing a given pin
  69 *
  70 * @domain:     the domain containing the pin
  71 * @pin:        the pin number
  72 * @bank:       the found bank
  73 *
  74 * Return:      0 on success, a negative value on error
  75 */
  76static int meson_get_bank(struct meson_domain *domain, unsigned int pin,
  77                          struct meson_bank **bank)
  78{
  79        int i;
  80
  81        for (i = 0; i < domain->data->num_banks; i++) {
  82                if (pin >= domain->data->banks[i].first &&
  83                    pin <= domain->data->banks[i].last) {
  84                        *bank = &domain->data->banks[i];
  85                        return 0;
  86                }
  87        }
  88
  89        return -EINVAL;
  90}
  91
  92/**
  93 * meson_get_domain_and_bank() - find domain and bank containing a given pin
  94 *
  95 * @pc:         Meson pin controller device
  96 * @pin:        the pin number
  97 * @domain:     the found domain
  98 * @bank:       the found bank
  99 *
 100 * Return:      0 on success, a negative value on error
 101 */
 102static int meson_get_domain_and_bank(struct meson_pinctrl *pc, unsigned int pin,
 103                                     struct meson_domain **domain,
 104                                     struct meson_bank **bank)
 105{
 106        struct meson_domain *d;
 107        int i;
 108
 109        for (i = 0; i < pc->data->num_domains; i++) {
 110                d = &pc->domains[i];
 111                if (pin >= d->data->pin_base &&
 112                    pin < d->data->pin_base + d->data->num_pins) {
 113                        *domain = d;
 114                        return meson_get_bank(d, pin, bank);
 115                }
 116        }
 117
 118        return -EINVAL;
 119}
 120
 121/**
 122 * meson_calc_reg_and_bit() - calculate register and bit for a pin
 123 *
 124 * @bank:       the bank containing the pin
 125 * @pin:        the pin number
 126 * @reg_type:   the type of register needed (pull-enable, pull, etc...)
 127 * @reg:        the computed register offset
 128 * @bit:        the computed bit
 129 */
 130static void meson_calc_reg_and_bit(struct meson_bank *bank, unsigned int pin,
 131                                   enum meson_reg_type reg_type,
 132                                   unsigned int *reg, unsigned int *bit)
 133{
 134        struct meson_reg_desc *desc = &bank->regs[reg_type];
 135
 136        *reg = desc->reg * 4;
 137        *bit = desc->bit + pin - bank->first;
 138}
 139
 140static int meson_get_groups_count(struct pinctrl_dev *pcdev)
 141{
 142        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 143
 144        return pc->data->num_groups;
 145}
 146
 147static const char *meson_get_group_name(struct pinctrl_dev *pcdev,
 148                                        unsigned selector)
 149{
 150        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 151
 152        return pc->data->groups[selector].name;
 153}
 154
 155static int meson_get_group_pins(struct pinctrl_dev *pcdev, unsigned selector,
 156                                const unsigned **pins, unsigned *num_pins)
 157{
 158        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 159
 160        *pins = pc->data->groups[selector].pins;
 161        *num_pins = pc->data->groups[selector].num_pins;
 162
 163        return 0;
 164}
 165
 166static void meson_pin_dbg_show(struct pinctrl_dev *pcdev, struct seq_file *s,
 167                               unsigned offset)
 168{
 169        seq_printf(s, " %s", dev_name(pcdev->dev));
 170}
 171
 172static const struct pinctrl_ops meson_pctrl_ops = {
 173        .get_groups_count       = meson_get_groups_count,
 174        .get_group_name         = meson_get_group_name,
 175        .get_group_pins         = meson_get_group_pins,
 176        .dt_node_to_map         = pinconf_generic_dt_node_to_map_all,
 177        .dt_free_map            = pinctrl_utils_dt_free_map,
 178        .pin_dbg_show           = meson_pin_dbg_show,
 179};
 180
 181/**
 182 * meson_pmx_disable_other_groups() - disable other groups using a given pin
 183 *
 184 * @pc:         meson pin controller device
 185 * @pin:        number of the pin
 186 * @sel_group:  index of the selected group, or -1 if none
 187 *
 188 * The function disables all pinmux groups using a pin except the
 189 * selected one. If @sel_group is -1 all groups are disabled, leaving
 190 * the pin in GPIO mode.
 191 */
 192static void meson_pmx_disable_other_groups(struct meson_pinctrl *pc,
 193                                           unsigned int pin, int sel_group)
 194{
 195        struct meson_pmx_group *group;
 196        struct meson_domain *domain;
 197        int i, j;
 198
 199        for (i = 0; i < pc->data->num_groups; i++) {
 200                group = &pc->data->groups[i];
 201                if (group->is_gpio || i == sel_group)
 202                        continue;
 203
 204                for (j = 0; j < group->num_pins; j++) {
 205                        if (group->pins[j] == pin) {
 206                                /* We have found a group using the pin */
 207                                domain = &pc->domains[group->domain];
 208                                regmap_update_bits(domain->reg_mux,
 209                                                   group->reg * 4,
 210                                                   BIT(group->bit), 0);
 211                        }
 212                }
 213        }
 214}
 215
 216static int meson_pmx_set_mux(struct pinctrl_dev *pcdev, unsigned func_num,
 217                             unsigned group_num)
 218{
 219        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 220        struct meson_pmx_func *func = &pc->data->funcs[func_num];
 221        struct meson_pmx_group *group = &pc->data->groups[group_num];
 222        struct meson_domain *domain = &pc->domains[group->domain];
 223        int i, ret = 0;
 224
 225        dev_dbg(pc->dev, "enable function %s, group %s\n", func->name,
 226                group->name);
 227
 228        /*
 229         * Disable groups using the same pin.
 230         * The selected group is not disabled to avoid glitches.
 231         */
 232        for (i = 0; i < group->num_pins; i++)
 233                meson_pmx_disable_other_groups(pc, group->pins[i], group_num);
 234
 235        /* Function 0 (GPIO) doesn't need any additional setting */
 236        if (func_num)
 237                ret = regmap_update_bits(domain->reg_mux, group->reg * 4,
 238                                         BIT(group->bit), BIT(group->bit));
 239
 240        return ret;
 241}
 242
 243static int meson_pmx_request_gpio(struct pinctrl_dev *pcdev,
 244                                  struct pinctrl_gpio_range *range,
 245                                  unsigned offset)
 246{
 247        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 248
 249        meson_pmx_disable_other_groups(pc, range->pin_base + offset, -1);
 250
 251        return 0;
 252}
 253
 254static int meson_pmx_get_funcs_count(struct pinctrl_dev *pcdev)
 255{
 256        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 257
 258        return pc->data->num_funcs;
 259}
 260
 261static const char *meson_pmx_get_func_name(struct pinctrl_dev *pcdev,
 262                                           unsigned selector)
 263{
 264        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 265
 266        return pc->data->funcs[selector].name;
 267}
 268
 269static int meson_pmx_get_groups(struct pinctrl_dev *pcdev, unsigned selector,
 270                                const char * const **groups,
 271                                unsigned * const num_groups)
 272{
 273        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 274
 275        *groups = pc->data->funcs[selector].groups;
 276        *num_groups = pc->data->funcs[selector].num_groups;
 277
 278        return 0;
 279}
 280
 281static const struct pinmux_ops meson_pmx_ops = {
 282        .set_mux = meson_pmx_set_mux,
 283        .get_functions_count = meson_pmx_get_funcs_count,
 284        .get_function_name = meson_pmx_get_func_name,
 285        .get_function_groups = meson_pmx_get_groups,
 286        .gpio_request_enable = meson_pmx_request_gpio,
 287};
 288
 289static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
 290                             unsigned long *configs, unsigned num_configs)
 291{
 292        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 293        struct meson_domain *domain;
 294        struct meson_bank *bank;
 295        enum pin_config_param param;
 296        unsigned int reg, bit;
 297        int i, ret;
 298        u16 arg;
 299
 300        ret = meson_get_domain_and_bank(pc, pin, &domain, &bank);
 301        if (ret)
 302                return ret;
 303
 304        for (i = 0; i < num_configs; i++) {
 305                param = pinconf_to_config_param(configs[i]);
 306                arg = pinconf_to_config_argument(configs[i]);
 307
 308                switch (param) {
 309                case PIN_CONFIG_BIAS_DISABLE:
 310                        dev_dbg(pc->dev, "pin %u: disable bias\n", pin);
 311
 312                        meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
 313                        ret = regmap_update_bits(domain->reg_pull, reg,
 314                                                 BIT(bit), 0);
 315                        if (ret)
 316                                return ret;
 317                        break;
 318                case PIN_CONFIG_BIAS_PULL_UP:
 319                        dev_dbg(pc->dev, "pin %u: enable pull-up\n", pin);
 320
 321                        meson_calc_reg_and_bit(bank, pin, REG_PULLEN,
 322                                               &reg, &bit);
 323                        ret = regmap_update_bits(domain->reg_pullen, reg,
 324                                                 BIT(bit), BIT(bit));
 325                        if (ret)
 326                                return ret;
 327
 328                        meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
 329                        ret = regmap_update_bits(domain->reg_pull, reg,
 330                                                 BIT(bit), BIT(bit));
 331                        if (ret)
 332                                return ret;
 333                        break;
 334                case PIN_CONFIG_BIAS_PULL_DOWN:
 335                        dev_dbg(pc->dev, "pin %u: enable pull-down\n", pin);
 336
 337                        meson_calc_reg_and_bit(bank, pin, REG_PULLEN,
 338                                               &reg, &bit);
 339                        ret = regmap_update_bits(domain->reg_pullen, reg,
 340                                                 BIT(bit), BIT(bit));
 341                        if (ret)
 342                                return ret;
 343
 344                        meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
 345                        ret = regmap_update_bits(domain->reg_pull, reg,
 346                                                 BIT(bit), 0);
 347                        if (ret)
 348                                return ret;
 349                        break;
 350                default:
 351                        return -ENOTSUPP;
 352                }
 353        }
 354
 355        return 0;
 356}
 357
 358static int meson_pinconf_get_pull(struct meson_pinctrl *pc, unsigned int pin)
 359{
 360        struct meson_domain *domain;
 361        struct meson_bank *bank;
 362        unsigned int reg, bit, val;
 363        int ret, conf;
 364
 365        ret = meson_get_domain_and_bank(pc, pin, &domain, &bank);
 366        if (ret)
 367                return ret;
 368
 369        meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg, &bit);
 370
 371        ret = regmap_read(domain->reg_pullen, reg, &val);
 372        if (ret)
 373                return ret;
 374
 375        if (!(val & BIT(bit))) {
 376                conf = PIN_CONFIG_BIAS_DISABLE;
 377        } else {
 378                meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
 379
 380                ret = regmap_read(domain->reg_pull, reg, &val);
 381                if (ret)
 382                        return ret;
 383
 384                if (val & BIT(bit))
 385                        conf = PIN_CONFIG_BIAS_PULL_UP;
 386                else
 387                        conf = PIN_CONFIG_BIAS_PULL_DOWN;
 388        }
 389
 390        return conf;
 391}
 392
 393static int meson_pinconf_get(struct pinctrl_dev *pcdev, unsigned int pin,
 394                             unsigned long *config)
 395{
 396        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 397        enum pin_config_param param = pinconf_to_config_param(*config);
 398        u16 arg;
 399
 400        switch (param) {
 401        case PIN_CONFIG_BIAS_DISABLE:
 402        case PIN_CONFIG_BIAS_PULL_DOWN:
 403        case PIN_CONFIG_BIAS_PULL_UP:
 404                if (meson_pinconf_get_pull(pc, pin) == param)
 405                        arg = 1;
 406                else
 407                        return -EINVAL;
 408                break;
 409        default:
 410                return -ENOTSUPP;
 411        }
 412
 413        *config = pinconf_to_config_packed(param, arg);
 414        dev_dbg(pc->dev, "pinconf for pin %u is %lu\n", pin, *config);
 415
 416        return 0;
 417}
 418
 419static int meson_pinconf_group_set(struct pinctrl_dev *pcdev,
 420                                   unsigned int num_group,
 421                                   unsigned long *configs, unsigned num_configs)
 422{
 423        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 424        struct meson_pmx_group *group = &pc->data->groups[num_group];
 425        int i;
 426
 427        dev_dbg(pc->dev, "set pinconf for group %s\n", group->name);
 428
 429        for (i = 0; i < group->num_pins; i++) {
 430                meson_pinconf_set(pcdev, group->pins[i], configs,
 431                                  num_configs);
 432        }
 433
 434        return 0;
 435}
 436
 437static int meson_pinconf_group_get(struct pinctrl_dev *pcdev,
 438                                   unsigned int group, unsigned long *config)
 439{
 440        return -ENOSYS;
 441}
 442
 443static const struct pinconf_ops meson_pinconf_ops = {
 444        .pin_config_get         = meson_pinconf_get,
 445        .pin_config_set         = meson_pinconf_set,
 446        .pin_config_group_get   = meson_pinconf_group_get,
 447        .pin_config_group_set   = meson_pinconf_group_set,
 448        .is_generic             = true,
 449};
 450
 451static inline struct meson_domain *to_meson_domain(struct gpio_chip *chip)
 452{
 453        return container_of(chip, struct meson_domain, chip);
 454}
 455
 456static int meson_gpio_request(struct gpio_chip *chip, unsigned gpio)
 457{
 458        return pinctrl_request_gpio(chip->base + gpio);
 459}
 460
 461static void meson_gpio_free(struct gpio_chip *chip, unsigned gpio)
 462{
 463        struct meson_domain *domain = to_meson_domain(chip);
 464
 465        pinctrl_free_gpio(domain->data->pin_base + gpio);
 466}
 467
 468static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
 469{
 470        struct meson_domain *domain = to_meson_domain(chip);
 471        unsigned int reg, bit, pin;
 472        struct meson_bank *bank;
 473        int ret;
 474
 475        pin = domain->data->pin_base + gpio;
 476        ret = meson_get_bank(domain, pin, &bank);
 477        if (ret)
 478                return ret;
 479
 480        meson_calc_reg_and_bit(bank, pin, REG_DIR, &reg, &bit);
 481
 482        return regmap_update_bits(domain->reg_gpio, reg, BIT(bit), BIT(bit));
 483}
 484
 485static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
 486                                       int value)
 487{
 488        struct meson_domain *domain = to_meson_domain(chip);
 489        unsigned int reg, bit, pin;
 490        struct meson_bank *bank;
 491        int ret;
 492
 493        pin = domain->data->pin_base + gpio;
 494        ret = meson_get_bank(domain, pin, &bank);
 495        if (ret)
 496                return ret;
 497
 498        meson_calc_reg_and_bit(bank, pin, REG_DIR, &reg, &bit);
 499        ret = regmap_update_bits(domain->reg_gpio, reg, BIT(bit), 0);
 500        if (ret)
 501                return ret;
 502
 503        meson_calc_reg_and_bit(bank, pin, REG_OUT, &reg, &bit);
 504        return regmap_update_bits(domain->reg_gpio, reg, BIT(bit),
 505                                  value ? BIT(bit) : 0);
 506}
 507
 508static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
 509{
 510        struct meson_domain *domain = to_meson_domain(chip);
 511        unsigned int reg, bit, pin;
 512        struct meson_bank *bank;
 513        int ret;
 514
 515        pin = domain->data->pin_base + gpio;
 516        ret = meson_get_bank(domain, pin, &bank);
 517        if (ret)
 518                return;
 519
 520        meson_calc_reg_and_bit(bank, pin, REG_OUT, &reg, &bit);
 521        regmap_update_bits(domain->reg_gpio, reg, BIT(bit),
 522                           value ? BIT(bit) : 0);
 523}
 524
 525static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
 526{
 527        struct meson_domain *domain = to_meson_domain(chip);
 528        unsigned int reg, bit, val, pin;
 529        struct meson_bank *bank;
 530        int ret;
 531
 532        pin = domain->data->pin_base + gpio;
 533        ret = meson_get_bank(domain, pin, &bank);
 534        if (ret)
 535                return ret;
 536
 537        meson_calc_reg_and_bit(bank, pin, REG_IN, &reg, &bit);
 538        regmap_read(domain->reg_gpio, reg, &val);
 539
 540        return !!(val & BIT(bit));
 541}
 542
 543static const struct of_device_id meson_pinctrl_dt_match[] = {
 544        {
 545                .compatible = "amlogic,meson8-pinctrl",
 546                .data = &meson8_pinctrl_data,
 547        },
 548        {
 549                .compatible = "amlogic,meson8b-pinctrl",
 550                .data = &meson8b_pinctrl_data,
 551        },
 552        { },
 553};
 554MODULE_DEVICE_TABLE(of, meson_pinctrl_dt_match);
 555
 556static int meson_gpiolib_register(struct meson_pinctrl *pc)
 557{
 558        struct meson_domain *domain;
 559        int i, ret;
 560
 561        for (i = 0; i < pc->data->num_domains; i++) {
 562                domain = &pc->domains[i];
 563
 564                domain->chip.label = domain->data->name;
 565                domain->chip.dev = pc->dev;
 566                domain->chip.request = meson_gpio_request;
 567                domain->chip.free = meson_gpio_free;
 568                domain->chip.direction_input = meson_gpio_direction_input;
 569                domain->chip.direction_output = meson_gpio_direction_output;
 570                domain->chip.get = meson_gpio_get;
 571                domain->chip.set = meson_gpio_set;
 572                domain->chip.base = domain->data->pin_base;
 573                domain->chip.ngpio = domain->data->num_pins;
 574                domain->chip.can_sleep = false;
 575                domain->chip.of_node = domain->of_node;
 576                domain->chip.of_gpio_n_cells = 2;
 577
 578                ret = gpiochip_add(&domain->chip);
 579                if (ret) {
 580                        dev_err(pc->dev, "can't add gpio chip %s\n",
 581                                domain->data->name);
 582                        goto fail;
 583                }
 584
 585                ret = gpiochip_add_pin_range(&domain->chip, dev_name(pc->dev),
 586                                             0, domain->data->pin_base,
 587                                             domain->chip.ngpio);
 588                if (ret) {
 589                        dev_err(pc->dev, "can't add pin range\n");
 590                        goto fail;
 591                }
 592        }
 593
 594        return 0;
 595fail:
 596        for (i--; i >= 0; i--)
 597                gpiochip_remove(&pc->domains[i].chip);
 598
 599        return ret;
 600}
 601
 602static struct meson_domain_data *meson_get_domain_data(struct meson_pinctrl *pc,
 603                                                       struct device_node *np)
 604{
 605        int i;
 606
 607        for (i = 0; i < pc->data->num_domains; i++) {
 608                if (!strcmp(np->name, pc->data->domain_data[i].name))
 609                        return &pc->data->domain_data[i];
 610        }
 611
 612        return NULL;
 613}
 614
 615static struct regmap_config meson_regmap_config = {
 616        .reg_bits = 32,
 617        .val_bits = 32,
 618        .reg_stride = 4,
 619};
 620
 621static struct regmap *meson_map_resource(struct meson_pinctrl *pc,
 622                                         struct device_node *node, char *name)
 623{
 624        struct resource res;
 625        void __iomem *base;
 626        int i;
 627
 628        i = of_property_match_string(node, "reg-names", name);
 629        if (of_address_to_resource(node, i, &res))
 630                return ERR_PTR(-ENOENT);
 631
 632        base = devm_ioremap_resource(pc->dev, &res);
 633        if (IS_ERR(base))
 634                return ERR_CAST(base);
 635
 636        meson_regmap_config.max_register = resource_size(&res) - 4;
 637        meson_regmap_config.name = devm_kasprintf(pc->dev, GFP_KERNEL,
 638                                                  "%s-%s", node->name,
 639                                                  name);
 640        if (!meson_regmap_config.name)
 641                return ERR_PTR(-ENOMEM);
 642
 643        return devm_regmap_init_mmio(pc->dev, base, &meson_regmap_config);
 644}
 645
 646static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
 647                                  struct device_node *node)
 648{
 649        struct device_node *np;
 650        struct meson_domain *domain;
 651        int i = 0, num_domains = 0;
 652
 653        for_each_child_of_node(node, np) {
 654                if (!of_find_property(np, "gpio-controller", NULL))
 655                        continue;
 656                num_domains++;
 657        }
 658
 659        if (num_domains != pc->data->num_domains) {
 660                dev_err(pc->dev, "wrong number of subnodes\n");
 661                return -EINVAL;
 662        }
 663
 664        pc->domains = devm_kzalloc(pc->dev, num_domains *
 665                                   sizeof(struct meson_domain), GFP_KERNEL);
 666        if (!pc->domains)
 667                return -ENOMEM;
 668
 669        for_each_child_of_node(node, np) {
 670                if (!of_find_property(np, "gpio-controller", NULL))
 671                        continue;
 672
 673                domain = &pc->domains[i];
 674
 675                domain->data = meson_get_domain_data(pc, np);
 676                if (!domain->data) {
 677                        dev_err(pc->dev, "domain data not found for node %s\n",
 678                                np->name);
 679                        return -ENODEV;
 680                }
 681
 682                domain->of_node = np;
 683
 684                domain->reg_mux = meson_map_resource(pc, np, "mux");
 685                if (IS_ERR(domain->reg_mux)) {
 686                        dev_err(pc->dev, "mux registers not found\n");
 687                        return PTR_ERR(domain->reg_mux);
 688                }
 689
 690                domain->reg_pull = meson_map_resource(pc, np, "pull");
 691                if (IS_ERR(domain->reg_pull)) {
 692                        dev_err(pc->dev, "pull registers not found\n");
 693                        return PTR_ERR(domain->reg_pull);
 694                }
 695
 696                domain->reg_pullen = meson_map_resource(pc, np, "pull-enable");
 697                /* Use pull region if pull-enable one is not present */
 698                if (IS_ERR(domain->reg_pullen))
 699                        domain->reg_pullen = domain->reg_pull;
 700
 701                domain->reg_gpio = meson_map_resource(pc, np, "gpio");
 702                if (IS_ERR(domain->reg_gpio)) {
 703                        dev_err(pc->dev, "gpio registers not found\n");
 704                        return PTR_ERR(domain->reg_gpio);
 705                }
 706
 707                i++;
 708        }
 709
 710        return 0;
 711}
 712
 713static int meson_pinctrl_probe(struct platform_device *pdev)
 714{
 715        const struct of_device_id *match;
 716        struct device *dev = &pdev->dev;
 717        struct meson_pinctrl *pc;
 718        int ret;
 719
 720        pc = devm_kzalloc(dev, sizeof(struct meson_pinctrl), GFP_KERNEL);
 721        if (!pc)
 722                return -ENOMEM;
 723
 724        pc->dev = dev;
 725        match = of_match_node(meson_pinctrl_dt_match, pdev->dev.of_node);
 726        pc->data = (struct meson_pinctrl_data *)match->data;
 727
 728        ret = meson_pinctrl_parse_dt(pc, pdev->dev.of_node);
 729        if (ret)
 730                return ret;
 731
 732        pc->desc.name           = "pinctrl-meson";
 733        pc->desc.owner          = THIS_MODULE;
 734        pc->desc.pctlops        = &meson_pctrl_ops;
 735        pc->desc.pmxops         = &meson_pmx_ops;
 736        pc->desc.confops        = &meson_pinconf_ops;
 737        pc->desc.pins           = pc->data->pins;
 738        pc->desc.npins          = pc->data->num_pins;
 739
 740        pc->pcdev = pinctrl_register(&pc->desc, pc->dev, pc);
 741        if (IS_ERR(pc->pcdev)) {
 742                dev_err(pc->dev, "can't register pinctrl device");
 743                return PTR_ERR(pc->pcdev);
 744        }
 745
 746        ret = meson_gpiolib_register(pc);
 747        if (ret) {
 748                pinctrl_unregister(pc->pcdev);
 749                return ret;
 750        }
 751
 752        return 0;
 753}
 754
 755static struct platform_driver meson_pinctrl_driver = {
 756        .probe          = meson_pinctrl_probe,
 757        .driver = {
 758                .name   = "meson-pinctrl",
 759                .of_match_table = meson_pinctrl_dt_match,
 760        },
 761};
 762module_platform_driver(meson_pinctrl_driver);
 763
 764MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
 765MODULE_DESCRIPTION("Amlogic Meson pinctrl driver");
 766MODULE_LICENSE("GPL v2");
 767