linux/drivers/base/power/opp/opp.h
<<
>>
Prefs
   1/*
   2 * Generic OPP Interface
   3 *
   4 * Copyright (C) 2009-2010 Texas Instruments Incorporated.
   5 *      Nishanth Menon
   6 *      Romit Dasgupta
   7 *      Kevin Hilman
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 */
  13
  14#ifndef __DRIVER_OPP_H__
  15#define __DRIVER_OPP_H__
  16
  17#include <linux/device.h>
  18#include <linux/kernel.h>
  19#include <linux/list.h>
  20#include <linux/limits.h>
  21#include <linux/pm_opp.h>
  22#include <linux/rculist.h>
  23#include <linux/rcupdate.h>
  24
  25struct clk;
  26struct regulator;
  27
  28/* Lock to allow exclusive modification to the device and opp lists */
  29extern struct mutex opp_table_lock;
  30
  31extern struct list_head opp_tables;
  32
  33/*
  34 * Internal data structure organization with the OPP layer library is as
  35 * follows:
  36 * opp_tables (root)
  37 *      |- device 1 (represents voltage domain 1)
  38 *      |       |- opp 1 (availability, freq, voltage)
  39 *      |       |- opp 2 ..
  40 *      ...     ...
  41 *      |       `- opp n ..
  42 *      |- device 2 (represents the next voltage domain)
  43 *      ...
  44 *      `- device m (represents mth voltage domain)
  45 * device 1, 2.. are represented by opp_table structure while each opp
  46 * is represented by the opp structure.
  47 */
  48
  49/**
  50 * struct dev_pm_opp - Generic OPP description structure
  51 * @node:       opp table node. The nodes are maintained throughout the lifetime
  52 *              of boot. It is expected only an optimal set of OPPs are
  53 *              added to the library by the SoC framework.
  54 *              RCU usage: opp table is traversed with RCU locks. node
  55 *              modification is possible realtime, hence the modifications
  56 *              are protected by the opp_table_lock for integrity.
  57 *              IMPORTANT: the opp nodes should be maintained in increasing
  58 *              order.
  59 * @available:  true/false - marks if this OPP as available or not
  60 * @dynamic:    not-created from static DT entries.
  61 * @turbo:      true if turbo (boost) OPP
  62 * @suspend:    true if suspend OPP
  63 * @rate:       Frequency in hertz
  64 * @u_volt:     Target voltage in microvolts corresponding to this OPP
  65 * @u_volt_min: Minimum voltage in microvolts corresponding to this OPP
  66 * @u_volt_max: Maximum voltage in microvolts corresponding to this OPP
  67 * @u_amp:      Maximum current drawn by the device in microamperes
  68 * @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's
  69 *              frequency from any other OPP's frequency.
  70 * @opp_table:  points back to the opp_table struct this opp belongs to
  71 * @rcu_head:   RCU callback head used for deferred freeing
  72 * @np:         OPP's device node.
  73 * @dentry:     debugfs dentry pointer (per opp)
  74 *
  75 * This structure stores the OPP information for a given device.
  76 */
  77struct dev_pm_opp {
  78        struct list_head node;
  79
  80        bool available;
  81        bool dynamic;
  82        bool turbo;
  83        bool suspend;
  84        unsigned long rate;
  85
  86        unsigned long u_volt;
  87        unsigned long u_volt_min;
  88        unsigned long u_volt_max;
  89        unsigned long u_amp;
  90        unsigned long clock_latency_ns;
  91
  92        struct opp_table *opp_table;
  93        struct rcu_head rcu_head;
  94
  95        struct device_node *np;
  96
  97#ifdef CONFIG_DEBUG_FS
  98        struct dentry *dentry;
  99#endif
 100};
 101
 102/**
 103 * struct opp_device - devices managed by 'struct opp_table'
 104 * @node:       list node
 105 * @dev:        device to which the struct object belongs
 106 * @rcu_head:   RCU callback head used for deferred freeing
 107 * @dentry:     debugfs dentry pointer (per device)
 108 *
 109 * This is an internal data structure maintaining the devices that are managed
 110 * by 'struct opp_table'.
 111 */
 112struct opp_device {
 113        struct list_head node;
 114        const struct device *dev;
 115        struct rcu_head rcu_head;
 116
 117#ifdef CONFIG_DEBUG_FS
 118        struct dentry *dentry;
 119#endif
 120};
 121
 122enum opp_table_access {
 123        OPP_TABLE_ACCESS_UNKNOWN = 0,
 124        OPP_TABLE_ACCESS_EXCLUSIVE = 1,
 125        OPP_TABLE_ACCESS_SHARED = 2,
 126};
 127
 128/**
 129 * struct opp_table - Device opp structure
 130 * @node:       table node - contains the devices with OPPs that
 131 *              have been registered. Nodes once added are not modified in this
 132 *              table.
 133 *              RCU usage: nodes are not modified in the table of opp_table,
 134 *              however addition is possible and is secured by opp_table_lock
 135 * @srcu_head:  notifier head to notify the OPP availability changes.
 136 * @rcu_head:   RCU callback head used for deferred freeing
 137 * @dev_list:   list of devices that share these OPPs
 138 * @opp_list:   table of opps
 139 * @np:         struct device_node pointer for opp's DT node.
 140 * @clock_latency_ns_max: Max clock latency in nanoseconds.
 141 * @shared_opp: OPP is shared between multiple devices.
 142 * @suspend_opp: Pointer to OPP to be used during device suspend.
 143 * @supported_hw: Array of version number to support.
 144 * @supported_hw_count: Number of elements in supported_hw array.
 145 * @prop_name: A name to postfix to many DT properties, while parsing them.
 146 * @clk: Device's clock handle
 147 * @regulator: Supply regulator
 148 * @dentry:     debugfs dentry pointer of the real device directory (not links).
 149 * @dentry_name: Name of the real dentry.
 150 *
 151 * @voltage_tolerance_v1: In percentage, for v1 bindings only.
 152 *
 153 * This is an internal data structure maintaining the link to opps attached to
 154 * a device. This structure is not meant to be shared to users as it is
 155 * meant for book keeping and private to OPP library.
 156 *
 157 * Because the opp structures can be used from both rcu and srcu readers, we
 158 * need to wait for the grace period of both of them before freeing any
 159 * resources. And so we have used kfree_rcu() from within call_srcu() handlers.
 160 */
 161struct opp_table {
 162        struct list_head node;
 163
 164        struct srcu_notifier_head srcu_head;
 165        struct rcu_head rcu_head;
 166        struct list_head dev_list;
 167        struct list_head opp_list;
 168
 169        struct device_node *np;
 170        unsigned long clock_latency_ns_max;
 171
 172        /* For backward compatibility with v1 bindings */
 173        unsigned int voltage_tolerance_v1;
 174
 175        enum opp_table_access shared_opp;
 176        struct dev_pm_opp *suspend_opp;
 177
 178        unsigned int *supported_hw;
 179        unsigned int supported_hw_count;
 180        const char *prop_name;
 181        struct clk *clk;
 182        struct regulator *regulator;
 183
 184#ifdef CONFIG_DEBUG_FS
 185        struct dentry *dentry;
 186        char dentry_name[NAME_MAX];
 187#endif
 188};
 189
 190/* Routines internal to opp core */
 191struct opp_table *_find_opp_table(struct device *dev);
 192struct opp_device *_add_opp_dev(const struct device *dev, struct opp_table *opp_table);
 193struct device_node *_of_get_opp_desc_node(struct device *dev);
 194void _dev_pm_opp_remove_table(struct device *dev, bool remove_all);
 195struct dev_pm_opp *_allocate_opp(struct device *dev, struct opp_table **opp_table);
 196int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_table *opp_table);
 197void _opp_remove(struct opp_table *opp_table, struct dev_pm_opp *opp, bool notify);
 198int _opp_add_v1(struct device *dev, unsigned long freq, long u_volt, bool dynamic);
 199void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, bool of);
 200
 201#ifdef CONFIG_OF
 202void _of_init_opp_table(struct opp_table *opp_table, struct device *dev);
 203#else
 204static inline void _of_init_opp_table(struct opp_table *opp_table, struct device *dev) {}
 205#endif
 206
 207#ifdef CONFIG_DEBUG_FS
 208void opp_debug_remove_one(struct dev_pm_opp *opp);
 209int opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table);
 210int opp_debug_register(struct opp_device *opp_dev, struct opp_table *opp_table);
 211void opp_debug_unregister(struct opp_device *opp_dev, struct opp_table *opp_table);
 212#else
 213static inline void opp_debug_remove_one(struct dev_pm_opp *opp) {}
 214
 215static inline int opp_debug_create_one(struct dev_pm_opp *opp,
 216                                       struct opp_table *opp_table)
 217{ return 0; }
 218static inline int opp_debug_register(struct opp_device *opp_dev,
 219                                     struct opp_table *opp_table)
 220{ return 0; }
 221
 222static inline void opp_debug_unregister(struct opp_device *opp_dev,
 223                                        struct opp_table *opp_table)
 224{ }
 225#endif          /* DEBUG_FS */
 226
 227#endif          /* __DRIVER_OPP_H__ */
 228