linux/drivers/pwm/core.c
<<
>>
Prefs
   1/*
   2 * Generic pwmlib implementation
   3 *
   4 * Copyright (C) 2011 Sascha Hauer <s.hauer@pengutronix.de>
   5 * Copyright (C) 2011-2012 Avionic Design GmbH
   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, or (at your option)
  10 *  any later version.
  11 *
  12 *  This program is distributed in the hope that it will be useful,
  13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 *  GNU General Public License for more details.
  16 *
  17 *  You should have received a copy of the GNU General Public License
  18 *  along with this program; see the file COPYING.  If not, write to
  19 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20 */
  21
  22#include <linux/module.h>
  23#include <linux/pwm.h>
  24#include <linux/radix-tree.h>
  25#include <linux/list.h>
  26#include <linux/mutex.h>
  27#include <linux/err.h>
  28#include <linux/slab.h>
  29#include <linux/device.h>
  30#include <linux/debugfs.h>
  31#include <linux/seq_file.h>
  32
  33#define MAX_PWMS 1024
  34
  35static DEFINE_MUTEX(pwm_lookup_lock);
  36static LIST_HEAD(pwm_lookup_list);
  37static DEFINE_MUTEX(pwm_lock);
  38static LIST_HEAD(pwm_chips);
  39static DECLARE_BITMAP(allocated_pwms, MAX_PWMS);
  40static RADIX_TREE(pwm_tree, GFP_KERNEL);
  41
  42static struct pwm_device *pwm_to_device(unsigned int pwm)
  43{
  44        return radix_tree_lookup(&pwm_tree, pwm);
  45}
  46
  47static int alloc_pwms(int pwm, unsigned int count)
  48{
  49        unsigned int from = 0;
  50        unsigned int start;
  51
  52        if (pwm >= MAX_PWMS)
  53                return -EINVAL;
  54
  55        if (pwm >= 0)
  56                from = pwm;
  57
  58        start = bitmap_find_next_zero_area(allocated_pwms, MAX_PWMS, from,
  59                                           count, 0);
  60
  61        if (pwm >= 0 && start != pwm)
  62                return -EEXIST;
  63
  64        if (start + count > MAX_PWMS)
  65                return -ENOSPC;
  66
  67        return start;
  68}
  69
  70static void free_pwms(struct pwm_chip *chip)
  71{
  72        unsigned int i;
  73
  74        for (i = 0; i < chip->npwm; i++) {
  75                struct pwm_device *pwm = &chip->pwms[i];
  76                radix_tree_delete(&pwm_tree, pwm->pwm);
  77        }
  78
  79        bitmap_clear(allocated_pwms, chip->base, chip->npwm);
  80
  81        kfree(chip->pwms);
  82        chip->pwms = NULL;
  83}
  84
  85static struct pwm_chip *pwmchip_find_by_name(const char *name)
  86{
  87        struct pwm_chip *chip;
  88
  89        if (!name)
  90                return NULL;
  91
  92        mutex_lock(&pwm_lock);
  93
  94        list_for_each_entry(chip, &pwm_chips, list) {
  95                const char *chip_name = dev_name(chip->dev);
  96
  97                if (chip_name && strcmp(chip_name, name) == 0) {
  98                        mutex_unlock(&pwm_lock);
  99                        return chip;
 100                }
 101        }
 102
 103        mutex_unlock(&pwm_lock);
 104
 105        return NULL;
 106}
 107
 108static int pwm_device_request(struct pwm_device *pwm, const char *label)
 109{
 110        int err;
 111
 112        if (test_bit(PWMF_REQUESTED, &pwm->flags))
 113                return -EBUSY;
 114
 115        if (!try_module_get(pwm->chip->ops->owner))
 116                return -ENODEV;
 117
 118        if (pwm->chip->ops->request) {
 119                err = pwm->chip->ops->request(pwm->chip, pwm);
 120                if (err) {
 121                        module_put(pwm->chip->ops->owner);
 122                        return err;
 123                }
 124        }
 125
 126        set_bit(PWMF_REQUESTED, &pwm->flags);
 127        pwm->label = label;
 128
 129        return 0;
 130}
 131
 132static struct pwm_device *
 133of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
 134{
 135        struct pwm_device *pwm;
 136
 137        if (pc->of_pwm_n_cells < 2)
 138                return ERR_PTR(-EINVAL);
 139
 140        if (args->args[0] >= pc->npwm)
 141                return ERR_PTR(-EINVAL);
 142
 143        pwm = pwm_request_from_chip(pc, args->args[0], NULL);
 144        if (IS_ERR(pwm))
 145                return pwm;
 146
 147        pwm_set_period(pwm, args->args[1]);
 148
 149        return pwm;
 150}
 151
 152static void of_pwmchip_add(struct pwm_chip *chip)
 153{
 154        if (!chip->dev || !chip->dev->of_node)
 155                return;
 156
 157        if (!chip->of_xlate) {
 158                chip->of_xlate = of_pwm_simple_xlate;
 159                chip->of_pwm_n_cells = 2;
 160        }
 161
 162        of_node_get(chip->dev->of_node);
 163}
 164
 165static void of_pwmchip_remove(struct pwm_chip *chip)
 166{
 167        if (chip->dev && chip->dev->of_node)
 168                of_node_put(chip->dev->of_node);
 169}
 170
 171/**
 172 * pwm_set_chip_data() - set private chip data for a PWM
 173 * @pwm: PWM device
 174 * @data: pointer to chip-specific data
 175 */
 176int pwm_set_chip_data(struct pwm_device *pwm, void *data)
 177{
 178        if (!pwm)
 179                return -EINVAL;
 180
 181        pwm->chip_data = data;
 182
 183        return 0;
 184}
 185
 186/**
 187 * pwm_get_chip_data() - get private chip data for a PWM
 188 * @pwm: PWM device
 189 */
 190void *pwm_get_chip_data(struct pwm_device *pwm)
 191{
 192        return pwm ? pwm->chip_data : NULL;
 193}
 194
 195/**
 196 * pwmchip_add() - register a new PWM chip
 197 * @chip: the PWM chip to add
 198 *
 199 * Register a new PWM chip. If chip->base < 0 then a dynamically assigned base
 200 * will be used.
 201 */
 202int pwmchip_add(struct pwm_chip *chip)
 203{
 204        struct pwm_device *pwm;
 205        unsigned int i;
 206        int ret;
 207
 208        if (!chip || !chip->dev || !chip->ops || !chip->ops->config ||
 209            !chip->ops->enable || !chip->ops->disable)
 210                return -EINVAL;
 211
 212        mutex_lock(&pwm_lock);
 213
 214        ret = alloc_pwms(chip->base, chip->npwm);
 215        if (ret < 0)
 216                goto out;
 217
 218        chip->pwms = kzalloc(chip->npwm * sizeof(*pwm), GFP_KERNEL);
 219        if (!chip->pwms) {
 220                ret = -ENOMEM;
 221                goto out;
 222        }
 223
 224        chip->base = ret;
 225
 226        for (i = 0; i < chip->npwm; i++) {
 227                pwm = &chip->pwms[i];
 228
 229                pwm->chip = chip;
 230                pwm->pwm = chip->base + i;
 231                pwm->hwpwm = i;
 232
 233                radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
 234        }
 235
 236        bitmap_set(allocated_pwms, chip->base, chip->npwm);
 237
 238        INIT_LIST_HEAD(&chip->list);
 239        list_add(&chip->list, &pwm_chips);
 240
 241        ret = 0;
 242
 243        if (IS_ENABLED(CONFIG_OF))
 244                of_pwmchip_add(chip);
 245
 246out:
 247        mutex_unlock(&pwm_lock);
 248        return ret;
 249}
 250EXPORT_SYMBOL_GPL(pwmchip_add);
 251
 252/**
 253 * pwmchip_remove() - remove a PWM chip
 254 * @chip: the PWM chip to remove
 255 *
 256 * Removes a PWM chip. This function may return busy if the PWM chip provides
 257 * a PWM device that is still requested.
 258 */
 259int pwmchip_remove(struct pwm_chip *chip)
 260{
 261        unsigned int i;
 262        int ret = 0;
 263
 264        mutex_lock(&pwm_lock);
 265
 266        for (i = 0; i < chip->npwm; i++) {
 267                struct pwm_device *pwm = &chip->pwms[i];
 268
 269                if (test_bit(PWMF_REQUESTED, &pwm->flags)) {
 270                        ret = -EBUSY;
 271                        goto out;
 272                }
 273        }
 274
 275        list_del_init(&chip->list);
 276
 277        if (IS_ENABLED(CONFIG_OF))
 278                of_pwmchip_remove(chip);
 279
 280        free_pwms(chip);
 281
 282out:
 283        mutex_unlock(&pwm_lock);
 284        return ret;
 285}
 286EXPORT_SYMBOL_GPL(pwmchip_remove);
 287
 288/**
 289 * pwm_request() - request a PWM device
 290 * @pwm_id: global PWM device index
 291 * @label: PWM device label
 292 *
 293 * This function is deprecated, use pwm_get() instead.
 294 */
 295struct pwm_device *pwm_request(int pwm, const char *label)
 296{
 297        struct pwm_device *dev;
 298        int err;
 299
 300        if (pwm < 0 || pwm >= MAX_PWMS)
 301                return ERR_PTR(-EINVAL);
 302
 303        mutex_lock(&pwm_lock);
 304
 305        dev = pwm_to_device(pwm);
 306        if (!dev) {
 307                dev = ERR_PTR(-EPROBE_DEFER);
 308                goto out;
 309        }
 310
 311        err = pwm_device_request(dev, label);
 312        if (err < 0)
 313                dev = ERR_PTR(err);
 314
 315out:
 316        mutex_unlock(&pwm_lock);
 317
 318        return dev;
 319}
 320EXPORT_SYMBOL_GPL(pwm_request);
 321
 322/**
 323 * pwm_request_from_chip() - request a PWM device relative to a PWM chip
 324 * @chip: PWM chip
 325 * @index: per-chip index of the PWM to request
 326 * @label: a literal description string of this PWM
 327 *
 328 * Returns the PWM at the given index of the given PWM chip. A negative error
 329 * code is returned if the index is not valid for the specified PWM chip or
 330 * if the PWM device cannot be requested.
 331 */
 332struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
 333                                         unsigned int index,
 334                                         const char *label)
 335{
 336        struct pwm_device *pwm;
 337        int err;
 338
 339        if (!chip || index >= chip->npwm)
 340                return ERR_PTR(-EINVAL);
 341
 342        mutex_lock(&pwm_lock);
 343        pwm = &chip->pwms[index];
 344
 345        err = pwm_device_request(pwm, label);
 346        if (err < 0)
 347                pwm = ERR_PTR(err);
 348
 349        mutex_unlock(&pwm_lock);
 350        return pwm;
 351}
 352EXPORT_SYMBOL_GPL(pwm_request_from_chip);
 353
 354/**
 355 * pwm_free() - free a PWM device
 356 * @pwm: PWM device
 357 *
 358 * This function is deprecated, use pwm_put() instead.
 359 */
 360void pwm_free(struct pwm_device *pwm)
 361{
 362        pwm_put(pwm);
 363}
 364EXPORT_SYMBOL_GPL(pwm_free);
 365
 366/**
 367 * pwm_config() - change a PWM device configuration
 368 * @pwm: PWM device
 369 * @duty_ns: "on" time (in nanoseconds)
 370 * @period_ns: duration (in nanoseconds) of one cycle
 371 */
 372int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
 373{
 374        if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
 375                return -EINVAL;
 376
 377        return pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
 378}
 379EXPORT_SYMBOL_GPL(pwm_config);
 380
 381/**
 382 * pwm_set_polarity() - configure the polarity of a PWM signal
 383 * @pwm: PWM device
 384 * @polarity: new polarity of the PWM signal
 385 *
 386 * Note that the polarity cannot be configured while the PWM device is enabled
 387 */
 388int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
 389{
 390        if (!pwm || !pwm->chip->ops)
 391                return -EINVAL;
 392
 393        if (!pwm->chip->ops->set_polarity)
 394                return -ENOSYS;
 395
 396        if (test_bit(PWMF_ENABLED, &pwm->flags))
 397                return -EBUSY;
 398
 399        return pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
 400}
 401EXPORT_SYMBOL_GPL(pwm_set_polarity);
 402
 403/**
 404 * pwm_enable() - start a PWM output toggling
 405 * @pwm: PWM device
 406 */
 407int pwm_enable(struct pwm_device *pwm)
 408{
 409        if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags))
 410                return pwm->chip->ops->enable(pwm->chip, pwm);
 411
 412        return pwm ? 0 : -EINVAL;
 413}
 414EXPORT_SYMBOL_GPL(pwm_enable);
 415
 416/**
 417 * pwm_disable() - stop a PWM output toggling
 418 * @pwm: PWM device
 419 */
 420void pwm_disable(struct pwm_device *pwm)
 421{
 422        if (pwm && test_and_clear_bit(PWMF_ENABLED, &pwm->flags))
 423                pwm->chip->ops->disable(pwm->chip, pwm);
 424}
 425EXPORT_SYMBOL_GPL(pwm_disable);
 426
 427static struct pwm_chip *of_node_to_pwmchip(struct device_node *np)
 428{
 429        struct pwm_chip *chip;
 430
 431        mutex_lock(&pwm_lock);
 432
 433        list_for_each_entry(chip, &pwm_chips, list)
 434                if (chip->dev && chip->dev->of_node == np) {
 435                        mutex_unlock(&pwm_lock);
 436                        return chip;
 437                }
 438
 439        mutex_unlock(&pwm_lock);
 440
 441        return ERR_PTR(-EPROBE_DEFER);
 442}
 443
 444/**
 445 * of_pwm_request() - request a PWM via the PWM framework
 446 * @np: device node to get the PWM from
 447 * @con_id: consumer name
 448 *
 449 * Returns the PWM device parsed from the phandle and index specified in the
 450 * "pwms" property of a device tree node or a negative error-code on failure.
 451 * Values parsed from the device tree are stored in the returned PWM device
 452 * object.
 453 *
 454 * If con_id is NULL, the first PWM device listed in the "pwms" property will
 455 * be requested. Otherwise the "pwm-names" property is used to do a reverse
 456 * lookup of the PWM index. This also means that the "pwm-names" property
 457 * becomes mandatory for devices that look up the PWM device via the con_id
 458 * parameter.
 459 */
 460static struct pwm_device *of_pwm_request(struct device_node *np,
 461                                         const char *con_id)
 462{
 463        struct pwm_device *pwm = NULL;
 464        struct of_phandle_args args;
 465        struct pwm_chip *pc;
 466        int index = 0;
 467        int err;
 468
 469        if (con_id) {
 470                index = of_property_match_string(np, "pwm-names", con_id);
 471                if (index < 0)
 472                        return ERR_PTR(index);
 473        }
 474
 475        err = of_parse_phandle_with_args(np, "pwms", "#pwm-cells", index,
 476                                         &args);
 477        if (err) {
 478                pr_debug("%s(): can't parse \"pwms\" property\n", __func__);
 479                return ERR_PTR(err);
 480        }
 481
 482        pc = of_node_to_pwmchip(args.np);
 483        if (IS_ERR(pc)) {
 484                pr_debug("%s(): PWM chip not found\n", __func__);
 485                pwm = ERR_CAST(pc);
 486                goto put;
 487        }
 488
 489        if (args.args_count != pc->of_pwm_n_cells) {
 490                pr_debug("%s: wrong #pwm-cells for %s\n", np->full_name,
 491                         args.np->full_name);
 492                pwm = ERR_PTR(-EINVAL);
 493                goto put;
 494        }
 495
 496        pwm = pc->of_xlate(pc, &args);
 497        if (IS_ERR(pwm))
 498                goto put;
 499
 500        /*
 501         * If a consumer name was not given, try to look it up from the
 502         * "pwm-names" property if it exists. Otherwise use the name of
 503         * the user device node.
 504         */
 505        if (!con_id) {
 506                err = of_property_read_string_index(np, "pwm-names", index,
 507                                                    &con_id);
 508                if (err < 0)
 509                        con_id = np->name;
 510        }
 511
 512        pwm->label = con_id;
 513
 514put:
 515        of_node_put(args.np);
 516
 517        return pwm;
 518}
 519
 520/**
 521 * pwm_add_table() - register PWM device consumers
 522 * @table: array of consumers to register
 523 * @num: number of consumers in table
 524 */
 525void __init pwm_add_table(struct pwm_lookup *table, size_t num)
 526{
 527        mutex_lock(&pwm_lookup_lock);
 528
 529        while (num--) {
 530                list_add_tail(&table->list, &pwm_lookup_list);
 531                table++;
 532        }
 533
 534        mutex_unlock(&pwm_lookup_lock);
 535}
 536
 537/**
 538 * pwm_get() - look up and request a PWM device
 539 * @dev: device for PWM consumer
 540 * @con_id: consumer name
 541 *
 542 * Lookup is first attempted using DT. If the device was not instantiated from
 543 * a device tree, a PWM chip and a relative index is looked up via a table
 544 * supplied by board setup code (see pwm_add_table()).
 545 *
 546 * Once a PWM chip has been found the specified PWM device will be requested
 547 * and is ready to be used.
 548 */
 549struct pwm_device *pwm_get(struct device *dev, const char *con_id)
 550{
 551        struct pwm_device *pwm = ERR_PTR(-EPROBE_DEFER);
 552        const char *dev_id = dev ? dev_name(dev) : NULL;
 553        struct pwm_chip *chip = NULL;
 554        unsigned int index = 0;
 555        unsigned int best = 0;
 556        struct pwm_lookup *p;
 557        unsigned int match;
 558
 559        /* look up via DT first */
 560        if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node)
 561                return of_pwm_request(dev->of_node, con_id);
 562
 563        /*
 564         * We look up the provider in the static table typically provided by
 565         * board setup code. We first try to lookup the consumer device by
 566         * name. If the consumer device was passed in as NULL or if no match
 567         * was found, we try to find the consumer by directly looking it up
 568         * by name.
 569         *
 570         * If a match is found, the provider PWM chip is looked up by name
 571         * and a PWM device is requested using the PWM device per-chip index.
 572         *
 573         * The lookup algorithm was shamelessly taken from the clock
 574         * framework:
 575         *
 576         * We do slightly fuzzy matching here:
 577         *  An entry with a NULL ID is assumed to be a wildcard.
 578         *  If an entry has a device ID, it must match
 579         *  If an entry has a connection ID, it must match
 580         * Then we take the most specific entry - with the following order
 581         * of precedence: dev+con > dev only > con only.
 582         */
 583        mutex_lock(&pwm_lookup_lock);
 584
 585        list_for_each_entry(p, &pwm_lookup_list, list) {
 586                match = 0;
 587
 588                if (p->dev_id) {
 589                        if (!dev_id || strcmp(p->dev_id, dev_id))
 590                                continue;
 591
 592                        match += 2;
 593                }
 594
 595                if (p->con_id) {
 596                        if (!con_id || strcmp(p->con_id, con_id))
 597                                continue;
 598
 599                        match += 1;
 600                }
 601
 602                if (match > best) {
 603                        chip = pwmchip_find_by_name(p->provider);
 604                        index = p->index;
 605
 606                        if (match != 3)
 607                                best = match;
 608                        else
 609                                break;
 610                }
 611        }
 612
 613        if (chip)
 614                pwm = pwm_request_from_chip(chip, index, con_id ?: dev_id);
 615
 616        mutex_unlock(&pwm_lookup_lock);
 617
 618        return pwm;
 619}
 620EXPORT_SYMBOL_GPL(pwm_get);
 621
 622/**
 623 * pwm_put() - release a PWM device
 624 * @pwm: PWM device
 625 */
 626void pwm_put(struct pwm_device *pwm)
 627{
 628        if (!pwm)
 629                return;
 630
 631        mutex_lock(&pwm_lock);
 632
 633        if (!test_and_clear_bit(PWMF_REQUESTED, &pwm->flags)) {
 634                pr_warn("PWM device already freed\n");
 635                goto out;
 636        }
 637
 638        if (pwm->chip->ops->free)
 639                pwm->chip->ops->free(pwm->chip, pwm);
 640
 641        pwm->label = NULL;
 642
 643        module_put(pwm->chip->ops->owner);
 644out:
 645        mutex_unlock(&pwm_lock);
 646}
 647EXPORT_SYMBOL_GPL(pwm_put);
 648
 649static void devm_pwm_release(struct device *dev, void *res)
 650{
 651        pwm_put(*(struct pwm_device **)res);
 652}
 653
 654/**
 655 * devm_pwm_get() - resource managed pwm_get()
 656 * @dev: device for PWM consumer
 657 * @con_id: consumer name
 658 *
 659 * This function performs like pwm_get() but the acquired PWM device will
 660 * automatically be released on driver detach.
 661 */
 662struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id)
 663{
 664        struct pwm_device **ptr, *pwm;
 665
 666        ptr = devres_alloc(devm_pwm_release, sizeof(**ptr), GFP_KERNEL);
 667        if (!ptr)
 668                return ERR_PTR(-ENOMEM);
 669
 670        pwm = pwm_get(dev, con_id);
 671        if (!IS_ERR(pwm)) {
 672                *ptr = pwm;
 673                devres_add(dev, ptr);
 674        } else {
 675                devres_free(ptr);
 676        }
 677
 678        return pwm;
 679}
 680EXPORT_SYMBOL_GPL(devm_pwm_get);
 681
 682static int devm_pwm_match(struct device *dev, void *res, void *data)
 683{
 684        struct pwm_device **p = res;
 685
 686        if (WARN_ON(!p || !*p))
 687                return 0;
 688
 689        return *p == data;
 690}
 691
 692/**
 693 * devm_pwm_put() - resource managed pwm_put()
 694 * @dev: device for PWM consumer
 695 * @pwm: PWM device
 696 *
 697 * Release a PWM previously allocated using devm_pwm_get(). Calling this
 698 * function is usually not needed because devm-allocated resources are
 699 * automatically released on driver detach.
 700 */
 701void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
 702{
 703        WARN_ON(devres_release(dev, devm_pwm_release, devm_pwm_match, pwm));
 704}
 705EXPORT_SYMBOL_GPL(devm_pwm_put);
 706
 707#ifdef CONFIG_DEBUG_FS
 708static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
 709{
 710        unsigned int i;
 711
 712        for (i = 0; i < chip->npwm; i++) {
 713                struct pwm_device *pwm = &chip->pwms[i];
 714
 715                seq_printf(s, " pwm-%-3d (%-20.20s):", i, pwm->label);
 716
 717                if (test_bit(PWMF_REQUESTED, &pwm->flags))
 718                        seq_printf(s, " requested");
 719
 720                if (test_bit(PWMF_ENABLED, &pwm->flags))
 721                        seq_printf(s, " enabled");
 722
 723                seq_printf(s, "\n");
 724        }
 725}
 726
 727static void *pwm_seq_start(struct seq_file *s, loff_t *pos)
 728{
 729        mutex_lock(&pwm_lock);
 730        s->private = "";
 731
 732        return seq_list_start(&pwm_chips, *pos);
 733}
 734
 735static void *pwm_seq_next(struct seq_file *s, void *v, loff_t *pos)
 736{
 737        s->private = "\n";
 738
 739        return seq_list_next(v, &pwm_chips, pos);
 740}
 741
 742static void pwm_seq_stop(struct seq_file *s, void *v)
 743{
 744        mutex_unlock(&pwm_lock);
 745}
 746
 747static int pwm_seq_show(struct seq_file *s, void *v)
 748{
 749        struct pwm_chip *chip = list_entry(v, struct pwm_chip, list);
 750
 751        seq_printf(s, "%s%s/%s, %d PWM device%s\n", (char *)s->private,
 752                   chip->dev->bus ? chip->dev->bus->name : "no-bus",
 753                   dev_name(chip->dev), chip->npwm,
 754                   (chip->npwm != 1) ? "s" : "");
 755
 756        if (chip->ops->dbg_show)
 757                chip->ops->dbg_show(chip, s);
 758        else
 759                pwm_dbg_show(chip, s);
 760
 761        return 0;
 762}
 763
 764static const struct seq_operations pwm_seq_ops = {
 765        .start = pwm_seq_start,
 766        .next = pwm_seq_next,
 767        .stop = pwm_seq_stop,
 768        .show = pwm_seq_show,
 769};
 770
 771static int pwm_seq_open(struct inode *inode, struct file *file)
 772{
 773        return seq_open(file, &pwm_seq_ops);
 774}
 775
 776static const struct file_operations pwm_debugfs_ops = {
 777        .owner = THIS_MODULE,
 778        .open = pwm_seq_open,
 779        .read = seq_read,
 780        .llseek = seq_lseek,
 781        .release = seq_release,
 782};
 783
 784static int __init pwm_debugfs_init(void)
 785{
 786        debugfs_create_file("pwm", S_IFREG | S_IRUGO, NULL, NULL,
 787                            &pwm_debugfs_ops);
 788
 789        return 0;
 790}
 791
 792subsys_initcall(pwm_debugfs_init);
 793#endif /* CONFIG_DEBUG_FS */
 794
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.