linux/drivers/pinctrl/pinctrl-sunxi.c
<<
>>
Prefs
   1/*
   2 * Allwinner A1X SoCs pinctrl driver.
   3 *
   4 * Copyright (C) 2012 Maxime Ripard
   5 *
   6 * Maxime Ripard <maxime.ripard@free-electrons.com>
   7 *
   8 * This file is licensed under the terms of the GNU General Public
   9 * License version 2.  This program is licensed "as is" without any
  10 * warranty of any kind, whether express or implied.
  11 */
  12
  13#include <linux/io.h>
  14#include <linux/clk.h>
  15#include <linux/gpio.h>
  16#include <linux/irqdomain.h>
  17#include <linux/module.h>
  18#include <linux/of.h>
  19#include <linux/of_address.h>
  20#include <linux/of_device.h>
  21#include <linux/of_irq.h>
  22#include <linux/pinctrl/consumer.h>
  23#include <linux/pinctrl/machine.h>
  24#include <linux/pinctrl/pinctrl.h>
  25#include <linux/pinctrl/pinconf-generic.h>
  26#include <linux/pinctrl/pinmux.h>
  27#include <linux/platform_device.h>
  28#include <linux/slab.h>
  29
  30#include "core.h"
  31#include "pinctrl-sunxi.h"
  32#include "pinctrl-sunxi-pins.h"
  33
  34static struct sunxi_pinctrl_group *
  35sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group)
  36{
  37        int i;
  38
  39        for (i = 0; i < pctl->ngroups; i++) {
  40                struct sunxi_pinctrl_group *grp = pctl->groups + i;
  41
  42                if (!strcmp(grp->name, group))
  43                        return grp;
  44        }
  45
  46        return NULL;
  47}
  48
  49static struct sunxi_pinctrl_function *
  50sunxi_pinctrl_find_function_by_name(struct sunxi_pinctrl *pctl,
  51                                    const char *name)
  52{
  53        struct sunxi_pinctrl_function *func = pctl->functions;
  54        int i;
  55
  56        for (i = 0; i < pctl->nfunctions; i++) {
  57                if (!func[i].name)
  58                        break;
  59
  60                if (!strcmp(func[i].name, name))
  61                        return func + i;
  62        }
  63
  64        return NULL;
  65}
  66
  67static struct sunxi_desc_function *
  68sunxi_pinctrl_desc_find_function_by_name(struct sunxi_pinctrl *pctl,
  69                                         const char *pin_name,
  70                                         const char *func_name)
  71{
  72        int i;
  73
  74        for (i = 0; i < pctl->desc->npins; i++) {
  75                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
  76
  77                if (!strcmp(pin->pin.name, pin_name)) {
  78                        struct sunxi_desc_function *func = pin->functions;
  79
  80                        while (func->name) {
  81                                if (!strcmp(func->name, func_name))
  82                                        return func;
  83
  84                                func++;
  85                        }
  86                }
  87        }
  88
  89        return NULL;
  90}
  91
  92static struct sunxi_desc_function *
  93sunxi_pinctrl_desc_find_function_by_pin(struct sunxi_pinctrl *pctl,
  94                                        const u16 pin_num,
  95                                        const char *func_name)
  96{
  97        int i;
  98
  99        for (i = 0; i < pctl->desc->npins; i++) {
 100                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
 101
 102                if (pin->pin.number == pin_num) {
 103                        struct sunxi_desc_function *func = pin->functions;
 104
 105                        while (func->name) {
 106                                if (!strcmp(func->name, func_name))
 107                                        return func;
 108
 109                                func++;
 110                        }
 111                }
 112        }
 113
 114        return NULL;
 115}
 116
 117static int sunxi_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
 118{
 119        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 120
 121        return pctl->ngroups;
 122}
 123
 124static const char *sunxi_pctrl_get_group_name(struct pinctrl_dev *pctldev,
 125                                              unsigned group)
 126{
 127        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 128
 129        return pctl->groups[group].name;
 130}
 131
 132static int sunxi_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
 133                                      unsigned group,
 134                                      const unsigned **pins,
 135                                      unsigned *num_pins)
 136{
 137        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 138
 139        *pins = (unsigned *)&pctl->groups[group].pin;
 140        *num_pins = 1;
 141
 142        return 0;
 143}
 144
 145static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
 146                                      struct device_node *node,
 147                                      struct pinctrl_map **map,
 148                                      unsigned *num_maps)
 149{
 150        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 151        unsigned long *pinconfig;
 152        struct property *prop;
 153        const char *function;
 154        const char *group;
 155        int ret, nmaps, i = 0;
 156        u32 val;
 157
 158        *map = NULL;
 159        *num_maps = 0;
 160
 161        ret = of_property_read_string(node, "allwinner,function", &function);
 162        if (ret) {
 163                dev_err(pctl->dev,
 164                        "missing allwinner,function property in node %s\n",
 165                        node->name);
 166                return -EINVAL;
 167        }
 168
 169        nmaps = of_property_count_strings(node, "allwinner,pins") * 2;
 170        if (nmaps < 0) {
 171                dev_err(pctl->dev,
 172                        "missing allwinner,pins property in node %s\n",
 173                        node->name);
 174                return -EINVAL;
 175        }
 176
 177        *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL);
 178        if (!*map)
 179                return -ENOMEM;
 180
 181        of_property_for_each_string(node, "allwinner,pins", prop, group) {
 182                struct sunxi_pinctrl_group *grp =
 183                        sunxi_pinctrl_find_group_by_name(pctl, group);
 184                int j = 0, configlen = 0;
 185
 186                if (!grp) {
 187                        dev_err(pctl->dev, "unknown pin %s", group);
 188                        continue;
 189                }
 190
 191                if (!sunxi_pinctrl_desc_find_function_by_name(pctl,
 192                                                              grp->name,
 193                                                              function)) {
 194                        dev_err(pctl->dev, "unsupported function %s on pin %s",
 195                                function, group);
 196                        continue;
 197                }
 198
 199                (*map)[i].type = PIN_MAP_TYPE_MUX_GROUP;
 200                (*map)[i].data.mux.group = group;
 201                (*map)[i].data.mux.function = function;
 202
 203                i++;
 204
 205                (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP;
 206                (*map)[i].data.configs.group_or_pin = group;
 207
 208                if (of_find_property(node, "allwinner,drive", NULL))
 209                        configlen++;
 210                if (of_find_property(node, "allwinner,pull", NULL))
 211                        configlen++;
 212
 213                pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL);
 214
 215                if (!of_property_read_u32(node, "allwinner,drive", &val)) {
 216                        u16 strength = (val + 1) * 10;
 217                        pinconfig[j++] =
 218                                pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH,
 219                                                         strength);
 220                }
 221
 222                if (!of_property_read_u32(node, "allwinner,pull", &val)) {
 223                        enum pin_config_param pull = PIN_CONFIG_END;
 224                        if (val == 1)
 225                                pull = PIN_CONFIG_BIAS_PULL_UP;
 226                        else if (val == 2)
 227                                pull = PIN_CONFIG_BIAS_PULL_DOWN;
 228                        pinconfig[j++] = pinconf_to_config_packed(pull, 0);
 229                }
 230
 231                (*map)[i].data.configs.configs = pinconfig;
 232                (*map)[i].data.configs.num_configs = configlen;
 233
 234                i++;
 235        }
 236
 237        *num_maps = nmaps;
 238
 239        return 0;
 240}
 241
 242static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev,
 243                                    struct pinctrl_map *map,
 244                                    unsigned num_maps)
 245{
 246        int i;
 247
 248        for (i = 0; i < num_maps; i++) {
 249                if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
 250                        kfree(map[i].data.configs.configs);
 251        }
 252
 253        kfree(map);
 254}
 255
 256static const struct pinctrl_ops sunxi_pctrl_ops = {
 257        .dt_node_to_map         = sunxi_pctrl_dt_node_to_map,
 258        .dt_free_map            = sunxi_pctrl_dt_free_map,
 259        .get_groups_count       = sunxi_pctrl_get_groups_count,
 260        .get_group_name         = sunxi_pctrl_get_group_name,
 261        .get_group_pins         = sunxi_pctrl_get_group_pins,
 262};
 263
 264static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev,
 265                                 unsigned group,
 266                                 unsigned long *config)
 267{
 268        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 269
 270        *config = pctl->groups[group].config;
 271
 272        return 0;
 273}
 274
 275static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
 276                                 unsigned group,
 277                                 unsigned long *configs,
 278                                 unsigned num_configs)
 279{
 280        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 281        struct sunxi_pinctrl_group *g = &pctl->groups[group];
 282        unsigned long flags;
 283        u32 val, mask;
 284        u16 strength;
 285        u8 dlevel;
 286        int i;
 287
 288        spin_lock_irqsave(&pctl->lock, flags);
 289
 290        for (i = 0; i < num_configs; i++) {
 291                switch (pinconf_to_config_param(configs[i])) {
 292                case PIN_CONFIG_DRIVE_STRENGTH:
 293                        strength = pinconf_to_config_argument(configs[i]);
 294                        if (strength > 40) {
 295                                spin_unlock_irqrestore(&pctl->lock, flags);
 296                                return -EINVAL;
 297                        }
 298                        /*
 299                         * We convert from mA to what the register expects:
 300                         *   0: 10mA
 301                         *   1: 20mA
 302                         *   2: 30mA
 303                         *   3: 40mA
 304                         */
 305                        dlevel = strength / 10 - 1;
 306                        val = readl(pctl->membase + sunxi_dlevel_reg(g->pin));
 307                        mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin);
 308                        writel((val & ~mask)
 309                                | dlevel << sunxi_dlevel_offset(g->pin),
 310                                pctl->membase + sunxi_dlevel_reg(g->pin));
 311                        break;
 312                case PIN_CONFIG_BIAS_PULL_UP:
 313                        val = readl(pctl->membase + sunxi_pull_reg(g->pin));
 314                        mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin);
 315                        writel((val & ~mask) | 1 << sunxi_pull_offset(g->pin),
 316                                pctl->membase + sunxi_pull_reg(g->pin));
 317                        break;
 318                case PIN_CONFIG_BIAS_PULL_DOWN:
 319                        val = readl(pctl->membase + sunxi_pull_reg(g->pin));
 320                        mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin);
 321                        writel((val & ~mask) | 2 << sunxi_pull_offset(g->pin),
 322                                pctl->membase + sunxi_pull_reg(g->pin));
 323                        break;
 324                default:
 325                        break;
 326                }
 327                /* cache the config value */
 328                g->config = configs[i];
 329        } /* for each config */
 330
 331        spin_unlock_irqrestore(&pctl->lock, flags);
 332
 333        return 0;
 334}
 335
 336static const struct pinconf_ops sunxi_pconf_ops = {
 337        .pin_config_group_get   = sunxi_pconf_group_get,
 338        .pin_config_group_set   = sunxi_pconf_group_set,
 339};
 340
 341static int sunxi_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
 342{
 343        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 344
 345        return pctl->nfunctions;
 346}
 347
 348static const char *sunxi_pmx_get_func_name(struct pinctrl_dev *pctldev,
 349                                           unsigned function)
 350{
 351        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 352
 353        return pctl->functions[function].name;
 354}
 355
 356static int sunxi_pmx_get_func_groups(struct pinctrl_dev *pctldev,
 357                                     unsigned function,
 358                                     const char * const **groups,
 359                                     unsigned * const num_groups)
 360{
 361        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 362
 363        *groups = pctl->functions[function].groups;
 364        *num_groups = pctl->functions[function].ngroups;
 365
 366        return 0;
 367}
 368
 369static void sunxi_pmx_set(struct pinctrl_dev *pctldev,
 370                                 unsigned pin,
 371                                 u8 config)
 372{
 373        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 374        unsigned long flags;
 375        u32 val, mask;
 376
 377        spin_lock_irqsave(&pctl->lock, flags);
 378
 379        val = readl(pctl->membase + sunxi_mux_reg(pin));
 380        mask = MUX_PINS_MASK << sunxi_mux_offset(pin);
 381        writel((val & ~mask) | config << sunxi_mux_offset(pin),
 382                pctl->membase + sunxi_mux_reg(pin));
 383
 384        spin_unlock_irqrestore(&pctl->lock, flags);
 385}
 386
 387static int sunxi_pmx_enable(struct pinctrl_dev *pctldev,
 388                            unsigned function,
 389                            unsigned group)
 390{
 391        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 392        struct sunxi_pinctrl_group *g = pctl->groups + group;
 393        struct sunxi_pinctrl_function *func = pctl->functions + function;
 394        struct sunxi_desc_function *desc =
 395                sunxi_pinctrl_desc_find_function_by_name(pctl,
 396                                                         g->name,
 397                                                         func->name);
 398
 399        if (!desc)
 400                return -EINVAL;
 401
 402        sunxi_pmx_set(pctldev, g->pin, desc->muxval);
 403
 404        return 0;
 405}
 406
 407static int
 408sunxi_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
 409                        struct pinctrl_gpio_range *range,
 410                        unsigned offset,
 411                        bool input)
 412{
 413        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 414        struct sunxi_desc_function *desc;
 415        const char *func;
 416
 417        if (input)
 418                func = "gpio_in";
 419        else
 420                func = "gpio_out";
 421
 422        desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, offset, func);
 423        if (!desc)
 424                return -EINVAL;
 425
 426        sunxi_pmx_set(pctldev, offset, desc->muxval);
 427
 428        return 0;
 429}
 430
 431static const struct pinmux_ops sunxi_pmx_ops = {
 432        .get_functions_count    = sunxi_pmx_get_funcs_cnt,
 433        .get_function_name      = sunxi_pmx_get_func_name,
 434        .get_function_groups    = sunxi_pmx_get_func_groups,
 435        .enable                 = sunxi_pmx_enable,
 436        .gpio_set_direction     = sunxi_pmx_gpio_set_direction,
 437};
 438
 439static struct pinctrl_desc sunxi_pctrl_desc = {
 440        .confops        = &sunxi_pconf_ops,
 441        .pctlops        = &sunxi_pctrl_ops,
 442        .pmxops         = &sunxi_pmx_ops,
 443};
 444
 445static int sunxi_pinctrl_gpio_request(struct gpio_chip *chip, unsigned offset)
 446{
 447        return pinctrl_request_gpio(chip->base + offset);
 448}
 449
 450static void sunxi_pinctrl_gpio_free(struct gpio_chip *chip, unsigned offset)
 451{
 452        pinctrl_free_gpio(chip->base + offset);
 453}
 454
 455static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip,
 456                                        unsigned offset)
 457{
 458        return pinctrl_gpio_direction_input(chip->base + offset);
 459}
 460
 461static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset)
 462{
 463        struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
 464
 465        u32 reg = sunxi_data_reg(offset);
 466        u8 index = sunxi_data_offset(offset);
 467        u32 val = (readl(pctl->membase + reg) >> index) & DATA_PINS_MASK;
 468
 469        return val;
 470}
 471
 472static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip,
 473                                        unsigned offset, int value)
 474{
 475        return pinctrl_gpio_direction_output(chip->base + offset);
 476}
 477
 478static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
 479                                unsigned offset, int value)
 480{
 481        struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
 482        u32 reg = sunxi_data_reg(offset);
 483        u8 index = sunxi_data_offset(offset);
 484        unsigned long flags;
 485        u32 regval;
 486
 487        spin_lock_irqsave(&pctl->lock, flags);
 488
 489        regval = readl(pctl->membase + reg);
 490
 491        if (value)
 492                regval |= BIT(index);
 493        else
 494                regval &= ~(BIT(index));
 495
 496        writel(regval, pctl->membase + reg);
 497
 498        spin_unlock_irqrestore(&pctl->lock, flags);
 499}
 500
 501static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
 502                                const struct of_phandle_args *gpiospec,
 503                                u32 *flags)
 504{
 505        int pin, base;
 506
 507        base = PINS_PER_BANK * gpiospec->args[0];
 508        pin = base + gpiospec->args[1];
 509
 510        if (pin > (gc->base + gc->ngpio))
 511                return -EINVAL;
 512
 513        if (flags)
 514                *flags = gpiospec->args[2];
 515
 516        return pin;
 517}
 518
 519static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 520{
 521        struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
 522        struct sunxi_desc_function *desc;
 523
 524        if (offset >= chip->ngpio)
 525                return -ENXIO;
 526
 527        desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, offset, "irq");
 528        if (!desc)
 529                return -EINVAL;
 530
 531        pctl->irq_array[desc->irqnum] = offset;
 532
 533        dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
 534                chip->label, offset + chip->base, desc->irqnum);
 535
 536        return irq_find_mapping(pctl->domain, desc->irqnum);
 537}
 538
 539static struct gpio_chip sunxi_pinctrl_gpio_chip = {
 540        .owner                  = THIS_MODULE,
 541        .request                = sunxi_pinctrl_gpio_request,
 542        .free                   = sunxi_pinctrl_gpio_free,
 543        .direction_input        = sunxi_pinctrl_gpio_direction_input,
 544        .direction_output       = sunxi_pinctrl_gpio_direction_output,
 545        .get                    = sunxi_pinctrl_gpio_get,
 546        .set                    = sunxi_pinctrl_gpio_set,
 547        .of_xlate               = sunxi_pinctrl_gpio_of_xlate,
 548        .to_irq                 = sunxi_pinctrl_gpio_to_irq,
 549        .of_gpio_n_cells        = 3,
 550        .can_sleep              = 0,
 551};
 552
 553static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
 554                                      unsigned int type)
 555{
 556        struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
 557        u32 reg = sunxi_irq_cfg_reg(d->hwirq);
 558        u8 index = sunxi_irq_cfg_offset(d->hwirq);
 559        unsigned long flags;
 560        u32 regval;
 561        u8 mode;
 562
 563        switch (type) {
 564        case IRQ_TYPE_EDGE_RISING:
 565                mode = IRQ_EDGE_RISING;
 566                break;
 567        case IRQ_TYPE_EDGE_FALLING:
 568                mode = IRQ_EDGE_FALLING;
 569                break;
 570        case IRQ_TYPE_EDGE_BOTH:
 571                mode = IRQ_EDGE_BOTH;
 572                break;
 573        case IRQ_TYPE_LEVEL_HIGH:
 574                mode = IRQ_LEVEL_HIGH;
 575                break;
 576        case IRQ_TYPE_LEVEL_LOW:
 577                mode = IRQ_LEVEL_LOW;
 578                break;
 579        default:
 580                return -EINVAL;
 581        }
 582
 583        spin_lock_irqsave(&pctl->lock, flags);
 584
 585        regval = readl(pctl->membase + reg);
 586        regval &= ~IRQ_CFG_IRQ_MASK;
 587        writel(regval | (mode << index), pctl->membase + reg);
 588
 589        spin_unlock_irqrestore(&pctl->lock, flags);
 590
 591        return 0;
 592}
 593
 594static void sunxi_pinctrl_irq_mask_ack(struct irq_data *d)
 595{
 596        struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
 597        u32 ctrl_reg = sunxi_irq_ctrl_reg(d->hwirq);
 598        u8 ctrl_idx = sunxi_irq_ctrl_offset(d->hwirq);
 599        u32 status_reg = sunxi_irq_status_reg(d->hwirq);
 600        u8 status_idx = sunxi_irq_status_offset(d->hwirq);
 601        unsigned long flags;
 602        u32 val;
 603
 604        spin_lock_irqsave(&pctl->lock, flags);
 605
 606        /* Mask the IRQ */
 607        val = readl(pctl->membase + ctrl_reg);
 608        writel(val & ~(1 << ctrl_idx), pctl->membase + ctrl_reg);
 609
 610        /* Clear the IRQ */
 611        writel(1 << status_idx, pctl->membase + status_reg);
 612
 613        spin_unlock_irqrestore(&pctl->lock, flags);
 614}
 615
 616static void sunxi_pinctrl_irq_mask(struct irq_data *d)
 617{
 618        struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
 619        u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
 620        u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
 621        unsigned long flags;
 622        u32 val;
 623
 624        spin_lock_irqsave(&pctl->lock, flags);
 625
 626        /* Mask the IRQ */
 627        val = readl(pctl->membase + reg);
 628        writel(val & ~(1 << idx), pctl->membase + reg);
 629
 630        spin_unlock_irqrestore(&pctl->lock, flags);
 631}
 632
 633static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
 634{
 635        struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
 636        struct sunxi_desc_function *func;
 637        u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
 638        u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
 639        unsigned long flags;
 640        u32 val;
 641
 642        func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
 643                                                       pctl->irq_array[d->hwirq],
 644                                                       "irq");
 645
 646        /* Change muxing to INT mode */
 647        sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval);
 648
 649        spin_lock_irqsave(&pctl->lock, flags);
 650
 651        /* Unmask the IRQ */
 652        val = readl(pctl->membase + reg);
 653        writel(val | (1 << idx), pctl->membase + reg);
 654
 655        spin_unlock_irqrestore(&pctl->lock, flags);
 656}
 657
 658static struct irq_chip sunxi_pinctrl_irq_chip = {
 659        .irq_mask       = sunxi_pinctrl_irq_mask,
 660        .irq_mask_ack   = sunxi_pinctrl_irq_mask_ack,
 661        .irq_unmask     = sunxi_pinctrl_irq_unmask,
 662        .irq_set_type   = sunxi_pinctrl_irq_set_type,
 663};
 664
 665static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc)
 666{
 667        struct sunxi_pinctrl *pctl = irq_get_handler_data(irq);
 668        const unsigned long reg = readl(pctl->membase + IRQ_STATUS_REG);
 669
 670        /* Clear all interrupts */
 671        writel(reg, pctl->membase + IRQ_STATUS_REG);
 672
 673        if (reg) {
 674                int irqoffset;
 675
 676                for_each_set_bit(irqoffset, &reg, SUNXI_IRQ_NUMBER) {
 677                        int pin_irq = irq_find_mapping(pctl->domain, irqoffset);
 678                        generic_handle_irq(pin_irq);
 679                }
 680        }
 681}
 682
 683static struct of_device_id sunxi_pinctrl_match[] = {
 684        { .compatible = "allwinner,sun4i-a10-pinctrl", .data = (void *)&sun4i_a10_pinctrl_data },
 685        { .compatible = "allwinner,sun5i-a10s-pinctrl", .data = (void *)&sun5i_a10s_pinctrl_data },
 686        { .compatible = "allwinner,sun5i-a13-pinctrl", .data = (void *)&sun5i_a13_pinctrl_data },
 687        { .compatible = "allwinner,sun6i-a31-pinctrl", .data = (void *)&sun6i_a31_pinctrl_data },
 688        { .compatible = "allwinner,sun7i-a20-pinctrl", .data = (void *)&sun7i_a20_pinctrl_data },
 689        {}
 690};
 691MODULE_DEVICE_TABLE(of, sunxi_pinctrl_match);
 692
 693static int sunxi_pinctrl_add_function(struct sunxi_pinctrl *pctl,
 694                                        const char *name)
 695{
 696        struct sunxi_pinctrl_function *func = pctl->functions;
 697
 698        while (func->name) {
 699                /* function already there */
 700                if (strcmp(func->name, name) == 0) {
 701                        func->ngroups++;
 702                        return -EEXIST;
 703                }
 704                func++;
 705        }
 706
 707        func->name = name;
 708        func->ngroups = 1;
 709
 710        pctl->nfunctions++;
 711
 712        return 0;
 713}
 714
 715static int sunxi_pinctrl_build_state(struct platform_device *pdev)
 716{
 717        struct sunxi_pinctrl *pctl = platform_get_drvdata(pdev);
 718        int i;
 719
 720        pctl->ngroups = pctl->desc->npins;
 721
 722        /* Allocate groups */
 723        pctl->groups = devm_kzalloc(&pdev->dev,
 724                                    pctl->ngroups * sizeof(*pctl->groups),
 725                                    GFP_KERNEL);
 726        if (!pctl->groups)
 727                return -ENOMEM;
 728
 729        for (i = 0; i < pctl->desc->npins; i++) {
 730                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
 731                struct sunxi_pinctrl_group *group = pctl->groups + i;
 732
 733                group->name = pin->pin.name;
 734                group->pin = pin->pin.number;
 735        }
 736
 737        /*
 738         * We suppose that we won't have any more functions than pins,
 739         * we'll reallocate that later anyway
 740         */
 741        pctl->functions = devm_kzalloc(&pdev->dev,
 742                                pctl->desc->npins * sizeof(*pctl->functions),
 743                                GFP_KERNEL);
 744        if (!pctl->functions)
 745                return -ENOMEM;
 746
 747        /* Count functions and their associated groups */
 748        for (i = 0; i < pctl->desc->npins; i++) {
 749                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
 750                struct sunxi_desc_function *func = pin->functions;
 751
 752                while (func->name) {
 753                        sunxi_pinctrl_add_function(pctl, func->name);
 754                        func++;
 755                }
 756        }
 757
 758        pctl->functions = krealloc(pctl->functions,
 759                                pctl->nfunctions * sizeof(*pctl->functions),
 760                                GFP_KERNEL);
 761
 762        for (i = 0; i < pctl->desc->npins; i++) {
 763                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
 764                struct sunxi_desc_function *func = pin->functions;
 765
 766                while (func->name) {
 767                        struct sunxi_pinctrl_function *func_item;
 768                        const char **func_grp;
 769
 770                        func_item = sunxi_pinctrl_find_function_by_name(pctl,
 771                                                                        func->name);
 772                        if (!func_item)
 773                                return -EINVAL;
 774
 775                        if (!func_item->groups) {
 776                                func_item->groups =
 777                                        devm_kzalloc(&pdev->dev,
 778                                                     func_item->ngroups * sizeof(*func_item->groups),
 779                                                     GFP_KERNEL);
 780                                if (!func_item->groups)
 781                                        return -ENOMEM;
 782                        }
 783
 784                        func_grp = func_item->groups;
 785                        while (*func_grp)
 786                                func_grp++;
 787
 788                        *func_grp = pin->pin.name;
 789                        func++;
 790                }
 791        }
 792
 793        return 0;
 794}
 795
 796static int sunxi_pinctrl_probe(struct platform_device *pdev)
 797{
 798        struct device_node *node = pdev->dev.of_node;
 799        const struct of_device_id *device;
 800        struct pinctrl_pin_desc *pins;
 801        struct sunxi_pinctrl *pctl;
 802        int i, ret, last_pin;
 803        struct clk *clk;
 804
 805        pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
 806        if (!pctl)
 807                return -ENOMEM;
 808        platform_set_drvdata(pdev, pctl);
 809
 810        spin_lock_init(&pctl->lock);
 811
 812        pctl->membase = of_iomap(node, 0);
 813        if (!pctl->membase)
 814                return -ENOMEM;
 815
 816        device = of_match_device(sunxi_pinctrl_match, &pdev->dev);
 817        if (!device)
 818                return -ENODEV;
 819
 820        pctl->desc = (struct sunxi_pinctrl_desc *)device->data;
 821
 822        ret = sunxi_pinctrl_build_state(pdev);
 823        if (ret) {
 824                dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
 825                return ret;
 826        }
 827
 828        pins = devm_kzalloc(&pdev->dev,
 829                            pctl->desc->npins * sizeof(*pins),
 830                            GFP_KERNEL);
 831        if (!pins)
 832                return -ENOMEM;
 833
 834        for (i = 0; i < pctl->desc->npins; i++)
 835                pins[i] = pctl->desc->pins[i].pin;
 836
 837        sunxi_pctrl_desc.name = dev_name(&pdev->dev);
 838        sunxi_pctrl_desc.owner = THIS_MODULE;
 839        sunxi_pctrl_desc.pins = pins;
 840        sunxi_pctrl_desc.npins = pctl->desc->npins;
 841        pctl->dev = &pdev->dev;
 842        pctl->pctl_dev = pinctrl_register(&sunxi_pctrl_desc,
 843                                          &pdev->dev, pctl);
 844        if (!pctl->pctl_dev) {
 845                dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
 846                return -EINVAL;
 847        }
 848
 849        pctl->chip = devm_kzalloc(&pdev->dev, sizeof(*pctl->chip), GFP_KERNEL);
 850        if (!pctl->chip) {
 851                ret = -ENOMEM;
 852                goto pinctrl_error;
 853        }
 854
 855        last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
 856        pctl->chip = &sunxi_pinctrl_gpio_chip;
 857        pctl->chip->ngpio = round_up(last_pin, PINS_PER_BANK);
 858        pctl->chip->label = dev_name(&pdev->dev);
 859        pctl->chip->dev = &pdev->dev;
 860        pctl->chip->base = 0;
 861
 862        ret = gpiochip_add(pctl->chip);
 863        if (ret)
 864                goto pinctrl_error;
 865
 866        for (i = 0; i < pctl->desc->npins; i++) {
 867                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
 868
 869                ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev),
 870                                             pin->pin.number,
 871                                             pin->pin.number, 1);
 872                if (ret)
 873                        goto gpiochip_error;
 874        }
 875
 876        clk = devm_clk_get(&pdev->dev, NULL);
 877        if (IS_ERR(clk)) {
 878                ret = PTR_ERR(clk);
 879                goto gpiochip_error;
 880        }
 881
 882        clk_prepare_enable(clk);
 883
 884        pctl->irq = irq_of_parse_and_map(node, 0);
 885        if (!pctl->irq) {
 886                ret = -EINVAL;
 887                goto gpiochip_error;
 888        }
 889
 890        pctl->domain = irq_domain_add_linear(node, SUNXI_IRQ_NUMBER,
 891                                             &irq_domain_simple_ops, NULL);
 892        if (!pctl->domain) {
 893                dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
 894                ret = -ENOMEM;
 895                goto gpiochip_error;
 896        }
 897
 898        for (i = 0; i < SUNXI_IRQ_NUMBER; i++) {
 899                int irqno = irq_create_mapping(pctl->domain, i);
 900
 901                irq_set_chip_and_handler(irqno, &sunxi_pinctrl_irq_chip,
 902                                         handle_simple_irq);
 903                irq_set_chip_data(irqno, pctl);
 904        };
 905
 906        irq_set_chained_handler(pctl->irq, sunxi_pinctrl_irq_handler);
 907        irq_set_handler_data(pctl->irq, pctl);
 908
 909        dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
 910
 911        return 0;
 912
 913gpiochip_error:
 914        if (gpiochip_remove(pctl->chip))
 915                dev_err(&pdev->dev, "failed to remove gpio chip\n");
 916pinctrl_error:
 917        pinctrl_unregister(pctl->pctl_dev);
 918        return ret;
 919}
 920
 921static struct platform_driver sunxi_pinctrl_driver = {
 922        .probe = sunxi_pinctrl_probe,
 923        .driver = {
 924                .name = "sunxi-pinctrl",
 925                .owner = THIS_MODULE,
 926                .of_match_table = sunxi_pinctrl_match,
 927        },
 928};
 929module_platform_driver(sunxi_pinctrl_driver);
 930
 931MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
 932MODULE_DESCRIPTION("Allwinner A1X pinctrl driver");
 933MODULE_LICENSE("GPL");
 934
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.