linux/drivers/pinctrl/pinctrl-mvebu.c
<<
>>
Prefs
   1/*
   2 * Marvell MVEBU pinctrl core driver
   3 *
   4 * Authors: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
   5 *          Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 */
  12
  13#include <linux/platform_device.h>
  14#include <linux/module.h>
  15#include <linux/slab.h>
  16#include <linux/io.h>
  17#include <linux/of.h>
  18#include <linux/of_address.h>
  19#include <linux/of_platform.h>
  20#include <linux/err.h>
  21#include <linux/gpio.h>
  22#include <linux/pinctrl/machine.h>
  23#include <linux/pinctrl/pinconf.h>
  24#include <linux/pinctrl/pinctrl.h>
  25#include <linux/pinctrl/pinmux.h>
  26
  27#include "core.h"
  28#include "pinctrl-mvebu.h"
  29
  30#define MPPS_PER_REG    8
  31#define MPP_BITS        4
  32#define MPP_MASK        0xf
  33
  34struct mvebu_pinctrl_function {
  35        const char *name;
  36        const char **groups;
  37        unsigned num_groups;
  38};
  39
  40struct mvebu_pinctrl_group {
  41        const char *name;
  42        struct mvebu_mpp_ctrl *ctrl;
  43        struct mvebu_mpp_ctrl_setting *settings;
  44        unsigned num_settings;
  45        unsigned gid;
  46        unsigned *pins;
  47        unsigned npins;
  48};
  49
  50struct mvebu_pinctrl {
  51        struct device *dev;
  52        struct pinctrl_dev *pctldev;
  53        struct pinctrl_desc desc;
  54        void __iomem *base;
  55        struct mvebu_pinctrl_group *groups;
  56        unsigned num_groups;
  57        struct mvebu_pinctrl_function *functions;
  58        unsigned num_functions;
  59        u8 variant;
  60};
  61
  62static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_pid(
  63        struct mvebu_pinctrl *pctl, unsigned pid)
  64{
  65        unsigned n;
  66        for (n = 0; n < pctl->num_groups; n++) {
  67                if (pid >= pctl->groups[n].pins[0] &&
  68                    pid < pctl->groups[n].pins[0] +
  69                        pctl->groups[n].npins)
  70                        return &pctl->groups[n];
  71        }
  72        return NULL;
  73}
  74
  75static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_name(
  76        struct mvebu_pinctrl *pctl, const char *name)
  77{
  78        unsigned n;
  79        for (n = 0; n < pctl->num_groups; n++) {
  80                if (strcmp(name, pctl->groups[n].name) == 0)
  81                        return &pctl->groups[n];
  82        }
  83        return NULL;
  84}
  85
  86static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_val(
  87        struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp,
  88        unsigned long config)
  89{
  90        unsigned n;
  91        for (n = 0; n < grp->num_settings; n++) {
  92                if (config == grp->settings[n].val) {
  93                        if (!pctl->variant || (pctl->variant &
  94                                               grp->settings[n].variant))
  95                                return &grp->settings[n];
  96                }
  97        }
  98        return NULL;
  99}
 100
 101static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_name(
 102        struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp,
 103        const char *name)
 104{
 105        unsigned n;
 106        for (n = 0; n < grp->num_settings; n++) {
 107                if (strcmp(name, grp->settings[n].name) == 0) {
 108                        if (!pctl->variant || (pctl->variant &
 109                                               grp->settings[n].variant))
 110                                return &grp->settings[n];
 111                }
 112        }
 113        return NULL;
 114}
 115
 116static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_gpio_setting(
 117        struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp)
 118{
 119        unsigned n;
 120        for (n = 0; n < grp->num_settings; n++) {
 121                if (grp->settings[n].flags &
 122                        (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
 123                        if (!pctl->variant || (pctl->variant &
 124                                                grp->settings[n].variant))
 125                                return &grp->settings[n];
 126                }
 127        }
 128        return NULL;
 129}
 130
 131static struct mvebu_pinctrl_function *mvebu_pinctrl_find_function_by_name(
 132        struct mvebu_pinctrl *pctl, const char *name)
 133{
 134        unsigned n;
 135        for (n = 0; n < pctl->num_functions; n++) {
 136                if (strcmp(name, pctl->functions[n].name) == 0)
 137                        return &pctl->functions[n];
 138        }
 139        return NULL;
 140}
 141
 142/*
 143 * Common mpp pin configuration registers on MVEBU are
 144 * registers of eight 4-bit values for each mpp setting.
 145 * Register offset and bit mask are calculated accordingly below.
 146 */
 147static int mvebu_common_mpp_get(struct mvebu_pinctrl *pctl,
 148                                struct mvebu_pinctrl_group *grp,
 149                                unsigned long *config)
 150{
 151        unsigned pin = grp->gid;
 152        unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
 153        unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;
 154
 155        *config = readl(pctl->base + off);
 156        *config >>= shift;
 157        *config &= MPP_MASK;
 158
 159        return 0;
 160}
 161
 162static int mvebu_common_mpp_set(struct mvebu_pinctrl *pctl,
 163                                struct mvebu_pinctrl_group *grp,
 164                                unsigned long config)
 165{
 166        unsigned pin = grp->gid;
 167        unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
 168        unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;
 169        unsigned long reg;
 170
 171        reg = readl(pctl->base + off);
 172        reg &= ~(MPP_MASK << shift);
 173        reg |= (config << shift);
 174        writel(reg, pctl->base + off);
 175
 176        return 0;
 177}
 178
 179static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
 180                                unsigned gid, unsigned long *config)
 181{
 182        struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 183        struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
 184
 185        if (!grp->ctrl)
 186                return -EINVAL;
 187
 188        if (grp->ctrl->mpp_get)
 189                return grp->ctrl->mpp_get(grp->ctrl, config);
 190
 191        return mvebu_common_mpp_get(pctl, grp, config);
 192}
 193
 194static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
 195                                unsigned gid, unsigned long config)
 196{
 197        struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 198        struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
 199
 200        if (!grp->ctrl)
 201                return -EINVAL;
 202
 203        if (grp->ctrl->mpp_set)
 204                return grp->ctrl->mpp_set(grp->ctrl, config);
 205
 206        return mvebu_common_mpp_set(pctl, grp, config);
 207}
 208
 209static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
 210                                        struct seq_file *s, unsigned gid)
 211{
 212        struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 213        struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
 214        struct mvebu_mpp_ctrl_setting *curr;
 215        unsigned long config;
 216        unsigned n;
 217
 218        if (mvebu_pinconf_group_get(pctldev, gid, &config))
 219                return;
 220
 221        curr = mvebu_pinctrl_find_setting_by_val(pctl, grp, config);
 222
 223        if (curr) {
 224                seq_printf(s, "current: %s", curr->name);
 225                if (curr->subname)
 226                        seq_printf(s, "(%s)", curr->subname);
 227                if (curr->flags & (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
 228                        seq_printf(s, "(");
 229                        if (curr->flags & MVEBU_SETTING_GPI)
 230                                seq_printf(s, "i");
 231                        if (curr->flags & MVEBU_SETTING_GPO)
 232                                seq_printf(s, "o");
 233                        seq_printf(s, ")");
 234                }
 235        } else
 236                seq_printf(s, "current: UNKNOWN");
 237
 238        if (grp->num_settings > 1) {
 239                seq_printf(s, ", available = [");
 240                for (n = 0; n < grp->num_settings; n++) {
 241                        if (curr == &grp->settings[n])
 242                                continue;
 243
 244                        /* skip unsupported settings for this variant */
 245                        if (pctl->variant &&
 246                            !(pctl->variant & grp->settings[n].variant))
 247                                continue;
 248
 249                        seq_printf(s, " %s", grp->settings[n].name);
 250                        if (grp->settings[n].subname)
 251                                seq_printf(s, "(%s)", grp->settings[n].subname);
 252                        if (grp->settings[n].flags &
 253                                (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
 254                                seq_printf(s, "(");
 255                                if (grp->settings[n].flags & MVEBU_SETTING_GPI)
 256                                        seq_printf(s, "i");
 257                                if (grp->settings[n].flags & MVEBU_SETTING_GPO)
 258                                        seq_printf(s, "o");
 259                                seq_printf(s, ")");
 260                        }
 261                }
 262                seq_printf(s, " ]");
 263        }
 264        return;
 265}
 266
 267static struct pinconf_ops mvebu_pinconf_ops = {
 268        .pin_config_group_get = mvebu_pinconf_group_get,
 269        .pin_config_group_set = mvebu_pinconf_group_set,
 270        .pin_config_group_dbg_show = mvebu_pinconf_group_dbg_show,
 271};
 272
 273static int mvebu_pinmux_get_funcs_count(struct pinctrl_dev *pctldev)
 274{
 275        struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 276
 277        return pctl->num_functions;
 278}
 279
 280static const char *mvebu_pinmux_get_func_name(struct pinctrl_dev *pctldev,
 281                                        unsigned fid)
 282{
 283        struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 284
 285        return pctl->functions[fid].name;
 286}
 287
 288static int mvebu_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned fid,
 289                                const char * const **groups,
 290                                unsigned * const num_groups)
 291{
 292        struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 293
 294        *groups = pctl->functions[fid].groups;
 295        *num_groups = pctl->functions[fid].num_groups;
 296        return 0;
 297}
 298
 299static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
 300                        unsigned gid)
 301{
 302        struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 303        struct mvebu_pinctrl_function *func = &pctl->functions[fid];
 304        struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
 305        struct mvebu_mpp_ctrl_setting *setting;
 306        int ret;
 307
 308        setting = mvebu_pinctrl_find_setting_by_name(pctl, grp,
 309                                                     func->name);
 310        if (!setting) {
 311                dev_err(pctl->dev,
 312                        "unable to find setting %s in group %s\n",
 313                        func->name, func->groups[gid]);
 314                return -EINVAL;
 315        }
 316
 317        ret = mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
 318        if (ret) {
 319                dev_err(pctl->dev, "cannot set group %s to %s\n",
 320                        func->groups[gid], func->name);
 321                return ret;
 322        }
 323
 324        return 0;
 325}
 326
 327static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 328                        struct pinctrl_gpio_range *range, unsigned offset)
 329{
 330        struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 331        struct mvebu_pinctrl_group *grp;
 332        struct mvebu_mpp_ctrl_setting *setting;
 333
 334        grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
 335        if (!grp)
 336                return -EINVAL;
 337
 338        if (grp->ctrl->mpp_gpio_req)
 339                return grp->ctrl->mpp_gpio_req(grp->ctrl, offset);
 340
 341        setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
 342        if (!setting)
 343                return -ENOTSUPP;
 344
 345        return mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
 346}
 347
 348static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
 349           struct pinctrl_gpio_range *range, unsigned offset, bool input)
 350{
 351        struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 352        struct mvebu_pinctrl_group *grp;
 353        struct mvebu_mpp_ctrl_setting *setting;
 354
 355        grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
 356        if (!grp)
 357                return -EINVAL;
 358
 359        if (grp->ctrl->mpp_gpio_dir)
 360                return grp->ctrl->mpp_gpio_dir(grp->ctrl, offset, input);
 361
 362        setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
 363        if (!setting)
 364                return -ENOTSUPP;
 365
 366        if ((input && (setting->flags & MVEBU_SETTING_GPI)) ||
 367            (!input && (setting->flags & MVEBU_SETTING_GPO)))
 368                return 0;
 369
 370        return -ENOTSUPP;
 371}
 372
 373static struct pinmux_ops mvebu_pinmux_ops = {
 374        .get_functions_count = mvebu_pinmux_get_funcs_count,
 375        .get_function_name = mvebu_pinmux_get_func_name,
 376        .get_function_groups = mvebu_pinmux_get_groups,
 377        .gpio_request_enable = mvebu_pinmux_gpio_request_enable,
 378        .gpio_set_direction = mvebu_pinmux_gpio_set_direction,
 379        .enable = mvebu_pinmux_enable,
 380};
 381
 382static int mvebu_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
 383{
 384        struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 385        return pctl->num_groups;
 386}
 387
 388static const char *mvebu_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
 389                                                unsigned gid)
 390{
 391        struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 392        return pctl->groups[gid].name;
 393}
 394
 395static int mvebu_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
 396                                        unsigned gid, const unsigned **pins,
 397                                        unsigned *num_pins)
 398{
 399        struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 400        *pins = pctl->groups[gid].pins;
 401        *num_pins = pctl->groups[gid].npins;
 402        return 0;
 403}
 404
 405static int mvebu_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
 406                                        struct device_node *np,
 407                                        struct pinctrl_map **map,
 408                                        unsigned *num_maps)
 409{
 410        struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 411        struct property *prop;
 412        const char *function;
 413        const char *group;
 414        int ret, nmaps, n;
 415
 416        *map = NULL;
 417        *num_maps = 0;
 418
 419        ret = of_property_read_string(np, "marvell,function", &function);
 420        if (ret) {
 421                dev_err(pctl->dev,
 422                        "missing marvell,function in node %s\n", np->name);
 423                return 0;
 424        }
 425
 426        nmaps = of_property_count_strings(np, "marvell,pins");
 427        if (nmaps < 0) {
 428                dev_err(pctl->dev,
 429                        "missing marvell,pins in node %s\n", np->name);
 430                return 0;
 431        }
 432
 433        *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL);
 434        if (map == NULL) {
 435                dev_err(pctl->dev,
 436                        "cannot allocate pinctrl_map memory for %s\n",
 437                        np->name);
 438                return -ENOMEM;
 439        }
 440
 441        n = 0;
 442        of_property_for_each_string(np, "marvell,pins", prop, group) {
 443                struct mvebu_pinctrl_group *grp =
 444                        mvebu_pinctrl_find_group_by_name(pctl, group);
 445
 446                if (!grp) {
 447                        dev_err(pctl->dev, "unknown pin %s", group);
 448                        continue;
 449                }
 450
 451                if (!mvebu_pinctrl_find_setting_by_name(pctl, grp, function)) {
 452                        dev_err(pctl->dev, "unsupported function %s on pin %s",
 453                                function, group);
 454                        continue;
 455                }
 456
 457                (*map)[n].type = PIN_MAP_TYPE_MUX_GROUP;
 458                (*map)[n].data.mux.group = group;
 459                (*map)[n].data.mux.function = function;
 460                n++;
 461        }
 462
 463        *num_maps = nmaps;
 464
 465        return 0;
 466}
 467
 468static void mvebu_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
 469                                struct pinctrl_map *map, unsigned num_maps)
 470{
 471        kfree(map);
 472}
 473
 474static struct pinctrl_ops mvebu_pinctrl_ops = {
 475        .get_groups_count = mvebu_pinctrl_get_groups_count,
 476        .get_group_name = mvebu_pinctrl_get_group_name,
 477        .get_group_pins = mvebu_pinctrl_get_group_pins,
 478        .dt_node_to_map = mvebu_pinctrl_dt_node_to_map,
 479        .dt_free_map = mvebu_pinctrl_dt_free_map,
 480};
 481
 482static int __devinit _add_function(struct mvebu_pinctrl_function *funcs,
 483                                   const char *name)
 484{
 485        while (funcs->num_groups) {
 486                /* function already there */
 487                if (strcmp(funcs->name, name) == 0) {
 488                        funcs->num_groups++;
 489                        return -EEXIST;
 490                }
 491                funcs++;
 492        }
 493        funcs->name = name;
 494        funcs->num_groups = 1;
 495        return 0;
 496}
 497
 498static int __devinit mvebu_pinctrl_build_functions(struct platform_device *pdev,
 499                                                   struct mvebu_pinctrl *pctl)
 500{
 501        struct mvebu_pinctrl_function *funcs;
 502        int num = 0;
 503        int n, s;
 504
 505        /* we allocate functions for number of pins and hope
 506         * there are less unique functions than pins available */
 507        funcs = devm_kzalloc(&pdev->dev, pctl->desc.npins *
 508                             sizeof(struct mvebu_pinctrl_function), GFP_KERNEL);
 509        if (!funcs)
 510                return -ENOMEM;
 511
 512        for (n = 0; n < pctl->num_groups; n++) {
 513                struct mvebu_pinctrl_group *grp = &pctl->groups[n];
 514                for (s = 0; s < grp->num_settings; s++) {
 515                        /* skip unsupported settings on this variant */
 516                        if (pctl->variant &&
 517                            !(pctl->variant & grp->settings[s].variant))
 518                                continue;
 519
 520                        /* check for unique functions and count groups */
 521                        if (_add_function(funcs, grp->settings[s].name))
 522                                continue;
 523
 524                        num++;
 525                }
 526        }
 527
 528        /* with the number of unique functions and it's groups known,
 529           reallocate functions and assign group names */
 530        funcs = krealloc(funcs, num * sizeof(struct mvebu_pinctrl_function),
 531                         GFP_KERNEL);
 532        if (!funcs)
 533                return -ENOMEM;
 534
 535        pctl->num_functions = num;
 536        pctl->functions = funcs;
 537
 538        for (n = 0; n < pctl->num_groups; n++) {
 539                struct mvebu_pinctrl_group *grp = &pctl->groups[n];
 540                for (s = 0; s < grp->num_settings; s++) {
 541                        struct mvebu_pinctrl_function *f;
 542                        const char **groups;
 543
 544                        /* skip unsupported settings on this variant */
 545                        if (pctl->variant &&
 546                            !(pctl->variant & grp->settings[s].variant))
 547                                continue;
 548
 549                        f = mvebu_pinctrl_find_function_by_name(pctl,
 550                                                        grp->settings[s].name);
 551
 552                        /* allocate group name array if not done already */
 553                        if (!f->groups) {
 554                                f->groups = devm_kzalloc(&pdev->dev,
 555                                                 f->num_groups * sizeof(char *),
 556                                                 GFP_KERNEL);
 557                                if (!f->groups)
 558                                        return -ENOMEM;
 559                        }
 560
 561                        /* find next free group name and assign current name */
 562                        groups = f->groups;
 563                        while (*groups)
 564                                groups++;
 565                        *groups = grp->name;
 566                }
 567        }
 568
 569        return 0;
 570}
 571
 572int __devinit mvebu_pinctrl_probe(struct platform_device *pdev)
 573{
 574        struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
 575        struct device_node *np = pdev->dev.of_node;
 576        struct mvebu_pinctrl *pctl;
 577        void __iomem *base;
 578        struct pinctrl_pin_desc *pdesc;
 579        unsigned gid, n, k;
 580        int ret;
 581
 582        if (!soc || !soc->controls || !soc->modes) {
 583                dev_err(&pdev->dev, "wrong pinctrl soc info\n");
 584                return -EINVAL;
 585        }
 586
 587        base = of_iomap(np, 0);
 588        if (!base) {
 589                dev_err(&pdev->dev, "unable to get base address\n");
 590                return -ENODEV;
 591        }
 592
 593        pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl),
 594                        GFP_KERNEL);
 595        if (!pctl) {
 596                dev_err(&pdev->dev, "unable to alloc driver\n");
 597                return -ENOMEM;
 598        }
 599
 600        pctl->desc.name = dev_name(&pdev->dev);
 601        pctl->desc.owner = THIS_MODULE;
 602        pctl->desc.pctlops = &mvebu_pinctrl_ops;
 603        pctl->desc.pmxops = &mvebu_pinmux_ops;
 604        pctl->desc.confops = &mvebu_pinconf_ops;
 605        pctl->variant = soc->variant;
 606        pctl->base = base;
 607        pctl->dev = &pdev->dev;
 608        platform_set_drvdata(pdev, pctl);
 609
 610        /* count controls and create names for mvebu generic
 611           register controls; also does sanity checks */
 612        pctl->num_groups = 0;
 613        pctl->desc.npins = 0;
 614        for (n = 0; n < soc->ncontrols; n++) {
 615                struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
 616                char *names;
 617
 618                pctl->desc.npins += ctrl->npins;
 619                /* initial control pins */
 620                for (k = 0; k < ctrl->npins; k++)
 621                        ctrl->pins[k] = ctrl->pid + k;
 622
 623                /* special soc specific control */
 624                if (ctrl->mpp_get || ctrl->mpp_set) {
 625                        if (!ctrl->name || !ctrl->mpp_set || !ctrl->mpp_set) {
 626                                dev_err(&pdev->dev, "wrong soc control info\n");
 627                                return -EINVAL;
 628                        }
 629                        pctl->num_groups += 1;
 630                        continue;
 631                }
 632
 633                /* generic mvebu register control */
 634                names = devm_kzalloc(&pdev->dev, ctrl->npins * 8, GFP_KERNEL);
 635                if (!names) {
 636                        dev_err(&pdev->dev, "failed to alloc mpp names\n");
 637                        return -ENOMEM;
 638                }
 639                for (k = 0; k < ctrl->npins; k++)
 640                        sprintf(names + 8*k, "mpp%d", ctrl->pid+k);
 641                ctrl->name = names;
 642                pctl->num_groups += ctrl->npins;
 643        }
 644
 645        pdesc = devm_kzalloc(&pdev->dev, pctl->desc.npins *
 646                             sizeof(struct pinctrl_pin_desc), GFP_KERNEL);
 647        if (!pdesc) {
 648                dev_err(&pdev->dev, "failed to alloc pinctrl pins\n");
 649                return -ENOMEM;
 650        }
 651
 652        for (n = 0; n < pctl->desc.npins; n++)
 653                pdesc[n].number = n;
 654        pctl->desc.pins = pdesc;
 655
 656        pctl->groups = devm_kzalloc(&pdev->dev, pctl->num_groups *
 657                             sizeof(struct mvebu_pinctrl_group), GFP_KERNEL);
 658        if (!pctl->groups) {
 659                dev_err(&pdev->dev, "failed to alloc pinctrl groups\n");
 660                return -ENOMEM;
 661        }
 662
 663        /* assign mpp controls to groups */
 664        gid = 0;
 665        for (n = 0; n < soc->ncontrols; n++) {
 666                struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
 667                pctl->groups[gid].gid = gid;
 668                pctl->groups[gid].ctrl = ctrl;
 669                pctl->groups[gid].name = ctrl->name;
 670                pctl->groups[gid].pins = ctrl->pins;
 671                pctl->groups[gid].npins = ctrl->npins;
 672
 673                /* generic mvebu register control maps to a number of groups */
 674                if (!ctrl->mpp_get && !ctrl->mpp_set) {
 675                        pctl->groups[gid].npins = 1;
 676
 677                        for (k = 1; k < ctrl->npins; k++) {
 678                                gid++;
 679                                pctl->groups[gid].gid = gid;
 680                                pctl->groups[gid].ctrl = ctrl;
 681                                pctl->groups[gid].name = &ctrl->name[8*k];
 682                                pctl->groups[gid].pins = &ctrl->pins[k];
 683                                pctl->groups[gid].npins = 1;
 684                        }
 685                }
 686                gid++;
 687        }
 688
 689        /* assign mpp modes to groups */
 690        for (n = 0; n < soc->nmodes; n++) {
 691                struct mvebu_mpp_mode *mode = &soc->modes[n];
 692                struct mvebu_pinctrl_group *grp =
 693                        mvebu_pinctrl_find_group_by_pid(pctl, mode->pid);
 694                unsigned num_settings;
 695
 696                if (!grp) {
 697                        dev_warn(&pdev->dev, "unknown pinctrl group %d\n",
 698                                mode->pid);
 699                        continue;
 700                }
 701
 702                for (num_settings = 0; ;) {
 703                        struct mvebu_mpp_ctrl_setting *set =
 704                                &mode->settings[num_settings];
 705
 706                        if (!set->name)
 707                                break;
 708                        num_settings++;
 709
 710                        /* skip unsupported settings for this variant */
 711                        if (pctl->variant && !(pctl->variant & set->variant))
 712                                continue;
 713
 714                        /* find gpio/gpo/gpi settings */
 715                        if (strcmp(set->name, "gpio") == 0)
 716                                set->flags = MVEBU_SETTING_GPI |
 717                                        MVEBU_SETTING_GPO;
 718                        else if (strcmp(set->name, "gpo") == 0)
 719                                set->flags = MVEBU_SETTING_GPO;
 720                        else if (strcmp(set->name, "gpi") == 0)
 721                                set->flags = MVEBU_SETTING_GPI;
 722                }
 723
 724                grp->settings = mode->settings;
 725                grp->num_settings = num_settings;
 726        }
 727
 728        ret = mvebu_pinctrl_build_functions(pdev, pctl);
 729        if (ret) {
 730                dev_err(&pdev->dev, "unable to build functions\n");
 731                return ret;
 732        }
 733
 734        pctl->pctldev = pinctrl_register(&pctl->desc, &pdev->dev, pctl);
 735        if (!pctl->pctldev) {
 736                dev_err(&pdev->dev, "unable to register pinctrl driver\n");
 737                return -EINVAL;
 738        }
 739
 740        dev_info(&pdev->dev, "registered pinctrl driver\n");
 741
 742        /* register gpio ranges */
 743        for (n = 0; n < soc->ngpioranges; n++)
 744                pinctrl_add_gpio_range(pctl->pctldev, &soc->gpioranges[n]);
 745
 746        return 0;
 747}
 748
 749int __devexit mvebu_pinctrl_remove(struct platform_device *pdev)
 750{
 751        struct mvebu_pinctrl *pctl = platform_get_drvdata(pdev);
 752        pinctrl_unregister(pctl->pctldev);
 753        return 0;
 754}
 755
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.