aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1/slaves/w1_therm.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-07 15:03:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-07 15:03:30 -0500
commit7affca3537d74365128e477b40c529d6f2fe86c8 (patch)
tree20be92bd240029182fc89c2c4f25401b7715dcae /drivers/w1/slaves/w1_therm.c
parent356b95424cfb456e14a59eaa579422ce014c424b (diff)
parentff4b8a57f0aaa2882d444ca44b2b9b333d22a4df (diff)
Merge branch 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
* 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (73 commits) arm: fix up some samsung merge sysdev conversion problems firmware: Fix an oops on reading fw_priv->fw in sysfs loading file Drivers:hv: Fix a bug in vmbus_driver_unregister() driver core: remove __must_check from device_create_file debugfs: add missing #ifdef HAS_IOMEM arm: time.h: remove device.h #include driver-core: remove sysdev.h usage. clockevents: remove sysdev.h arm: convert sysdev_class to a regular subsystem arm: leds: convert sysdev_class to a regular subsystem kobject: remove kset_find_obj_hinted() m86k: gpio - convert sysdev_class to a regular subsystem mips: txx9_sram - convert sysdev_class to a regular subsystem mips: 7segled - convert sysdev_class to a regular subsystem sh: dma - convert sysdev_class to a regular subsystem sh: intc - convert sysdev_class to a regular subsystem power: suspend - convert sysdev_class to a regular subsystem power: qe_ic - convert sysdev_class to a regular subsystem power: cmm - convert sysdev_class to a regular subsystem s390: time - convert sysdev_class to a regular subsystem ... Fix up conflicts with 'struct sysdev' removal from various platform drivers that got changed: - arch/arm/mach-exynos/cpu.c - arch/arm/mach-exynos/irq-eint.c - arch/arm/mach-s3c64xx/common.c - arch/arm/mach-s3c64xx/cpu.c - arch/arm/mach-s5p64x0/cpu.c - arch/arm/mach-s5pv210/common.c - arch/arm/plat-samsung/include/plat/cpu.h - arch/powerpc/kernel/sysfs.c and fix up cpu_is_hotpluggable() as per Greg in include/linux/cpu.h
Diffstat (limited to 'drivers/w1/slaves/w1_therm.c')
-rw-r--r--drivers/w1/slaves/w1_therm.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index a1ef9b5b38cf..ff29ae747ee8 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -175,11 +175,13 @@ static ssize_t w1_therm_read(struct device *device,
175{ 175{
176 struct w1_slave *sl = dev_to_w1_slave(device); 176 struct w1_slave *sl = dev_to_w1_slave(device);
177 struct w1_master *dev = sl->master; 177 struct w1_master *dev = sl->master;
178 u8 rom[9], crc, verdict; 178 u8 rom[9], crc, verdict, external_power;
179 int i, max_trying = 10; 179 int i, max_trying = 10;
180 ssize_t c = PAGE_SIZE; 180 ssize_t c = PAGE_SIZE;
181 181
182 mutex_lock(&dev->mutex); 182 i = mutex_lock_interruptible(&dev->mutex);
183 if (i != 0)
184 return i;
183 185
184 memset(rom, 0, sizeof(rom)); 186 memset(rom, 0, sizeof(rom));
185 187
@@ -190,13 +192,37 @@ static ssize_t w1_therm_read(struct device *device,
190 if (!w1_reset_select_slave(sl)) { 192 if (!w1_reset_select_slave(sl)) {
191 int count = 0; 193 int count = 0;
192 unsigned int tm = 750; 194 unsigned int tm = 750;
195 unsigned long sleep_rem;
196
197 w1_write_8(dev, W1_READ_PSUPPLY);
198 external_power = w1_read_8(dev);
199
200 if (w1_reset_select_slave(sl))
201 continue;
193 202
194 /* 750ms strong pullup (or delay) after the convert */ 203 /* 750ms strong pullup (or delay) after the convert */
195 if (w1_strong_pullup) 204 if (!external_power && w1_strong_pullup)
196 w1_next_pullup(dev, tm); 205 w1_next_pullup(dev, tm);
206
197 w1_write_8(dev, W1_CONVERT_TEMP); 207 w1_write_8(dev, W1_CONVERT_TEMP);
198 if (!w1_strong_pullup) 208
199 msleep(tm); 209 if (external_power) {
210 mutex_unlock(&dev->mutex);
211
212 sleep_rem = msleep_interruptible(tm);
213 if (sleep_rem != 0)
214 return -EINTR;
215
216 i = mutex_lock_interruptible(&dev->mutex);
217 if (i != 0)
218 return i;
219 } else if (!w1_strong_pullup) {
220 sleep_rem = msleep_interruptible(tm);
221 if (sleep_rem != 0) {
222 mutex_unlock(&dev->mutex);
223 return -EINTR;
224 }
225 }
200 226
201 if (!w1_reset_select_slave(sl)) { 227 if (!w1_reset_select_slave(sl)) {
202 228