diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2013-01-31 04:03:11 -0500 |
---|---|---|
committer | Zhang Rui <rui.zhang@intel.com> | 2013-02-06 01:13:57 -0500 |
commit | f8f53e1874c2dfddf4c6dc69008ba85d6de4d944 (patch) | |
tree | 775477b103c1850c02097da2df82e0a8bd4edc8b /drivers/thermal | |
parent | 9dde8f86085d283042718f88eed017eccad73ab9 (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.c | 91 |
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, |