linux/arch/arm/mach-omap2/mux.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-omap2/mux.c
   3 *
   4 * OMAP2, OMAP3 and OMAP4 pin multiplexing configurations
   5 *
   6 * Copyright (C) 2004 - 2010 Texas Instruments Inc.
   7 * Copyright (C) 2003 - 2008 Nokia Corporation
   8 *
   9 * Written by Tony Lindgren
  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 program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19 * GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  24 *
  25 */
  26#include <linux/kernel.h>
  27#include <linux/init.h>
  28#include <linux/io.h>
  29#include <linux/list.h>
  30#include <linux/slab.h>
  31#include <linux/ctype.h>
  32#include <linux/debugfs.h>
  33#include <linux/seq_file.h>
  34#include <linux/uaccess.h>
  35#include <linux/irq.h>
  36#include <linux/interrupt.h>
  37
  38
  39#include "omap_hwmod.h"
  40
  41#include "soc.h"
  42#include "control.h"
  43#include "mux.h"
  44#include "prm.h"
  45#include "common.h"
  46
  47#define OMAP_MUX_BASE_OFFSET            0x30    /* Offset from CTRL_BASE */
  48#define OMAP_MUX_BASE_SZ                0x5ca
  49
  50struct omap_mux_entry {
  51        struct omap_mux         mux;
  52        struct list_head        node;
  53};
  54
  55static LIST_HEAD(mux_partitions);
  56static DEFINE_MUTEX(muxmode_mutex);
  57
  58struct omap_mux_partition *omap_mux_get(const char *name)
  59{
  60        struct omap_mux_partition *partition;
  61
  62        list_for_each_entry(partition, &mux_partitions, node) {
  63                if (!strcmp(name, partition->name))
  64                        return partition;
  65        }
  66
  67        return NULL;
  68}
  69
  70u16 omap_mux_read(struct omap_mux_partition *partition, u16 reg)
  71{
  72        if (partition->flags & OMAP_MUX_REG_8BIT)
  73                return readb_relaxed(partition->base + reg);
  74        else
  75                return readw_relaxed(partition->base + reg);
  76}
  77
  78void omap_mux_write(struct omap_mux_partition *partition, u16 val,
  79                           u16 reg)
  80{
  81        if (partition->flags & OMAP_MUX_REG_8BIT)
  82                writeb_relaxed(val, partition->base + reg);
  83        else
  84                writew_relaxed(val, partition->base + reg);
  85}
  86
  87void omap_mux_write_array(struct omap_mux_partition *partition,
  88                                 struct omap_board_mux *board_mux)
  89{
  90        if (!board_mux)
  91                return;
  92
  93        while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
  94                omap_mux_write(partition, board_mux->value,
  95                               board_mux->reg_offset);
  96                board_mux++;
  97        }
  98}
  99
 100#ifdef CONFIG_OMAP_MUX
 101
 102static char *omap_mux_options;
 103
 104static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
 105                                      int gpio, int val)
 106{
 107        struct omap_mux_entry *e;
 108        struct omap_mux *gpio_mux = NULL;
 109        u16 old_mode;
 110        u16 mux_mode;
 111        int found = 0;
 112        struct list_head *muxmodes = &partition->muxmodes;
 113
 114        if (!gpio)
 115                return -EINVAL;
 116
 117        list_for_each_entry(e, muxmodes, node) {
 118                struct omap_mux *m = &e->mux;
 119                if (gpio == m->gpio) {
 120                        gpio_mux = m;
 121                        found++;
 122                }
 123        }
 124
 125        if (found == 0) {
 126                pr_err("%s: Could not set gpio%i\n", __func__, gpio);
 127                return -ENODEV;
 128        }
 129
 130        if (found > 1) {
 131                pr_info("%s: Multiple gpio paths (%d) for gpio%i\n", __func__,
 132                        found, gpio);
 133                return -EINVAL;
 134        }
 135
 136        old_mode = omap_mux_read(partition, gpio_mux->reg_offset);
 137        mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
 138        mux_mode |= partition->gpio;
 139        pr_debug("%s: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", __func__,
 140                 gpio_mux->muxnames[0], gpio, old_mode, mux_mode);
 141        omap_mux_write(partition, mux_mode, gpio_mux->reg_offset);
 142
 143        return 0;
 144}
 145
 146int __init omap_mux_init_gpio(int gpio, int val)
 147{
 148        struct omap_mux_partition *partition;
 149        int ret;
 150
 151        list_for_each_entry(partition, &mux_partitions, node) {
 152                ret = _omap_mux_init_gpio(partition, gpio, val);
 153                if (!ret)
 154                        return ret;
 155        }
 156
 157        return -ENODEV;
 158}
 159
 160static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
 161                                        const char *muxname,
 162                                        struct omap_mux **found_mux)
 163{
 164        struct omap_mux *mux = NULL;
 165        struct omap_mux_entry *e;
 166        const char *mode_name;
 167        int found = 0, found_mode = 0, mode0_len = 0;
 168        struct list_head *muxmodes = &partition->muxmodes;
 169
 170        mode_name = strchr(muxname, '.');
 171        if (mode_name) {
 172                mode0_len = strlen(muxname) - strlen(mode_name);
 173                mode_name++;
 174        } else {
 175                mode_name = muxname;
 176        }
 177
 178        list_for_each_entry(e, muxmodes, node) {
 179                char *m0_entry;
 180                int i;
 181
 182                mux = &e->mux;
 183                m0_entry = mux->muxnames[0];
 184
 185                /* First check for full name in mode0.muxmode format */
 186                if (mode0_len)
 187                        if (strncmp(muxname, m0_entry, mode0_len) ||
 188                            (strlen(m0_entry) != mode0_len))
 189                                continue;
 190
 191                /* Then check for muxmode only */
 192                for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
 193                        char *mode_cur = mux->muxnames[i];
 194
 195                        if (!mode_cur)
 196                                continue;
 197
 198                        if (!strcmp(mode_name, mode_cur)) {
 199                                *found_mux = mux;
 200                                found++;
 201                                found_mode = i;
 202                        }
 203                }
 204        }
 205
 206        if (found == 1) {
 207                return found_mode;
 208        }
 209
 210        if (found > 1) {
 211                pr_err("%s: Multiple signal paths (%i) for %s\n", __func__,
 212                       found, muxname);
 213                return -EINVAL;
 214        }
 215
 216        return -ENODEV;
 217}
 218
 219int __init omap_mux_get_by_name(const char *muxname,
 220                        struct omap_mux_partition **found_partition,
 221                        struct omap_mux **found_mux)
 222{
 223        struct omap_mux_partition *partition;
 224
 225        list_for_each_entry(partition, &mux_partitions, node) {
 226                struct omap_mux *mux = NULL;
 227                int mux_mode = _omap_mux_get_by_name(partition, muxname, &mux);
 228                if (mux_mode < 0)
 229                        continue;
 230
 231                *found_partition = partition;
 232                *found_mux = mux;
 233
 234                return mux_mode;
 235        }
 236
 237        pr_err("%s: Could not find signal %s\n", __func__, muxname);
 238
 239        return -ENODEV;
 240}
 241
 242int __init omap_mux_init_signal(const char *muxname, int val)
 243{
 244        struct omap_mux_partition *partition = NULL;
 245        struct omap_mux *mux = NULL;
 246        u16 old_mode;
 247        int mux_mode;
 248
 249        mux_mode = omap_mux_get_by_name(muxname, &partition, &mux);
 250        if (mux_mode < 0 || !mux)
 251                return mux_mode;
 252
 253        old_mode = omap_mux_read(partition, mux->reg_offset);
 254        mux_mode |= val;
 255        pr_debug("%s: Setting signal %s 0x%04x -> 0x%04x\n",
 256                         __func__, muxname, old_mode, mux_mode);
 257        omap_mux_write(partition, mux_mode, mux->reg_offset);
 258
 259        return 0;
 260}
 261
 262struct omap_hwmod_mux_info * __init
 263omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
 264{
 265        struct omap_hwmod_mux_info *hmux;
 266        int i, nr_pads_dynamic = 0;
 267
 268        if (!bpads || nr_pads < 1)
 269                return NULL;
 270
 271        hmux = kzalloc(sizeof(struct omap_hwmod_mux_info), GFP_KERNEL);
 272        if (!hmux)
 273                goto err1;
 274
 275        hmux->nr_pads = nr_pads;
 276
 277        hmux->pads = kzalloc(sizeof(struct omap_device_pad) *
 278                                nr_pads, GFP_KERNEL);
 279        if (!hmux->pads)
 280                goto err2;
 281
 282        for (i = 0; i < hmux->nr_pads; i++) {
 283                struct omap_mux_partition *partition;
 284                struct omap_device_pad *bpad = &bpads[i], *pad = &hmux->pads[i];
 285                struct omap_mux *mux;
 286                int mux_mode;
 287
 288                mux_mode = omap_mux_get_by_name(bpad->name, &partition, &mux);
 289                if (mux_mode < 0)
 290                        goto err3;
 291                if (!pad->partition)
 292                        pad->partition = partition;
 293                if (!pad->mux)
 294                        pad->mux = mux;
 295
 296                pad->name = kzalloc(strlen(bpad->name) + 1, GFP_KERNEL);
 297                if (!pad->name) {
 298                        int j;
 299
 300                        for (j = i - 1; j >= 0; j--)
 301                                kfree(hmux->pads[j].name);
 302                        goto err3;
 303                }
 304                strcpy(pad->name, bpad->name);
 305
 306                pad->flags = bpad->flags;
 307                pad->enable = bpad->enable;
 308                pad->idle = bpad->idle;
 309                pad->off = bpad->off;
 310
 311                if (pad->flags &
 312                    (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP))
 313                        nr_pads_dynamic++;
 314
 315                pr_debug("%s: Initialized %s\n", __func__, pad->name);
 316        }
 317
 318        if (!nr_pads_dynamic)
 319                return hmux;
 320
 321        /*
 322         * Add pads that need dynamic muxing into a separate list
 323         */
 324
 325        hmux->nr_pads_dynamic = nr_pads_dynamic;
 326        hmux->pads_dynamic = kzalloc(sizeof(struct omap_device_pad *) *
 327                                        nr_pads_dynamic, GFP_KERNEL);
 328        if (!hmux->pads_dynamic) {
 329                pr_err("%s: Could not allocate dynamic pads\n", __func__);
 330                return hmux;
 331        }
 332
 333        nr_pads_dynamic = 0;
 334        for (i = 0; i < hmux->nr_pads; i++) {
 335                struct omap_device_pad *pad = &hmux->pads[i];
 336
 337                if (pad->flags &
 338                    (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP)) {
 339                        pr_debug("%s: pad %s tagged dynamic\n",
 340                                        __func__, pad->name);
 341                        hmux->pads_dynamic[nr_pads_dynamic] = pad;
 342                        nr_pads_dynamic++;
 343                }
 344        }
 345
 346        return hmux;
 347
 348err3:
 349        kfree(hmux->pads);
 350err2:
 351        kfree(hmux);
 352err1:
 353        pr_err("%s: Could not allocate device mux entry\n", __func__);
 354
 355        return NULL;
 356}
 357
 358/**
 359 * omap_hwmod_mux_scan_wakeups - omap hwmod scan wakeup pads
 360 * @hmux: Pads for a hwmod
 361 * @mpu_irqs: MPU irq array for a hwmod
 362 *
 363 * Scans the wakeup status of pads for a single hwmod.  If an irq
 364 * array is defined for this mux, the parser will call the registered
 365 * ISRs for corresponding pads, otherwise the parser will stop at the
 366 * first wakeup active pad and return.  Returns true if there is a
 367 * pending and non-served wakeup event for the mux, otherwise false.
 368 */
 369static bool omap_hwmod_mux_scan_wakeups(struct omap_hwmod_mux_info *hmux,
 370                struct omap_hwmod_irq_info *mpu_irqs)
 371{
 372        int i, irq;
 373        unsigned int val;
 374        u32 handled_irqs = 0;
 375
 376        for (i = 0; i < hmux->nr_pads_dynamic; i++) {
 377                struct omap_device_pad *pad = hmux->pads_dynamic[i];
 378
 379                if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP) ||
 380                    !(pad->idle & OMAP_WAKEUP_EN))
 381                        continue;
 382
 383                val = omap_mux_read(pad->partition, pad->mux->reg_offset);
 384                if (!(val & OMAP_WAKEUP_EVENT))
 385                        continue;
 386
 387                if (!hmux->irqs)
 388                        return true;
 389
 390                irq = hmux->irqs[i];
 391                /* make sure we only handle each irq once */
 392                if (handled_irqs & 1 << irq)
 393                        continue;
 394
 395                handled_irqs |= 1 << irq;
 396
 397                generic_handle_irq(mpu_irqs[irq].irq);
 398        }
 399
 400        return false;
 401}
 402
 403/**
 404 * _omap_hwmod_mux_handle_irq - Process wakeup events for a single hwmod
 405 *
 406 * Checks a single hwmod for every wakeup capable pad to see if there is an
 407 * active wakeup event. If this is the case, call the corresponding ISR.
 408 */
 409static int _omap_hwmod_mux_handle_irq(struct omap_hwmod *oh, void *data)
 410{
 411        if (!oh->mux || !oh->mux->enabled)
 412                return 0;
 413        if (omap_hwmod_mux_scan_wakeups(oh->mux, oh->mpu_irqs))
 414                generic_handle_irq(oh->mpu_irqs[0].irq);
 415        return 0;
 416}
 417
 418/**
 419 * omap_hwmod_mux_handle_irq - Process pad wakeup irqs.
 420 *
 421 * Calls a function for each registered omap_hwmod to check
 422 * pad wakeup statuses.
 423 */
 424static irqreturn_t omap_hwmod_mux_handle_irq(int irq, void *unused)
 425{
 426        omap_hwmod_for_each(_omap_hwmod_mux_handle_irq, NULL);
 427        return IRQ_HANDLED;
 428}
 429
 430/* Assumes the calling function takes care of locking */
 431void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
 432{
 433        int i;
 434
 435        /* Runtime idling of dynamic pads */
 436        if (state == _HWMOD_STATE_IDLE && hmux->enabled) {
 437                for (i = 0; i < hmux->nr_pads_dynamic; i++) {
 438                        struct omap_device_pad *pad = hmux->pads_dynamic[i];
 439                        int val = -EINVAL;
 440
 441                        val = pad->idle;
 442                        omap_mux_write(pad->partition, val,
 443                                        pad->mux->reg_offset);
 444                }
 445
 446                return;
 447        }
 448
 449        /* Runtime enabling of dynamic pads */
 450        if ((state == _HWMOD_STATE_ENABLED) && hmux->pads_dynamic
 451                                        && hmux->enabled) {
 452                for (i = 0; i < hmux->nr_pads_dynamic; i++) {
 453                        struct omap_device_pad *pad = hmux->pads_dynamic[i];
 454                        int val = -EINVAL;
 455
 456                        val = pad->enable;
 457                        omap_mux_write(pad->partition, val,
 458                                        pad->mux->reg_offset);
 459                }
 460
 461                return;
 462        }
 463
 464        /* Enabling or disabling of all pads */
 465        for (i = 0; i < hmux->nr_pads; i++) {
 466                struct omap_device_pad *pad = &hmux->pads[i];
 467                int flags, val = -EINVAL;
 468
 469                flags = pad->flags;
 470
 471                switch (state) {
 472                case _HWMOD_STATE_ENABLED:
 473                        val = pad->enable;
 474                        pr_debug("%s: Enabling %s %x\n", __func__,
 475                                        pad->name, val);
 476                        break;
 477                case _HWMOD_STATE_DISABLED:
 478                        /* Use safe mode unless OMAP_DEVICE_PAD_REMUX */
 479                        if (flags & OMAP_DEVICE_PAD_REMUX)
 480                                val = pad->off;
 481                        else
 482                                val = OMAP_MUX_MODE7;
 483                        pr_debug("%s: Disabling %s %x\n", __func__,
 484                                        pad->name, val);
 485                        break;
 486                default:
 487                        /* Nothing to be done */
 488                        break;
 489                }
 490
 491                if (val >= 0) {
 492                        omap_mux_write(pad->partition, val,
 493                                        pad->mux->reg_offset);
 494                        pad->flags = flags;
 495                }
 496        }
 497
 498        if (state == _HWMOD_STATE_ENABLED)
 499                hmux->enabled = true;
 500        else
 501                hmux->enabled = false;
 502}
 503
 504#ifdef CONFIG_DEBUG_FS
 505
 506#define OMAP_MUX_MAX_NR_FLAGS   10
 507#define OMAP_MUX_TEST_FLAG(val, mask)                           \
 508        if (((val) & (mask)) == (mask)) {                       \
 509                i++;                                            \
 510                flags[i] =  #mask;                              \
 511        }
 512
 513/* REVISIT: Add checking for non-optimal mux settings */
 514static inline void omap_mux_decode(struct seq_file *s, u16 val)
 515{
 516        char *flags[OMAP_MUX_MAX_NR_FLAGS];
 517        char mode[sizeof("OMAP_MUX_MODE") + 1];
 518        int i = -1;
 519
 520        sprintf(mode, "OMAP_MUX_MODE%d", val & 0x7);
 521        i++;
 522        flags[i] = mode;
 523
 524        OMAP_MUX_TEST_FLAG(val, OMAP_PIN_OFF_WAKEUPENABLE);
 525        if (val & OMAP_OFF_EN) {
 526                if (!(val & OMAP_OFFOUT_EN)) {
 527                        if (!(val & OMAP_OFF_PULL_UP)) {
 528                                OMAP_MUX_TEST_FLAG(val,
 529                                        OMAP_PIN_OFF_INPUT_PULLDOWN);
 530                        } else {
 531                                OMAP_MUX_TEST_FLAG(val,
 532                                        OMAP_PIN_OFF_INPUT_PULLUP);
 533                        }
 534                } else {
 535                        if (!(val & OMAP_OFFOUT_VAL)) {
 536                                OMAP_MUX_TEST_FLAG(val,
 537                                        OMAP_PIN_OFF_OUTPUT_LOW);
 538                        } else {
 539                                OMAP_MUX_TEST_FLAG(val,
 540                                        OMAP_PIN_OFF_OUTPUT_HIGH);
 541                        }
 542                }
 543        }
 544
 545        if (val & OMAP_INPUT_EN) {
 546                if (val & OMAP_PULL_ENA) {
 547                        if (!(val & OMAP_PULL_UP)) {
 548                                OMAP_MUX_TEST_FLAG(val,
 549                                        OMAP_PIN_INPUT_PULLDOWN);
 550                        } else {
 551                                OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT_PULLUP);
 552                        }
 553                } else {
 554                        OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT);
 555                }
 556        } else {
 557                i++;
 558                flags[i] = "OMAP_PIN_OUTPUT";
 559        }
 560
 561        do {
 562                seq_printf(s, "%s", flags[i]);
 563                if (i > 0)
 564                        seq_printf(s, " | ");
 565        } while (i-- > 0);
 566}
 567
 568#define OMAP_MUX_DEFNAME_LEN    32
 569
 570static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
 571{
 572        struct omap_mux_partition *partition = s->private;
 573        struct omap_mux_entry *e;
 574        u8 omap_gen = omap_rev() >> 28;
 575
 576        list_for_each_entry(e, &partition->muxmodes, node) {
 577                struct omap_mux *m = &e->mux;
 578                char m0_def[OMAP_MUX_DEFNAME_LEN];
 579                char *m0_name = m->muxnames[0];
 580                u16 val;
 581                int i, mode;
 582
 583                if (!m0_name)
 584                        continue;
 585
 586                /* REVISIT: Needs to be updated if mode0 names get longer */
 587                for (i = 0; i < OMAP_MUX_DEFNAME_LEN; i++) {
 588                        if (m0_name[i] == '\0') {
 589                                m0_def[i] = m0_name[i];
 590                                break;
 591                        }
 592                        m0_def[i] = toupper(m0_name[i]);
 593                }
 594                val = omap_mux_read(partition, m->reg_offset);
 595                mode = val & OMAP_MUX_MODE7;
 596                if (mode != 0)
 597                        seq_printf(s, "/* %s */\n", m->muxnames[mode]);
 598
 599                /*
 600                 * XXX: Might be revisited to support differences across
 601                 * same OMAP generation.
 602                 */
 603                seq_printf(s, "OMAP%d_MUX(%s, ", omap_gen, m0_def);
 604                omap_mux_decode(s, val);
 605                seq_printf(s, "),\n");
 606        }
 607
 608        return 0;
 609}
 610
 611static int omap_mux_dbg_board_open(struct inode *inode, struct file *file)
 612{
 613        return single_open(file, omap_mux_dbg_board_show, inode->i_private);
 614}
 615
 616static const struct file_operations omap_mux_dbg_board_fops = {
 617        .open           = omap_mux_dbg_board_open,
 618        .read           = seq_read,
 619        .llseek         = seq_lseek,
 620        .release        = single_release,
 621};
 622
 623static struct omap_mux_partition *omap_mux_get_partition(struct omap_mux *mux)
 624{
 625        struct omap_mux_partition *partition;
 626
 627        list_for_each_entry(partition, &mux_partitions, node) {
 628                struct list_head *muxmodes = &partition->muxmodes;
 629                struct omap_mux_entry *e;
 630
 631                list_for_each_entry(e, muxmodes, node) {
 632                        struct omap_mux *m = &e->mux;
 633
 634                        if (m == mux)
 635                                return partition;
 636                }
 637        }
 638
 639        return NULL;
 640}
 641
 642static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
 643{
 644        struct omap_mux *m = s->private;
 645        struct omap_mux_partition *partition;
 646        const char *none = "NA";
 647        u16 val;
 648        int mode;
 649
 650        partition = omap_mux_get_partition(m);
 651        if (!partition)
 652                return 0;
 653
 654        val = omap_mux_read(partition, m->reg_offset);
 655        mode = val & OMAP_MUX_MODE7;
 656
 657        seq_printf(s, "name: %s.%s (0x%08x/0x%03x = 0x%04x), b %s, t %s\n",
 658                        m->muxnames[0], m->muxnames[mode],
 659                        partition->phys + m->reg_offset, m->reg_offset, val,
 660                        m->balls[0] ? m->balls[0] : none,
 661                        m->balls[1] ? m->balls[1] : none);
 662        seq_printf(s, "mode: ");
 663        omap_mux_decode(s, val);
 664        seq_printf(s, "\n");
 665        seq_printf(s, "signals: %s | %s | %s | %s | %s | %s | %s | %s\n",
 666                        m->muxnames[0] ? m->muxnames[0] : none,
 667                        m->muxnames[1] ? m->muxnames[1] : none,
 668                        m->muxnames[2] ? m->muxnames[2] : none,
 669                        m->muxnames[3] ? m->muxnames[3] : none,
 670                        m->muxnames[4] ? m->muxnames[4] : none,
 671                        m->muxnames[5] ? m->muxnames[5] : none,
 672                        m->muxnames[6] ? m->muxnames[6] : none,
 673                        m->muxnames[7] ? m->muxnames[7] : none);
 674
 675        return 0;
 676}
 677
 678#define OMAP_MUX_MAX_ARG_CHAR  7
 679
 680static ssize_t omap_mux_dbg_signal_write(struct file *file,
 681                                         const char __user *user_buf,
 682                                         size_t count, loff_t *ppos)
 683{
 684        struct seq_file *seqf;
 685        struct omap_mux *m;
 686        u16 val;
 687        int ret;
 688        struct omap_mux_partition *partition;
 689
 690        if (count > OMAP_MUX_MAX_ARG_CHAR)
 691                return -EINVAL;
 692
 693        ret = kstrtou16_from_user(user_buf, count, 0x10, &val);
 694        if (ret < 0)
 695                return ret;
 696
 697        seqf = file->private_data;
 698        m = seqf->private;
 699
 700        partition = omap_mux_get_partition(m);
 701        if (!partition)
 702                return -ENODEV;
 703
 704        omap_mux_write(partition, val, m->reg_offset);
 705        *ppos += count;
 706
 707        return count;
 708}
 709
 710static int omap_mux_dbg_signal_open(struct inode *inode, struct file *file)
 711{
 712        return single_open(file, omap_mux_dbg_signal_show, inode->i_private);
 713}
 714
 715static const struct file_operations omap_mux_dbg_signal_fops = {
 716        .open           = omap_mux_dbg_signal_open,
 717        .read           = seq_read,
 718        .write          = omap_mux_dbg_signal_write,
 719        .llseek         = seq_lseek,
 720        .release        = single_release,
 721};
 722
 723static struct dentry *mux_dbg_dir;
 724
 725static void __init omap_mux_dbg_create_entry(
 726                                struct omap_mux_partition *partition,
 727                                struct dentry *mux_dbg_dir)
 728{
 729        struct omap_mux_entry *e;
 730
 731        list_for_each_entry(e, &partition->muxmodes, node) {
 732                struct omap_mux *m = &e->mux;
 733
 734                (void)debugfs_create_file(m->muxnames[0], S_IWUSR | S_IRUGO,
 735                                          mux_dbg_dir, m,
 736                                          &omap_mux_dbg_signal_fops);
 737        }
 738}
 739
 740static void __init omap_mux_dbg_init(void)
 741{
 742        struct omap_mux_partition *partition;
 743        static struct dentry *mux_dbg_board_dir;
 744
 745        mux_dbg_dir = debugfs_create_dir("omap_mux", NULL);
 746        if (!mux_dbg_dir)
 747                return;
 748
 749        mux_dbg_board_dir = debugfs_create_dir("board", mux_dbg_dir);
 750        if (!mux_dbg_board_dir)
 751                return;
 752
 753        list_for_each_entry(partition, &mux_partitions, node) {
 754                omap_mux_dbg_create_entry(partition, mux_dbg_dir);
 755                (void)debugfs_create_file(partition->name, S_IRUGO,
 756                                          mux_dbg_board_dir, partition,
 757                                          &omap_mux_dbg_board_fops);
 758        }
 759}
 760
 761#else
 762static inline void omap_mux_dbg_init(void)
 763{
 764}
 765#endif  /* CONFIG_DEBUG_FS */
 766
 767static void __init omap_mux_free_names(struct omap_mux *m)
 768{
 769        int i;
 770
 771        for (i = 0; i < OMAP_MUX_NR_MODES; i++)
 772                kfree(m->muxnames[i]);
 773
 774#ifdef CONFIG_DEBUG_FS
 775        for (i = 0; i < OMAP_MUX_NR_SIDES; i++)
 776                kfree(m->balls[i]);
 777#endif
 778
 779}
 780
 781/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */
 782int __init omap_mux_late_init(void)
 783{
 784        struct omap_mux_partition *partition;
 785        int ret;
 786
 787        list_for_each_entry(partition, &mux_partitions, node) {
 788                struct omap_mux_entry *e, *tmp;
 789                list_for_each_entry_safe(e, tmp, &partition->muxmodes, node) {
 790                        struct omap_mux *m = &e->mux;
 791                        u16 mode = omap_mux_read(partition, m->reg_offset);
 792
 793                        if (OMAP_MODE_GPIO(partition, mode))
 794                                continue;
 795
 796#ifndef CONFIG_DEBUG_FS
 797                        mutex_lock(&muxmode_mutex);
 798                        list_del(&e->node);
 799                        mutex_unlock(&muxmode_mutex);
 800                        omap_mux_free_names(m);
 801                        kfree(m);
 802#endif
 803                }
 804        }
 805
 806        omap_mux_dbg_init();
 807
 808        /* see pinctrl-single-omap for the wake-up interrupt handling */
 809        if (of_have_populated_dt())
 810                return 0;
 811
 812        ret = request_irq(omap_prcm_event_to_irq("io"),
 813                omap_hwmod_mux_handle_irq, IRQF_SHARED | IRQF_NO_SUSPEND,
 814                        "hwmod_io", omap_mux_late_init);
 815
 816        if (ret)
 817                pr_warn("mux: Failed to setup hwmod io irq %d\n", ret);
 818
 819        return 0;
 820}
 821
 822static void __init omap_mux_package_fixup(struct omap_mux *p,
 823                                        struct omap_mux *superset)
 824{
 825        while (p->reg_offset !=  OMAP_MUX_TERMINATOR) {
 826                struct omap_mux *s = superset;
 827                int found = 0;
 828
 829                while (s->reg_offset != OMAP_MUX_TERMINATOR) {
 830                        if (s->reg_offset == p->reg_offset) {
 831                                *s = *p;
 832                                found++;
 833                                break;
 834                        }
 835                        s++;
 836                }
 837                if (!found)
 838                        pr_err("%s: Unknown entry offset 0x%x\n", __func__,
 839                               p->reg_offset);
 840                p++;
 841        }
 842}
 843
 844#ifdef CONFIG_DEBUG_FS
 845
 846static void __init omap_mux_package_init_balls(struct omap_ball *b,
 847                                struct omap_mux *superset)
 848{
 849        while (b->reg_offset != OMAP_MUX_TERMINATOR) {
 850                struct omap_mux *s = superset;
 851                int found = 0;
 852
 853                while (s->reg_offset != OMAP_MUX_TERMINATOR) {
 854                        if (s->reg_offset == b->reg_offset) {
 855                                s->balls[0] = b->balls[0];
 856                                s->balls[1] = b->balls[1];
 857                                found++;
 858                                break;
 859                        }
 860                        s++;
 861                }
 862                if (!found)
 863                        pr_err("%s: Unknown ball offset 0x%x\n", __func__,
 864                               b->reg_offset);
 865                b++;
 866        }
 867}
 868
 869#else   /* CONFIG_DEBUG_FS */
 870
 871static inline void omap_mux_package_init_balls(struct omap_ball *b,
 872                                        struct omap_mux *superset)
 873{
 874}
 875
 876#endif  /* CONFIG_DEBUG_FS */
 877
 878static int __init omap_mux_setup(char *options)
 879{
 880        if (!options)
 881                return 0;
 882
 883        omap_mux_options = options;
 884
 885        return 1;
 886}
 887__setup("omap_mux=", omap_mux_setup);
 888
 889/*
 890 * Note that the omap_mux=some.signal1=0x1234,some.signal2=0x1234
 891 * cmdline options only override the bootloader values.
 892 * During development, please enable CONFIG_DEBUG_FS, and use the
 893 * signal specific entries under debugfs.
 894 */
 895static void __init omap_mux_set_cmdline_signals(void)
 896{
 897        char *options, *next_opt, *token;
 898
 899        if (!omap_mux_options)
 900                return;
 901
 902        options = kstrdup(omap_mux_options, GFP_KERNEL);
 903        if (!options)
 904                return;
 905
 906        next_opt = options;
 907
 908        while ((token = strsep(&next_opt, ",")) != NULL) {
 909                char *keyval, *name;
 910                u16 val;
 911
 912                keyval = token;
 913                name = strsep(&keyval, "=");
 914                if (name) {
 915                        int res;
 916
 917                        res = kstrtou16(keyval, 0x10, &val);
 918                        if (res < 0)
 919                                continue;
 920
 921                        omap_mux_init_signal(name, (u16)val);
 922                }
 923        }
 924
 925        kfree(options);
 926}
 927
 928static int __init omap_mux_copy_names(struct omap_mux *src,
 929                                      struct omap_mux *dst)
 930{
 931        int i;
 932
 933        for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
 934                if (src->muxnames[i]) {
 935                        dst->muxnames[i] = kstrdup(src->muxnames[i],
 936                                                   GFP_KERNEL);
 937                        if (!dst->muxnames[i])
 938                                goto free;
 939                }
 940        }
 941
 942#ifdef CONFIG_DEBUG_FS
 943        for (i = 0; i < OMAP_MUX_NR_SIDES; i++) {
 944                if (src->balls[i]) {
 945                        dst->balls[i] = kstrdup(src->balls[i], GFP_KERNEL);
 946                        if (!dst->balls[i])
 947                                goto free;
 948                }
 949        }
 950#endif
 951
 952        return 0;
 953
 954free:
 955        omap_mux_free_names(dst);
 956        return -ENOMEM;
 957
 958}
 959
 960#endif  /* CONFIG_OMAP_MUX */
 961
 962static struct omap_mux *omap_mux_get_by_gpio(
 963                                struct omap_mux_partition *partition,
 964                                int gpio)
 965{
 966        struct omap_mux_entry *e;
 967        struct omap_mux *ret = NULL;
 968
 969        list_for_each_entry(e, &partition->muxmodes, node) {
 970                struct omap_mux *m = &e->mux;
 971                if (m->gpio == gpio) {
 972                        ret = m;
 973                        break;
 974                }
 975        }
 976
 977        return ret;
 978}
 979
 980/* Needed for dynamic muxing of GPIO pins for off-idle */
 981u16 omap_mux_get_gpio(int gpio)
 982{
 983        struct omap_mux_partition *partition;
 984        struct omap_mux *m = NULL;
 985
 986        list_for_each_entry(partition, &mux_partitions, node) {
 987                m = omap_mux_get_by_gpio(partition, gpio);
 988                if (m)
 989                        return omap_mux_read(partition, m->reg_offset);
 990        }
 991
 992        if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
 993                pr_err("%s: Could not get gpio%i\n", __func__, gpio);
 994
 995        return OMAP_MUX_TERMINATOR;
 996}
 997
 998/* Needed for dynamic muxing of GPIO pins for off-idle */
 999void omap_mux_set_gpio(u16 val, int gpio)
1000{
1001        struct omap_mux_partition *partition;
1002        struct omap_mux *m = NULL;
1003
1004        list_for_each_entry(partition, &mux_partitions, node) {
1005                m = omap_mux_get_by_gpio(partition, gpio);
1006                if (m) {
1007                        omap_mux_write(partition, val, m->reg_offset);
1008                        return;
1009                }
1010        }
1011
1012        if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
1013                pr_err("%s: Could not set gpio%i\n", __func__, gpio);
1014}
1015
1016static struct omap_mux * __init omap_mux_list_add(
1017                                        struct omap_mux_partition *partition,
1018                                        struct omap_mux *src)
1019{
1020        struct omap_mux_entry *entry;
1021        struct omap_mux *m;
1022
1023        entry = kzalloc(sizeof(struct omap_mux_entry), GFP_KERNEL);
1024        if (!entry)
1025                return NULL;
1026
1027        m = &entry->mux;
1028        entry->mux = *src;
1029
1030#ifdef CONFIG_OMAP_MUX
1031        if (omap_mux_copy_names(src, m)) {
1032                kfree(entry);
1033                return NULL;
1034        }
1035#endif
1036
1037        mutex_lock(&muxmode_mutex);
1038        list_add_tail(&entry->node, &partition->muxmodes);
1039        mutex_unlock(&muxmode_mutex);
1040
1041        return m;
1042}
1043
1044/*
1045 * Note if CONFIG_OMAP_MUX is not selected, we will only initialize
1046 * the GPIO to mux offset mapping that is needed for dynamic muxing
1047 * of GPIO pins for off-idle.
1048 */
1049static void __init omap_mux_init_list(struct omap_mux_partition *partition,
1050                                      struct omap_mux *superset)
1051{
1052        while (superset->reg_offset !=  OMAP_MUX_TERMINATOR) {
1053                struct omap_mux *entry;
1054
1055#ifdef CONFIG_OMAP_MUX
1056                if (!superset->muxnames[0]) {
1057                        superset++;
1058                        continue;
1059                }
1060#else
1061                /* Skip pins that are not muxed as GPIO by bootloader */
1062                if (!OMAP_MODE_GPIO(partition, omap_mux_read(partition,
1063                                    superset->reg_offset))) {
1064                        superset++;
1065                        continue;
1066                }
1067#endif
1068
1069                entry = omap_mux_list_add(partition, superset);
1070                if (!entry) {
1071                        pr_err("%s: Could not add entry\n", __func__);
1072                        return;
1073                }
1074                superset++;
1075        }
1076}
1077
1078#ifdef CONFIG_OMAP_MUX
1079
1080static void omap_mux_init_package(struct omap_mux *superset,
1081                                  struct omap_mux *package_subset,
1082                                  struct omap_ball *package_balls)
1083{
1084        if (package_subset)
1085                omap_mux_package_fixup(package_subset, superset);
1086        if (package_balls)
1087                omap_mux_package_init_balls(package_balls, superset);
1088}
1089
1090static void __init omap_mux_init_signals(struct omap_mux_partition *partition,
1091                                         struct omap_board_mux *board_mux)
1092{
1093        omap_mux_set_cmdline_signals();
1094        omap_mux_write_array(partition, board_mux);
1095}
1096
1097#else
1098
1099static void omap_mux_init_package(struct omap_mux *superset,
1100                                  struct omap_mux *package_subset,
1101                                  struct omap_ball *package_balls)
1102{
1103}
1104
1105static void __init omap_mux_init_signals(struct omap_mux_partition *partition,
1106                                         struct omap_board_mux *board_mux)
1107{
1108}
1109
1110#endif
1111
1112static u32 mux_partitions_cnt;
1113
1114int __init omap_mux_init(const char *name, u32 flags,
1115                         u32 mux_pbase, u32 mux_size,
1116                         struct omap_mux *superset,
1117                         struct omap_mux *package_subset,
1118                         struct omap_board_mux *board_mux,
1119                         struct omap_ball *package_balls)
1120{
1121        struct omap_mux_partition *partition;
1122
1123        partition = kzalloc(sizeof(struct omap_mux_partition), GFP_KERNEL);
1124        if (!partition)
1125                return -ENOMEM;
1126
1127        partition->name = name;
1128        partition->flags = flags;
1129        partition->gpio = flags & OMAP_MUX_MODE7;
1130        partition->size = mux_size;
1131        partition->phys = mux_pbase;
1132        partition->base = ioremap(mux_pbase, mux_size);
1133        if (!partition->base) {
1134                pr_err("%s: Could not ioremap mux partition at 0x%08x\n",
1135                        __func__, partition->phys);
1136                kfree(partition);
1137                return -ENODEV;
1138        }
1139
1140        INIT_LIST_HEAD(&partition->muxmodes);
1141
1142        list_add_tail(&partition->node, &mux_partitions);
1143        mux_partitions_cnt++;
1144        pr_info("%s: Add partition: #%d: %s, flags: %x\n", __func__,
1145                mux_partitions_cnt, partition->name, partition->flags);
1146
1147        omap_mux_init_package(superset, package_subset, package_balls);
1148        omap_mux_init_list(partition, superset);
1149        omap_mux_init_signals(partition, board_mux);
1150
1151        return 0;
1152}
1153
1154