aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2013-01-31 04:03:11 -0500
committerZhang Rui <rui.zhang@intel.com>2013-02-06 01:13:57 -0500
commitf8f53e1874c2dfddf4c6dc69008ba85d6de4d944 (patch)
tree775477b103c1850c02097da2df82e0a8bd4edc8b /drivers/thermal
parent9dde8f86085d283042718f88eed017eccad73ab9 (diff)
thermal: rcar: enable CPCTL to use hardware TSC deciding
If CPCTL was 1 on R-Car thermal, the thermal comparator offset is automatically decided by hardware. And this CPCTL is the conditions which validate interrupt. This patch enabled CPCTL. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/rcar_thermal.c91
1 files changed, 26 insertions, 65 deletions
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index 47b2b227c91e..068b2a1c5c15 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -33,7 +33,7 @@
33#define THSSR 0x30 33#define THSSR 0x30
34 34
35/* THSCR */ 35/* THSCR */
36#define CPTAP 0xf 36#define CPCTL (1 << 12)
37 37
38/* THSSR */ 38/* THSSR */
39#define CTEMP 0x3f 39#define CTEMP 0x3f
@@ -43,11 +43,11 @@ struct rcar_thermal_priv {
43 void __iomem *base; 43 void __iomem *base;
44 struct device *dev; 44 struct device *dev;
45 spinlock_t lock; 45 spinlock_t lock;
46 u32 comp;
47}; 46};
48 47
49#define MCELSIUS(temp) ((temp) * 1000) 48#define MCELSIUS(temp) ((temp) * 1000)
50#define rcar_zone_to_priv(zone) ((zone)->devdata) 49#define rcar_zone_to_priv(zone) ((zone)->devdata)
50#define rcar_priv_to_dev(priv) ((priv)->dev)
51 51
52/* 52/*
53 * basic functions 53 * basic functions
@@ -103,79 +103,41 @@ static int rcar_thermal_get_temp(struct thermal_zone_device *zone,
103 unsigned long *temp) 103 unsigned long *temp)
104{ 104{
105 struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone); 105 struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
106 int val, min, max, tmp; 106 struct device *dev = rcar_priv_to_dev(priv);
107 107 int i;
108 tmp = -200; /* default */ 108 int ctemp, old, new;
109 while (1) { 109
110 if (priv->comp < 1 || priv->comp > 12) { 110 /*
111 dev_err(priv->dev, 111 * TSC decides a value of CPTAP automatically,
112 "THSSR invalid data (%d)\n", priv->comp); 112 * and this is the conditions which validate interrupt.
113 priv->comp = 4; /* for next thermal */ 113 */
114 return -EINVAL; 114 rcar_thermal_bset(priv, THSCR, CPCTL, CPCTL);
115 } 115
116 116 ctemp = 0;
117 /* 117 old = ~0;
118 * THS comparator offset and the reference temperature 118 for (i = 0; i < 128; i++) {
119 *
120 * Comparator | reference | Temperature field
121 * offset | temperature | measurement
122 * | (degrees C) | (degrees C)
123 * -------------+---------------+-------------------
124 * 1 | -45 | -45 to -30
125 * 2 | -30 | -30 to -15
126 * 3 | -15 | -15 to 0
127 * 4 | 0 | 0 to +15
128 * 5 | +15 | +15 to +30
129 * 6 | +30 | +30 to +45
130 * 7 | +45 | +45 to +60
131 * 8 | +60 | +60 to +75
132 * 9 | +75 | +75 to +90
133 * 10 | +90 | +90 to +105
134 * 11 | +105 | +105 to +120
135 * 12 | +120 | +120 to +135
136 */
137
138 /* calculate thermal limitation */
139 min = (priv->comp * 15) - 60;
140 max = min + 15;
141
142 /* 119 /*
143 * we need to wait 300us after changing comparator offset 120 * we need to wait 300us after changing comparator offset
144 * to get stable temperature. 121 * to get stable temperature.
145 * see "Usage Notes" on datasheet 122 * see "Usage Notes" on datasheet
146 */ 123 */
147 rcar_thermal_bset(priv, THSCR, CPTAP, priv->comp);
148 udelay(300); 124 udelay(300);
149 125
150 /* calculate current temperature */ 126 new = rcar_thermal_read(priv, THSSR) & CTEMP;
151 val = rcar_thermal_read(priv, THSSR) & CTEMP; 127 if (new == old) {
152 val = (val * 5) - 65; 128 ctemp = new;
153
154 dev_dbg(priv->dev, "comp/min/max/val = %d/%d/%d/%d\n",
155 priv->comp, min, max, val);
156
157 /*
158 * If val is same as min/max, then,
159 * it should try again on next comparator.
160 * But the val might be correct temperature.
161 * Keep it on "tmp" and compare with next val.
162 */
163 if (tmp == val)
164 break;
165
166 if (val <= min) {
167 tmp = min;
168 priv->comp--; /* try again */
169 } else if (val >= max) {
170 tmp = max;
171 priv->comp++; /* try again */
172 } else {
173 tmp = val;
174 break; 129 break;
175 } 130 }
131 old = new;
176 } 132 }
177 133
178 *temp = MCELSIUS(tmp); 134 if (!ctemp) {
135 dev_err(dev, "thermal sensor was broken\n");
136 return -EINVAL;
137 }
138
139 *temp = MCELSIUS((ctemp * 5) - 65);
140
179 return 0; 141 return 0;
180} 142}
181 143
@@ -262,7 +224,6 @@ static int rcar_thermal_probe(struct platform_device *pdev)
262 return -ENOMEM; 224 return -ENOMEM;
263 } 225 }
264 226
265 priv->comp = 4; /* basic setup */
266 priv->dev = &pdev->dev; 227 priv->dev = &pdev->dev;
267 spin_lock_init(&priv->lock); 228 spin_lock_init(&priv->lock);
268 priv->base = devm_ioremap_nocache(&pdev->dev, 229 priv->base = devm_ioremap_nocache(&pdev->dev,