diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-07 21:03:30 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-07 21:03:30 +0100 |
commit | 7affca3537d74365128e477b40c529d6f2fe86c8 (patch) | |
tree | 20be92bd240029182fc89c2c4f25401b7715dcae /drivers/w1/slaves | |
parent | Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gee... (diff) | |
parent | Merge branch 'driver-core-next' into Linux 3.2 (diff) | |
download | linux-7affca3537d74365128e477b40c529d6f2fe86c8.tar.xz linux-7affca3537d74365128e477b40c529d6f2fe86c8.zip |
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')
-rw-r--r-- | drivers/w1/slaves/w1_therm.c | 36 |
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, { struct w1_slave *sl = dev_to_w1_slave(device); struct w1_master *dev = sl->master; - u8 rom[9], crc, verdict; + u8 rom[9], crc, verdict, external_power; int i, max_trying = 10; ssize_t c = PAGE_SIZE; - mutex_lock(&dev->mutex); + i = mutex_lock_interruptible(&dev->mutex); + if (i != 0) + return i; memset(rom, 0, sizeof(rom)); @@ -190,13 +192,37 @@ static ssize_t w1_therm_read(struct device *device, if (!w1_reset_select_slave(sl)) { int count = 0; unsigned int tm = 750; + unsigned long sleep_rem; + + w1_write_8(dev, W1_READ_PSUPPLY); + external_power = w1_read_8(dev); + + if (w1_reset_select_slave(sl)) + continue; /* 750ms strong pullup (or delay) after the convert */ - if (w1_strong_pullup) + if (!external_power && w1_strong_pullup) w1_next_pullup(dev, tm); + w1_write_8(dev, W1_CONVERT_TEMP); - if (!w1_strong_pullup) - msleep(tm); + + if (external_power) { + mutex_unlock(&dev->mutex); + + sleep_rem = msleep_interruptible(tm); + if (sleep_rem != 0) + return -EINTR; + + i = mutex_lock_interruptible(&dev->mutex); + if (i != 0) + return i; + } else if (!w1_strong_pullup) { + sleep_rem = msleep_interruptible(tm); + if (sleep_rem != 0) { + mutex_unlock(&dev->mutex); + return -EINTR; + } + } if (!w1_reset_select_slave(sl)) { |