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/pm_opp.h> 21 #include <linux/rculist.h> 22 #include <linux/rcupdate.h> 23 24 /* Lock to allow exclusive modification to the device and opp lists */ 25 extern struct mutex dev_opp_list_lock; 26 27 /* 28 * Internal data structure organization with the OPP layer library is as 29 * follows: 30 * dev_opp_list (root) 31 * |- device 1 (represents voltage domain 1) 32 * | |- opp 1 (availability, freq, voltage) 33 * | |- opp 2 .. 34 * ... ... 35 * | `- opp n .. 36 * |- device 2 (represents the next voltage domain) 37 * ... 38 * `- device m (represents mth voltage domain) 39 * device 1, 2.. are represented by dev_opp structure while each opp 40 * is represented by the opp structure. 41 */ 42 43 /** 44 * struct dev_pm_opp - Generic OPP description structure 45 * @node: opp list node. The nodes are maintained throughout the lifetime 46 * of boot. It is expected only an optimal set of OPPs are 47 * added to the library by the SoC framework. 48 * RCU usage: opp list is traversed with RCU locks. node 49 * modification is possible realtime, hence the modifications 50 * are protected by the dev_opp_list_lock for integrity. 51 * IMPORTANT: the opp nodes should be maintained in increasing 52 * order. 53 * @dynamic: not-created from static DT entries. 54 * @available: true/false - marks if this OPP as available or not 55 * @turbo: true if turbo (boost) OPP 56 * @rate: Frequency in hertz 57 * @u_volt: Target voltage in microvolts corresponding to this OPP 58 * @u_volt_min: Minimum voltage in microvolts corresponding to this OPP 59 * @u_volt_max: Maximum voltage in microvolts corresponding to this OPP 60 * @u_amp: Maximum current drawn by the device in microamperes 61 * @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's 62 * frequency from any other OPP's frequency. 63 * @dev_opp: points back to the device_opp struct this opp belongs to 64 * @rcu_head: RCU callback head used for deferred freeing 65 * @np: OPP's device node. 66 * 67 * This structure stores the OPP information for a given device. 68 */ 69 struct dev_pm_opp { 70 struct list_head node; 71 72 bool available; 73 bool dynamic; 74 bool turbo; 75 unsigned long rate; 76 77 unsigned long u_volt; 78 unsigned long u_volt_min; 79 unsigned long u_volt_max; 80 unsigned long u_amp; 81 unsigned long clock_latency_ns; 82 83 struct device_opp *dev_opp; 84 struct rcu_head rcu_head; 85 86 struct device_node *np; 87 }; 88 89 /** 90 * struct device_list_opp - devices managed by 'struct device_opp' 91 * @node: list node 92 * @dev: device to which the struct object belongs 93 * @rcu_head: RCU callback head used for deferred freeing 94 * 95 * This is an internal data structure maintaining the list of devices that are 96 * managed by 'struct device_opp'. 97 */ 98 struct device_list_opp { 99 struct list_head node; 100 const struct device *dev; 101 struct rcu_head rcu_head; 102 }; 103 104 /** 105 * struct device_opp - Device opp structure 106 * @node: list node - contains the devices with OPPs that 107 * have been registered. Nodes once added are not modified in this 108 * list. 109 * RCU usage: nodes are not modified in the list of device_opp, 110 * however addition is possible and is secured by dev_opp_list_lock 111 * @srcu_head: notifier head to notify the OPP availability changes. 112 * @rcu_head: RCU callback head used for deferred freeing 113 * @dev_list: list of devices that share these OPPs 114 * @opp_list: list of opps 115 * @np: struct device_node pointer for opp's DT node. 116 * @shared_opp: OPP is shared between multiple devices. 117 * 118 * This is an internal data structure maintaining the link to opps attached to 119 * a device. This structure is not meant to be shared to users as it is 120 * meant for book keeping and private to OPP library. 121 * 122 * Because the opp structures can be used from both rcu and srcu readers, we 123 * need to wait for the grace period of both of them before freeing any 124 * resources. And so we have used kfree_rcu() from within call_srcu() handlers. 125 */ 126 struct device_opp { 127 struct list_head node; 128 129 struct srcu_notifier_head srcu_head; 130 struct rcu_head rcu_head; 131 struct list_head dev_list; 132 struct list_head opp_list; 133 134 struct device_node *np; 135 unsigned long clock_latency_ns_max; 136 bool shared_opp; 137 struct dev_pm_opp *suspend_opp; 138 }; 139 140 /* Routines internal to opp core */ 141 struct device_opp *_find_device_opp(struct device *dev); 142 struct device_list_opp *_add_list_dev(const struct device *dev, 143 struct device_opp *dev_opp); 144 struct device_node *_of_get_opp_desc_node(struct device *dev); 145 146 #endif /* __DRIVER_OPP_H__ */ 147