linux/drivers/pinctrl/pinctrl-samsung.c
<<
>>
Prefs
   1/*
   2 * pin-controller/pin-mux/pin-config/gpio-driver for Samsung's SoC's.
   3 *
   4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
   5 *              http://www.samsung.com
   6 * Copyright (c) 2012 Linaro Ltd
   7 *              http://www.linaro.org
   8 *
   9 * Author: Thomas Abraham <thomas.ab@samsung.com>
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License as published by
  13 * the Free Software Foundation; either version 2 of the License, or
  14 * (at your option) any later version.
  15 *
  16 * This driver implements the Samsung pinctrl driver. It supports setting up of
  17 * pinmux and pinconf configurations. The gpiolib interface is also included.
  18 * External interrupt (gpio and wakeup) support are not included in this driver
  19 * but provides extensions to which platform specific implementation of the gpio
  20 * and wakeup interrupts can be hooked to.
  21 */
  22
  23#include <linux/module.h>
  24#include <linux/platform_device.h>
  25#include <linux/io.h>
  26#include <linux/slab.h>
  27#include <linux/err.h>
  28#include <linux/gpio.h>
  29
  30#include "core.h"
  31#include "pinctrl-samsung.h"
  32
  33#define GROUP_SUFFIX            "-grp"
  34#define GSUFFIX_LEN             sizeof(GROUP_SUFFIX)
  35#define FUNCTION_SUFFIX         "-mux"
  36#define FSUFFIX_LEN             sizeof(FUNCTION_SUFFIX)
  37
  38/* list of all possible config options supported */
  39struct pin_config {
  40        char            *prop_cfg;
  41        unsigned int    cfg_type;
  42} pcfgs[] = {
  43        { "samsung,pin-pud", PINCFG_TYPE_PUD },
  44        { "samsung,pin-drv", PINCFG_TYPE_DRV },
  45        { "samsung,pin-con-pdn", PINCFG_TYPE_CON_PDN },
  46        { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },
  47};
  48
  49/* check if the selector is a valid pin group selector */
  50static int samsung_get_group_count(struct pinctrl_dev *pctldev)
  51{
  52        struct samsung_pinctrl_drv_data *drvdata;
  53
  54        drvdata = pinctrl_dev_get_drvdata(pctldev);
  55        return drvdata->nr_groups;
  56}
  57
  58/* return the name of the group selected by the group selector */
  59static const char *samsung_get_group_name(struct pinctrl_dev *pctldev,
  60                                                unsigned selector)
  61{
  62        struct samsung_pinctrl_drv_data *drvdata;
  63
  64        drvdata = pinctrl_dev_get_drvdata(pctldev);
  65        return drvdata->pin_groups[selector].name;
  66}
  67
  68/* return the pin numbers associated with the specified group */
  69static int samsung_get_group_pins(struct pinctrl_dev *pctldev,
  70                unsigned selector, const unsigned **pins, unsigned *num_pins)
  71{
  72        struct samsung_pinctrl_drv_data *drvdata;
  73
  74        drvdata = pinctrl_dev_get_drvdata(pctldev);
  75        *pins = drvdata->pin_groups[selector].pins;
  76        *num_pins = drvdata->pin_groups[selector].num_pins;
  77        return 0;
  78}
  79
  80/* create pinctrl_map entries by parsing device tree nodes */
  81static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
  82                        struct device_node *np, struct pinctrl_map **maps,
  83                        unsigned *nmaps)
  84{
  85        struct device *dev = pctldev->dev;
  86        struct pinctrl_map *map;
  87        unsigned long *cfg = NULL;
  88        char *gname, *fname;
  89        int cfg_cnt = 0, map_cnt = 0, idx = 0;
  90
  91        /* count the number of config options specfied in the node */
  92        for (idx = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
  93                if (of_find_property(np, pcfgs[idx].prop_cfg, NULL))
  94                        cfg_cnt++;
  95        }
  96
  97        /*
  98         * Find out the number of map entries to create. All the config options
  99         * can be accomadated into a single config map entry.
 100         */
 101        if (cfg_cnt)
 102                map_cnt = 1;
 103        if (of_find_property(np, "samsung,pin-function", NULL))
 104                map_cnt++;
 105        if (!map_cnt) {
 106                dev_err(dev, "node %s does not have either config or function "
 107                                "configurations\n", np->name);
 108                return -EINVAL;
 109        }
 110
 111        /* Allocate memory for pin-map entries */
 112        map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL);
 113        if (!map) {
 114                dev_err(dev, "could not alloc memory for pin-maps\n");
 115                return -ENOMEM;
 116        }
 117        *nmaps = 0;
 118
 119        /*
 120         * Allocate memory for pin group name. The pin group name is derived
 121         * from the node name from which these map entries are be created.
 122         */
 123        gname = kzalloc(strlen(np->name) + GSUFFIX_LEN, GFP_KERNEL);
 124        if (!gname) {
 125                dev_err(dev, "failed to alloc memory for group name\n");
 126                goto free_map;
 127        }
 128        sprintf(gname, "%s%s", np->name, GROUP_SUFFIX);
 129
 130        /*
 131         * don't have config options? then skip over to creating function
 132         * map entries.
 133         */
 134        if (!cfg_cnt)
 135                goto skip_cfgs;
 136
 137        /* Allocate memory for config entries */
 138        cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL);
 139        if (!cfg) {
 140                dev_err(dev, "failed to alloc memory for configs\n");
 141                goto free_gname;
 142        }
 143
 144        /* Prepare a list of config settings */
 145        for (idx = 0, cfg_cnt = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
 146                u32 value;
 147                if (!of_property_read_u32(np, pcfgs[idx].prop_cfg, &value))
 148                        cfg[cfg_cnt++] =
 149                                PINCFG_PACK(pcfgs[idx].cfg_type, value);
 150        }
 151
 152        /* create the config map entry */
 153        map[*nmaps].data.configs.group_or_pin = gname;
 154        map[*nmaps].data.configs.configs = cfg;
 155        map[*nmaps].data.configs.num_configs = cfg_cnt;
 156        map[*nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
 157        *nmaps += 1;
 158
 159skip_cfgs:
 160        /* create the function map entry */
 161        if (of_find_property(np, "samsung,pin-function", NULL)) {
 162                fname = kzalloc(strlen(np->name) + FSUFFIX_LEN, GFP_KERNEL);
 163                if (!fname) {
 164                        dev_err(dev, "failed to alloc memory for func name\n");
 165                        goto free_cfg;
 166                }
 167                sprintf(fname, "%s%s", np->name, FUNCTION_SUFFIX);
 168
 169                map[*nmaps].data.mux.group = gname;
 170                map[*nmaps].data.mux.function = fname;
 171                map[*nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
 172                *nmaps += 1;
 173        }
 174
 175        *maps = map;
 176        return 0;
 177
 178free_cfg:
 179        kfree(cfg);
 180free_gname:
 181        kfree(gname);
 182free_map:
 183        kfree(map);
 184        return -ENOMEM;
 185}
 186
 187/* free the memory allocated to hold the pin-map table */
 188static void samsung_dt_free_map(struct pinctrl_dev *pctldev,
 189                             struct pinctrl_map *map, unsigned num_maps)
 190{
 191        int idx;
 192
 193        for (idx = 0; idx < num_maps; idx++) {
 194                if (map[idx].type == PIN_MAP_TYPE_MUX_GROUP) {
 195                        kfree(map[idx].data.mux.function);
 196                        if (!idx)
 197                                kfree(map[idx].data.mux.group);
 198                } else if (map->type == PIN_MAP_TYPE_CONFIGS_GROUP) {
 199                        kfree(map[idx].data.configs.configs);
 200                        if (!idx)
 201                                kfree(map[idx].data.configs.group_or_pin);
 202                }
 203        };
 204
 205        kfree(map);
 206}
 207
 208/* list of pinctrl callbacks for the pinctrl core */
 209static struct pinctrl_ops samsung_pctrl_ops = {
 210        .get_groups_count       = samsung_get_group_count,
 211        .get_group_name         = samsung_get_group_name,
 212        .get_group_pins         = samsung_get_group_pins,
 213        .dt_node_to_map         = samsung_dt_node_to_map,
 214        .dt_free_map            = samsung_dt_free_map,
 215};
 216
 217/* check if the selector is a valid pin function selector */
 218static int samsung_get_functions_count(struct pinctrl_dev *pctldev)
 219{
 220        struct samsung_pinctrl_drv_data *drvdata;
 221
 222        drvdata = pinctrl_dev_get_drvdata(pctldev);
 223        return drvdata->nr_functions;
 224}
 225
 226/* return the name of the pin function specified */
 227static const char *samsung_pinmux_get_fname(struct pinctrl_dev *pctldev,
 228                                                unsigned selector)
 229{
 230        struct samsung_pinctrl_drv_data *drvdata;
 231
 232        drvdata = pinctrl_dev_get_drvdata(pctldev);
 233        return drvdata->pmx_functions[selector].name;
 234}
 235
 236/* return the groups associated for the specified function selector */
 237static int samsung_pinmux_get_groups(struct pinctrl_dev *pctldev,
 238                unsigned selector, const char * const **groups,
 239                unsigned * const num_groups)
 240{
 241        struct samsung_pinctrl_drv_data *drvdata;
 242
 243        drvdata = pinctrl_dev_get_drvdata(pctldev);
 244        *groups = drvdata->pmx_functions[selector].groups;
 245        *num_groups = drvdata->pmx_functions[selector].num_groups;
 246        return 0;
 247}
 248
 249/*
 250 * given a pin number that is local to a pin controller, find out the pin bank
 251 * and the register base of the pin bank.
 252 */
 253static void pin_to_reg_bank(struct gpio_chip *gc, unsigned pin,
 254                        void __iomem **reg, u32 *offset,
 255                        struct samsung_pin_bank **bank)
 256{
 257        struct samsung_pinctrl_drv_data *drvdata;
 258        struct samsung_pin_bank *b;
 259
 260        drvdata = dev_get_drvdata(gc->dev);
 261        b = drvdata->ctrl->pin_banks;
 262
 263        while ((pin >= b->pin_base) &&
 264                        ((b->pin_base + b->nr_pins - 1) < pin))
 265                b++;
 266
 267        *reg = drvdata->virt_base + b->pctl_offset;
 268        *offset = pin - b->pin_base;
 269        if (bank)
 270                *bank = b;
 271
 272        /* some banks have two config registers in a single bank */
 273        if (*offset * b->func_width > BITS_PER_LONG)
 274                *reg += 4;
 275}
 276
 277/* enable or disable a pinmux function */
 278static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
 279                                        unsigned group, bool enable)
 280{
 281        struct samsung_pinctrl_drv_data *drvdata;
 282        const unsigned int *pins;
 283        struct samsung_pin_bank *bank;
 284        void __iomem *reg;
 285        u32 mask, shift, data, pin_offset, cnt;
 286
 287        drvdata = pinctrl_dev_get_drvdata(pctldev);
 288        pins = drvdata->pin_groups[group].pins;
 289
 290        /*
 291         * for each pin in the pin group selected, program the correspoding pin
 292         * pin function number in the config register.
 293         */
 294        for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) {
 295                pin_to_reg_bank(drvdata->gc, pins[cnt] - drvdata->ctrl->base,
 296                                &reg, &pin_offset, &bank);
 297                mask = (1 << bank->func_width) - 1;
 298                shift = pin_offset * bank->func_width;
 299
 300                data = readl(reg);
 301                data &= ~(mask << shift);
 302                if (enable)
 303                        data |= drvdata->pin_groups[group].func << shift;
 304                writel(data, reg);
 305        }
 306}
 307
 308/* enable a specified pinmux by writing to registers */
 309static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
 310                                        unsigned group)
 311{
 312        samsung_pinmux_setup(pctldev, selector, group, true);
 313        return 0;
 314}
 315
 316/* disable a specified pinmux by writing to registers */
 317static void samsung_pinmux_disable(struct pinctrl_dev *pctldev,
 318                                        unsigned selector, unsigned group)
 319{
 320        samsung_pinmux_setup(pctldev, selector, group, false);
 321}
 322
 323/*
 324 * The calls to gpio_direction_output() and gpio_direction_input()
 325 * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
 326 * function called from the gpiolib interface).
 327 */
 328static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
 329                struct pinctrl_gpio_range *range, unsigned offset, bool input)
 330{
 331        struct samsung_pin_bank *bank;
 332        void __iomem *reg;
 333        u32 data, pin_offset, mask, shift;
 334
 335        pin_to_reg_bank(range->gc, offset, &reg, &pin_offset, &bank);
 336        mask = (1 << bank->func_width) - 1;
 337        shift = pin_offset * bank->func_width;
 338
 339        data = readl(reg);
 340        data &= ~(mask << shift);
 341        if (!input)
 342                data |= FUNC_OUTPUT << shift;
 343        writel(data, reg);
 344        return 0;
 345}
 346
 347/* list of pinmux callbacks for the pinmux vertical in pinctrl core */
 348static struct pinmux_ops samsung_pinmux_ops = {
 349        .get_functions_count    = samsung_get_functions_count,
 350        .get_function_name      = samsung_pinmux_get_fname,
 351        .get_function_groups    = samsung_pinmux_get_groups,
 352        .enable                 = samsung_pinmux_enable,
 353        .disable                = samsung_pinmux_disable,
 354        .gpio_set_direction     = samsung_pinmux_gpio_set_direction,
 355};
 356
 357/* set or get the pin config settings for a specified pin */
 358static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
 359                                unsigned long *config, bool set)
 360{
 361        struct samsung_pinctrl_drv_data *drvdata;
 362        struct samsung_pin_bank *bank;
 363        void __iomem *reg_base;
 364        enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config);
 365        u32 data, width, pin_offset, mask, shift;
 366        u32 cfg_value, cfg_reg;
 367
 368        drvdata = pinctrl_dev_get_drvdata(pctldev);
 369        pin_to_reg_bank(drvdata->gc, pin - drvdata->ctrl->base, &reg_base,
 370                                        &pin_offset, &bank);
 371
 372        switch (cfg_type) {
 373        case PINCFG_TYPE_PUD:
 374                width = bank->pud_width;
 375                cfg_reg = PUD_REG;
 376                break;
 377        case PINCFG_TYPE_DRV:
 378                width = bank->drv_width;
 379                cfg_reg = DRV_REG;
 380                break;
 381        case PINCFG_TYPE_CON_PDN:
 382                width = bank->conpdn_width;
 383                cfg_reg = CONPDN_REG;
 384                break;
 385        case PINCFG_TYPE_PUD_PDN:
 386                width = bank->pudpdn_width;
 387                cfg_reg = PUDPDN_REG;
 388                break;
 389        default:
 390                WARN_ON(1);
 391                return -EINVAL;
 392        }
 393
 394        mask = (1 << width) - 1;
 395        shift = pin_offset * width;
 396        data = readl(reg_base + cfg_reg);
 397
 398        if (set) {
 399                cfg_value = PINCFG_UNPACK_VALUE(*config);
 400                data &= ~(mask << shift);
 401                data |= (cfg_value << shift);
 402                writel(data, reg_base + cfg_reg);
 403        } else {
 404                data >>= shift;
 405                data &= mask;
 406                *config = PINCFG_PACK(cfg_type, data);
 407        }
 408        return 0;
 409}
 410
 411/* set the pin config settings for a specified pin */
 412static int samsung_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
 413                                unsigned long config)
 414{
 415        return samsung_pinconf_rw(pctldev, pin, &config, true);
 416}
 417
 418/* get the pin config settings for a specified pin */
 419static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
 420                                        unsigned long *config)
 421{
 422        return samsung_pinconf_rw(pctldev, pin, config, false);
 423}
 424
 425/* set the pin config settings for a specified pin group */
 426static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
 427                        unsigned group, unsigned long config)
 428{
 429        struct samsung_pinctrl_drv_data *drvdata;
 430        const unsigned int *pins;
 431        unsigned int cnt;
 432
 433        drvdata = pinctrl_dev_get_drvdata(pctldev);
 434        pins = drvdata->pin_groups[group].pins;
 435
 436        for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++)
 437                samsung_pinconf_set(pctldev, pins[cnt], config);
 438
 439        return 0;
 440}
 441
 442/* get the pin config settings for a specified pin group */
 443static int samsung_pinconf_group_get(struct pinctrl_dev *pctldev,
 444                                unsigned int group, unsigned long *config)
 445{
 446        struct samsung_pinctrl_drv_data *drvdata;
 447        const unsigned int *pins;
 448
 449        drvdata = pinctrl_dev_get_drvdata(pctldev);
 450        pins = drvdata->pin_groups[group].pins;
 451        samsung_pinconf_get(pctldev, pins[0], config);
 452        return 0;
 453}
 454
 455/* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */
 456static struct pinconf_ops samsung_pinconf_ops = {
 457        .pin_config_get         = samsung_pinconf_get,
 458        .pin_config_set         = samsung_pinconf_set,
 459        .pin_config_group_get   = samsung_pinconf_group_get,
 460        .pin_config_group_set   = samsung_pinconf_group_set,
 461};
 462
 463/* gpiolib gpio_set callback function */
 464static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
 465{
 466        void __iomem *reg;
 467        u32 pin_offset, data;
 468
 469        pin_to_reg_bank(gc, offset, &reg, &pin_offset, NULL);
 470        data = readl(reg + DAT_REG);
 471        data &= ~(1 << pin_offset);
 472        if (value)
 473                data |= 1 << pin_offset;
 474        writel(data, reg + DAT_REG);
 475}
 476
 477/* gpiolib gpio_get callback function */
 478static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
 479{
 480        void __iomem *reg;
 481        u32 pin_offset, data;
 482
 483        pin_to_reg_bank(gc, offset, &reg, &pin_offset, NULL);
 484        data = readl(reg + DAT_REG);
 485        data >>= pin_offset;
 486        data &= 1;
 487        return data;
 488}
 489
 490/*
 491 * gpiolib gpio_direction_input callback function. The setting of the pin
 492 * mux function as 'gpio input' will be handled by the pinctrl susbsystem
 493 * interface.
 494 */
 495static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
 496{
 497        return pinctrl_gpio_direction_input(gc->base + offset);
 498}
 499
 500/*
 501 * gpiolib gpio_direction_output callback function. The setting of the pin
 502 * mux function as 'gpio output' will be handled by the pinctrl susbsystem
 503 * interface.
 504 */
 505static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
 506                                                        int value)
 507{
 508        samsung_gpio_set(gc, offset, value);
 509        return pinctrl_gpio_direction_output(gc->base + offset);
 510}
 511
 512/*
 513 * Parse the pin names listed in the 'samsung,pins' property and convert it
 514 * into a list of gpio numbers are create a pin group from it.
 515 */
 516static int __devinit samsung_pinctrl_parse_dt_pins(struct platform_device *pdev,
 517                        struct device_node *cfg_np, struct pinctrl_desc *pctl,
 518                        unsigned int **pin_list, unsigned int *npins)
 519{
 520        struct device *dev = &pdev->dev;
 521        struct property *prop;
 522        struct pinctrl_pin_desc const *pdesc = pctl->pins;
 523        unsigned int idx = 0, cnt;
 524        const char *pin_name;
 525
 526        *npins = of_property_count_strings(cfg_np, "samsung,pins");
 527        if (*npins < 0) {
 528                dev_err(dev, "invalid pin list in %s node", cfg_np->name);
 529                return -EINVAL;
 530        }
 531
 532        *pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL);
 533        if (!*pin_list) {
 534                dev_err(dev, "failed to allocate memory for pin list\n");
 535                return -ENOMEM;
 536        }
 537
 538        of_property_for_each_string(cfg_np, "samsung,pins", prop, pin_name) {
 539                for (cnt = 0; cnt < pctl->npins; cnt++) {
 540                        if (pdesc[cnt].name) {
 541                                if (!strcmp(pin_name, pdesc[cnt].name)) {
 542                                        (*pin_list)[idx++] = pdesc[cnt].number;
 543                                        break;
 544                                }
 545                        }
 546                }
 547                if (cnt == pctl->npins) {
 548                        dev_err(dev, "pin %s not valid in %s node\n",
 549                                        pin_name, cfg_np->name);
 550                        devm_kfree(dev, *pin_list);
 551                        return -EINVAL;
 552                }
 553        }
 554
 555        return 0;
 556}
 557
 558/*
 559 * Parse the information about all the available pin groups and pin functions
 560 * from device node of the pin-controller. A pin group is formed with all
 561 * the pins listed in the "samsung,pins" property.
 562 */
 563static int __devinit samsung_pinctrl_parse_dt(struct platform_device *pdev,
 564                                struct samsung_pinctrl_drv_data *drvdata)
 565{
 566        struct device *dev = &pdev->dev;
 567        struct device_node *dev_np = dev->of_node;
 568        struct device_node *cfg_np;
 569        struct samsung_pin_group *groups, *grp;
 570        struct samsung_pmx_func *functions, *func;
 571        unsigned *pin_list;
 572        unsigned int npins, grp_cnt, func_idx = 0;
 573        char *gname, *fname;
 574        int ret;
 575
 576        grp_cnt = of_get_child_count(dev_np);
 577        if (!grp_cnt)
 578                return -EINVAL;
 579
 580        groups = devm_kzalloc(dev, grp_cnt * sizeof(*groups), GFP_KERNEL);
 581        if (!groups) {
 582                dev_err(dev, "failed allocate memory for ping group list\n");
 583                return -EINVAL;
 584        }
 585        grp = groups;
 586
 587        functions = devm_kzalloc(dev, grp_cnt * sizeof(*functions), GFP_KERNEL);
 588        if (!functions) {
 589                dev_err(dev, "failed to allocate memory for function list\n");
 590                return -EINVAL;
 591        }
 592        func = functions;
 593
 594        /*
 595         * Iterate over all the child nodes of the pin controller node
 596         * and create pin groups and pin function lists.
 597         */
 598        for_each_child_of_node(dev_np, cfg_np) {
 599                u32 function;
 600                if (of_find_property(cfg_np, "interrupt-controller", NULL))
 601                        continue;
 602
 603                ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np,
 604                                        &drvdata->pctl, &pin_list, &npins);
 605                if (ret)
 606                        return ret;
 607
 608                /* derive pin group name from the node name */
 609                gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN,
 610                                        GFP_KERNEL);
 611                if (!gname) {
 612                        dev_err(dev, "failed to alloc memory for group name\n");
 613                        return -ENOMEM;
 614                }
 615                sprintf(gname, "%s%s", cfg_np->name, GROUP_SUFFIX);
 616
 617                grp->name = gname;
 618                grp->pins = pin_list;
 619                grp->num_pins = npins;
 620                of_property_read_u32(cfg_np, "samsung,pin-function", &function);
 621                grp->func = function;
 622                grp++;
 623
 624                if (!of_find_property(cfg_np, "samsung,pin-function", NULL))
 625                        continue;
 626
 627                /* derive function name from the node name */
 628                fname = devm_kzalloc(dev, strlen(cfg_np->name) + FSUFFIX_LEN,
 629                                        GFP_KERNEL);
 630                if (!fname) {
 631                        dev_err(dev, "failed to alloc memory for func name\n");
 632                        return -ENOMEM;
 633                }
 634                sprintf(fname, "%s%s", cfg_np->name, FUNCTION_SUFFIX);
 635
 636                func->name = fname;
 637                func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL);
 638                if (!func->groups) {
 639                        dev_err(dev, "failed to alloc memory for group list "
 640                                        "in pin function");
 641                        return -ENOMEM;
 642                }
 643                func->groups[0] = gname;
 644                func->num_groups = 1;
 645                func++;
 646                func_idx++;
 647        }
 648
 649        drvdata->pin_groups = groups;
 650        drvdata->nr_groups = grp_cnt;
 651        drvdata->pmx_functions = functions;
 652        drvdata->nr_functions = func_idx;
 653
 654        return 0;
 655}
 656
 657/* register the pinctrl interface with the pinctrl subsystem */
 658static int __devinit samsung_pinctrl_register(struct platform_device *pdev,
 659                                struct samsung_pinctrl_drv_data *drvdata)
 660{
 661        struct pinctrl_desc *ctrldesc = &drvdata->pctl;
 662        struct pinctrl_pin_desc *pindesc, *pdesc;
 663        struct samsung_pin_bank *pin_bank;
 664        char *pin_names;
 665        int pin, bank, ret;
 666
 667        ctrldesc->name = "samsung-pinctrl";
 668        ctrldesc->owner = THIS_MODULE;
 669        ctrldesc->pctlops = &samsung_pctrl_ops;
 670        ctrldesc->pmxops = &samsung_pinmux_ops;
 671        ctrldesc->confops = &samsung_pinconf_ops;
 672
 673        pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
 674                        drvdata->ctrl->nr_pins, GFP_KERNEL);
 675        if (!pindesc) {
 676                dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n");
 677                return -ENOMEM;
 678        }
 679        ctrldesc->pins = pindesc;
 680        ctrldesc->npins = drvdata->ctrl->nr_pins;
 681        ctrldesc->npins = drvdata->ctrl->nr_pins;
 682
 683        /* dynamically populate the pin number and pin name for pindesc */
 684        for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++)
 685                pdesc->number = pin + drvdata->ctrl->base;
 686
 687        /*
 688         * allocate space for storing the dynamically generated names for all
 689         * the pins which belong to this pin-controller.
 690         */
 691        pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH *
 692                                        drvdata->ctrl->nr_pins, GFP_KERNEL);
 693        if (!pin_names) {
 694                dev_err(&pdev->dev, "mem alloc for pin names failed\n");
 695                return -ENOMEM;
 696        }
 697
 698        /* for each pin, the name of the pin is pin-bank name + pin number */
 699        for (bank = 0; bank < drvdata->ctrl->nr_banks; bank++) {
 700                pin_bank = &drvdata->ctrl->pin_banks[bank];
 701                for (pin = 0; pin < pin_bank->nr_pins; pin++) {
 702                        sprintf(pin_names, "%s-%d", pin_bank->name, pin);
 703                        pdesc = pindesc + pin_bank->pin_base + pin;
 704                        pdesc->name = pin_names;
 705                        pin_names += PIN_NAME_LENGTH;
 706                }
 707        }
 708
 709        drvdata->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, drvdata);
 710        if (!drvdata->pctl_dev) {
 711                dev_err(&pdev->dev, "could not register pinctrl driver\n");
 712                return -EINVAL;
 713        }
 714
 715        drvdata->grange.name = "samsung-pctrl-gpio-range";
 716        drvdata->grange.id = 0;
 717        drvdata->grange.base = drvdata->ctrl->base;
 718        drvdata->grange.npins = drvdata->ctrl->nr_pins;
 719        drvdata->grange.gc = drvdata->gc;
 720        pinctrl_add_gpio_range(drvdata->pctl_dev, &drvdata->grange);
 721
 722        ret = samsung_pinctrl_parse_dt(pdev, drvdata);
 723        if (ret) {
 724                pinctrl_unregister(drvdata->pctl_dev);
 725                return ret;
 726        }
 727
 728        return 0;
 729}
 730
 731/* register the gpiolib interface with the gpiolib subsystem */
 732static int __devinit samsung_gpiolib_register(struct platform_device *pdev,
 733                                struct samsung_pinctrl_drv_data *drvdata)
 734{
 735        struct gpio_chip *gc;
 736        int ret;
 737
 738        gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
 739        if (!gc) {
 740                dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n");
 741                return -ENOMEM;
 742        }
 743
 744        drvdata->gc = gc;
 745        gc->base = drvdata->ctrl->base;
 746        gc->ngpio = drvdata->ctrl->nr_pins;
 747        gc->dev = &pdev->dev;
 748        gc->set = samsung_gpio_set;
 749        gc->get = samsung_gpio_get;
 750        gc->direction_input = samsung_gpio_direction_input;
 751        gc->direction_output = samsung_gpio_direction_output;
 752        gc->label = drvdata->ctrl->label;
 753        gc->owner = THIS_MODULE;
 754        ret = gpiochip_add(gc);
 755        if (ret) {
 756                dev_err(&pdev->dev, "failed to register gpio_chip %s, error "
 757                                        "code: %d\n", gc->label, ret);
 758                return ret;
 759        }
 760
 761        return 0;
 762}
 763
 764/* unregister the gpiolib interface with the gpiolib subsystem */
 765static int __devinit samsung_gpiolib_unregister(struct platform_device *pdev,
 766                                struct samsung_pinctrl_drv_data *drvdata)
 767{
 768        int ret = gpiochip_remove(drvdata->gc);
 769        if (ret) {
 770                dev_err(&pdev->dev, "gpio chip remove failed\n");
 771                return ret;
 772        }
 773        return 0;
 774}
 775
 776static const struct of_device_id samsung_pinctrl_dt_match[];
 777
 778/* retrieve the soc specific data */
 779static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 780                                struct platform_device *pdev)
 781{
 782        int id;
 783        const struct of_device_id *match;
 784        const struct device_node *node = pdev->dev.of_node;
 785
 786        id = of_alias_get_id(pdev->dev.of_node, "pinctrl");
 787        if (id < 0) {
 788                dev_err(&pdev->dev, "failed to get alias id\n");
 789                return NULL;
 790        }
 791        match = of_match_node(samsung_pinctrl_dt_match, node);
 792        return (struct samsung_pin_ctrl *)match->data + id;
 793}
 794
 795static int __devinit samsung_pinctrl_probe(struct platform_device *pdev)
 796{
 797        struct samsung_pinctrl_drv_data *drvdata;
 798        struct device *dev = &pdev->dev;
 799        struct samsung_pin_ctrl *ctrl;
 800        struct resource *res;
 801        int ret;
 802
 803        if (!dev->of_node) {
 804                dev_err(dev, "device tree node not found\n");
 805                return -ENODEV;
 806        }
 807
 808        ctrl = samsung_pinctrl_get_soc_data(pdev);
 809        if (!ctrl) {
 810                dev_err(&pdev->dev, "driver data not available\n");
 811                return -EINVAL;
 812        }
 813
 814        drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
 815        if (!drvdata) {
 816                dev_err(dev, "failed to allocate memory for driver's "
 817                                "private data\n");
 818                return -ENOMEM;
 819        }
 820        drvdata->ctrl = ctrl;
 821        drvdata->dev = dev;
 822
 823        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 824        if (!res) {
 825                dev_err(dev, "cannot find IO resource\n");
 826                return -ENOENT;
 827        }
 828
 829        drvdata->virt_base = devm_request_and_ioremap(&pdev->dev, res);
 830        if (!drvdata->virt_base) {
 831                dev_err(dev, "ioremap failed\n");
 832                return -ENODEV;
 833        }
 834
 835        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 836        if (res)
 837                drvdata->irq = res->start;
 838
 839        ret = samsung_gpiolib_register(pdev, drvdata);
 840        if (ret)
 841                return ret;
 842
 843        ret = samsung_pinctrl_register(pdev, drvdata);
 844        if (ret) {
 845                samsung_gpiolib_unregister(pdev, drvdata);
 846                return ret;
 847        }
 848
 849        if (ctrl->eint_gpio_init)
 850                ctrl->eint_gpio_init(drvdata);
 851        if (ctrl->eint_wkup_init)
 852                ctrl->eint_wkup_init(drvdata);
 853
 854        platform_set_drvdata(pdev, drvdata);
 855        return 0;
 856}
 857
 858static const struct of_device_id samsung_pinctrl_dt_match[] = {
 859        { .compatible = "samsung,pinctrl-exynos4210",
 860                .data = (void *)exynos4210_pin_ctrl },
 861        {},
 862};
 863MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match);
 864
 865static struct platform_driver samsung_pinctrl_driver = {
 866        .probe          = samsung_pinctrl_probe,
 867        .driver = {
 868                .name   = "samsung-pinctrl",
 869                .owner  = THIS_MODULE,
 870                .of_match_table = of_match_ptr(samsung_pinctrl_dt_match),
 871        },
 872};
 873
 874static int __init samsung_pinctrl_drv_register(void)
 875{
 876        return platform_driver_register(&samsung_pinctrl_driver);
 877}
 878postcore_initcall(samsung_pinctrl_drv_register);
 879
 880static void __exit samsung_pinctrl_drv_unregister(void)
 881{
 882        platform_driver_unregister(&samsung_pinctrl_driver);
 883}
 884module_exit(samsung_pinctrl_drv_unregister);
 885
 886MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
 887MODULE_DESCRIPTION("Samsung pinctrl driver");
 888MODULE_LICENSE("GPL v2");
 889
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.