diff options
41 files changed, 1213 insertions, 173 deletions
diff --git a/Documentation/ABI/stable/sysfs-driver-w1_ds28e04 b/Documentation/ABI/stable/sysfs-driver-w1_ds28e04 new file mode 100644 index 000000000000..26579ee868c9 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-driver-w1_ds28e04 | |||
@@ -0,0 +1,15 @@ | |||
1 | What: /sys/bus/w1/devices/.../pio | ||
2 | Date: May 2012 | ||
3 | Contact: Markus Franke <franm@hrz.tu-chemnitz.de> | ||
4 | Description: read/write the contents of the two PIO's of the DS28E04-100 | ||
5 | see Documentation/w1/slaves/w1_ds28e04 for detailed information | ||
6 | Users: any user space application which wants to communicate with DS28E04-100 | ||
7 | |||
8 | |||
9 | |||
10 | What: /sys/bus/w1/devices/.../eeprom | ||
11 | Date: May 2012 | ||
12 | Contact: Markus Franke <franm@hrz.tu-chemnitz.de> | ||
13 | Description: read/write the contents of the EEPROM memory of the DS28E04-100 | ||
14 | see Documentation/w1/slaves/w1_ds28e04 for detailed information | ||
15 | Users: any user space application which wants to communicate with DS28E04-100 | ||
diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt index 4a7b54bd37e8..b0714d8f678a 100644 --- a/Documentation/stable_kernel_rules.txt +++ b/Documentation/stable_kernel_rules.txt | |||
@@ -1,4 +1,4 @@ | |||
1 | Everything you ever wanted to know about Linux 2.6 -stable releases. | 1 | Everything you ever wanted to know about Linux -stable releases. |
2 | 2 | ||
3 | Rules on what kind of patches are accepted, and which ones are not, into the | 3 | Rules on what kind of patches are accepted, and which ones are not, into the |
4 | "-stable" tree: | 4 | "-stable" tree: |
@@ -42,10 +42,10 @@ Procedure for submitting patches to the -stable tree: | |||
42 | cherry-picked than this can be specified in the following format in | 42 | cherry-picked than this can be specified in the following format in |
43 | the sign-off area: | 43 | the sign-off area: |
44 | 44 | ||
45 | Cc: <stable@vger.kernel.org> # .32.x: a1f84a3: sched: Check for idle | 45 | Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle |
46 | Cc: <stable@vger.kernel.org> # .32.x: 1b9508f: sched: Rate-limit newidle | 46 | Cc: <stable@vger.kernel.org> # 3.3.x: 1b9508f: sched: Rate-limit newidle |
47 | Cc: <stable@vger.kernel.org> # .32.x: fd21073: sched: Fix affinity logic | 47 | Cc: <stable@vger.kernel.org> # 3.3.x: fd21073: sched: Fix affinity logic |
48 | Cc: <stable@vger.kernel.org> # .32.x | 48 | Cc: <stable@vger.kernel.org> # 3.3.x |
49 | Signed-off-by: Ingo Molnar <mingo@elte.hu> | 49 | Signed-off-by: Ingo Molnar <mingo@elte.hu> |
50 | 50 | ||
51 | The tag sequence has the meaning of: | 51 | The tag sequence has the meaning of: |
@@ -79,6 +79,15 @@ Review cycle: | |||
79 | security kernel team, and not go through the normal review cycle. | 79 | security kernel team, and not go through the normal review cycle. |
80 | Contact the kernel security team for more details on this procedure. | 80 | Contact the kernel security team for more details on this procedure. |
81 | 81 | ||
82 | Trees: | ||
83 | |||
84 | - The queues of patches, for both completed versions and in progress | ||
85 | versions can be found at: | ||
86 | http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git | ||
87 | - The finalized and tagged releases of all stable kernels can be found | ||
88 | in separate branches per version at: | ||
89 | http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git | ||
90 | |||
82 | 91 | ||
83 | Review committee: | 92 | Review committee: |
84 | 93 | ||
diff --git a/Documentation/w1/slaves/w1_ds28e04 b/Documentation/w1/slaves/w1_ds28e04 new file mode 100644 index 000000000000..85bc9a7e02fe --- /dev/null +++ b/Documentation/w1/slaves/w1_ds28e04 | |||
@@ -0,0 +1,36 @@ | |||
1 | Kernel driver w1_ds28e04 | ||
2 | ======================== | ||
3 | |||
4 | Supported chips: | ||
5 | * Maxim DS28E04-100 4096-Bit Addressable 1-Wire EEPROM with PIO | ||
6 | |||
7 | supported family codes: | ||
8 | W1_FAMILY_DS28E04 0x1C | ||
9 | |||
10 | Author: Markus Franke, <franke.m@sebakmt.com> <franm@hrz.tu-chemnitz.de> | ||
11 | |||
12 | Description | ||
13 | ----------- | ||
14 | |||
15 | Support is provided through the sysfs files "eeprom" and "pio". CRC checking | ||
16 | during memory accesses can optionally be enabled/disabled via the device | ||
17 | attribute "crccheck". The strong pull-up can optionally be enabled/disabled | ||
18 | via the module parameter "w1_strong_pullup". | ||
19 | |||
20 | Memory Access | ||
21 | |||
22 | A read operation on the "eeprom" file reads the given amount of bytes | ||
23 | from the EEPROM of the DS28E04. | ||
24 | |||
25 | A write operation on the "eeprom" file writes the given byte sequence | ||
26 | to the EEPROM of the DS28E04. If CRC checking mode is enabled only | ||
27 | fully alligned blocks of 32 bytes with valid CRC16 values (in bytes 30 | ||
28 | and 31) are allowed to be written. | ||
29 | |||
30 | PIO Access | ||
31 | |||
32 | The 2 PIOs of the DS28E04-100 are accessible via the "pio" sysfs file. | ||
33 | |||
34 | The current status of the PIO's is returned as an 8 bit value. Bit 0/1 | ||
35 | represent the state of PIO_0/PIO_1. Bits 2..7 do not care. The PIO's are | ||
36 | driven low-active, i.e. the driver delivers/expects low-active values. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 1b71f6ceae0a..63ccf7edec3d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2709,6 +2709,14 @@ M: Mimi Zohar <zohar@us.ibm.com> | |||
2709 | S: Supported | 2709 | S: Supported |
2710 | F: security/integrity/evm/ | 2710 | F: security/integrity/evm/ |
2711 | 2711 | ||
2712 | EXTERNAL CONNECTOR SUBSYSTEM (EXTCON) | ||
2713 | M: MyungJoo Ham <myungjoo.ham@samsung.com> | ||
2714 | M: Chanwoo Choi <cw00.choi@samsung.com> | ||
2715 | L: linux-kernel@vger.kernel.org | ||
2716 | S: Maintained | ||
2717 | F: drivers/extcon/ | ||
2718 | F: Documentation/extcon/ | ||
2719 | |||
2712 | EXYNOS DP DRIVER | 2720 | EXYNOS DP DRIVER |
2713 | M: Jingoo Han <jg1.han@samsung.com> | 2721 | M: Jingoo Han <jg1.han@samsung.com> |
2714 | L: linux-fbdev@vger.kernel.org | 2722 | L: linux-fbdev@vger.kernel.org |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 2bcef657a60c..181ed2660b33 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -743,7 +743,6 @@ int bus_add_driver(struct device_driver *drv) | |||
743 | } | 743 | } |
744 | } | 744 | } |
745 | 745 | ||
746 | kobject_uevent(&priv->kobj, KOBJ_ADD); | ||
747 | return 0; | 746 | return 0; |
748 | 747 | ||
749 | out_unregister: | 748 | out_unregister: |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 346be8b78b24..f338037a4f3d 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -85,14 +85,13 @@ const char *dev_driver_string(const struct device *dev) | |||
85 | } | 85 | } |
86 | EXPORT_SYMBOL(dev_driver_string); | 86 | EXPORT_SYMBOL(dev_driver_string); |
87 | 87 | ||
88 | #define to_dev(obj) container_of(obj, struct device, kobj) | ||
89 | #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) | 88 | #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) |
90 | 89 | ||
91 | static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, | 90 | static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, |
92 | char *buf) | 91 | char *buf) |
93 | { | 92 | { |
94 | struct device_attribute *dev_attr = to_dev_attr(attr); | 93 | struct device_attribute *dev_attr = to_dev_attr(attr); |
95 | struct device *dev = to_dev(kobj); | 94 | struct device *dev = kobj_to_dev(kobj); |
96 | ssize_t ret = -EIO; | 95 | ssize_t ret = -EIO; |
97 | 96 | ||
98 | if (dev_attr->show) | 97 | if (dev_attr->show) |
@@ -108,7 +107,7 @@ static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, | |||
108 | const char *buf, size_t count) | 107 | const char *buf, size_t count) |
109 | { | 108 | { |
110 | struct device_attribute *dev_attr = to_dev_attr(attr); | 109 | struct device_attribute *dev_attr = to_dev_attr(attr); |
111 | struct device *dev = to_dev(kobj); | 110 | struct device *dev = kobj_to_dev(kobj); |
112 | ssize_t ret = -EIO; | 111 | ssize_t ret = -EIO; |
113 | 112 | ||
114 | if (dev_attr->store) | 113 | if (dev_attr->store) |
@@ -182,7 +181,7 @@ EXPORT_SYMBOL_GPL(device_show_int); | |||
182 | */ | 181 | */ |
183 | static void device_release(struct kobject *kobj) | 182 | static void device_release(struct kobject *kobj) |
184 | { | 183 | { |
185 | struct device *dev = to_dev(kobj); | 184 | struct device *dev = kobj_to_dev(kobj); |
186 | struct device_private *p = dev->p; | 185 | struct device_private *p = dev->p; |
187 | 186 | ||
188 | if (dev->release) | 187 | if (dev->release) |
@@ -200,7 +199,7 @@ static void device_release(struct kobject *kobj) | |||
200 | 199 | ||
201 | static const void *device_namespace(struct kobject *kobj) | 200 | static const void *device_namespace(struct kobject *kobj) |
202 | { | 201 | { |
203 | struct device *dev = to_dev(kobj); | 202 | struct device *dev = kobj_to_dev(kobj); |
204 | const void *ns = NULL; | 203 | const void *ns = NULL; |
205 | 204 | ||
206 | if (dev->class && dev->class->ns_type) | 205 | if (dev->class && dev->class->ns_type) |
@@ -221,7 +220,7 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) | |||
221 | struct kobj_type *ktype = get_ktype(kobj); | 220 | struct kobj_type *ktype = get_ktype(kobj); |
222 | 221 | ||
223 | if (ktype == &device_ktype) { | 222 | if (ktype == &device_ktype) { |
224 | struct device *dev = to_dev(kobj); | 223 | struct device *dev = kobj_to_dev(kobj); |
225 | if (dev->bus) | 224 | if (dev->bus) |
226 | return 1; | 225 | return 1; |
227 | if (dev->class) | 226 | if (dev->class) |
@@ -232,7 +231,7 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) | |||
232 | 231 | ||
233 | static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) | 232 | static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) |
234 | { | 233 | { |
235 | struct device *dev = to_dev(kobj); | 234 | struct device *dev = kobj_to_dev(kobj); |
236 | 235 | ||
237 | if (dev->bus) | 236 | if (dev->bus) |
238 | return dev->bus->name; | 237 | return dev->bus->name; |
@@ -244,7 +243,7 @@ static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) | |||
244 | static int dev_uevent(struct kset *kset, struct kobject *kobj, | 243 | static int dev_uevent(struct kset *kset, struct kobject *kobj, |
245 | struct kobj_uevent_env *env) | 244 | struct kobj_uevent_env *env) |
246 | { | 245 | { |
247 | struct device *dev = to_dev(kobj); | 246 | struct device *dev = kobj_to_dev(kobj); |
248 | int retval = 0; | 247 | int retval = 0; |
249 | 248 | ||
250 | /* add device node properties if present */ | 249 | /* add device node properties if present */ |
@@ -1132,7 +1131,7 @@ int device_register(struct device *dev) | |||
1132 | */ | 1131 | */ |
1133 | struct device *get_device(struct device *dev) | 1132 | struct device *get_device(struct device *dev) |
1134 | { | 1133 | { |
1135 | return dev ? to_dev(kobject_get(&dev->kobj)) : NULL; | 1134 | return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; |
1136 | } | 1135 | } |
1137 | 1136 | ||
1138 | /** | 1137 | /** |
@@ -1754,25 +1753,25 @@ int device_move(struct device *dev, struct device *new_parent, | |||
1754 | set_dev_node(dev, dev_to_node(new_parent)); | 1753 | set_dev_node(dev, dev_to_node(new_parent)); |
1755 | } | 1754 | } |
1756 | 1755 | ||
1757 | if (!dev->class) | 1756 | if (dev->class) { |
1758 | goto out_put; | 1757 | error = device_move_class_links(dev, old_parent, new_parent); |
1759 | error = device_move_class_links(dev, old_parent, new_parent); | 1758 | if (error) { |
1760 | if (error) { | 1759 | /* We ignore errors on cleanup since we're hosed anyway... */ |
1761 | /* We ignore errors on cleanup since we're hosed anyway... */ | 1760 | device_move_class_links(dev, new_parent, old_parent); |
1762 | device_move_class_links(dev, new_parent, old_parent); | 1761 | if (!kobject_move(&dev->kobj, &old_parent->kobj)) { |
1763 | if (!kobject_move(&dev->kobj, &old_parent->kobj)) { | 1762 | if (new_parent) |
1764 | if (new_parent) | 1763 | klist_remove(&dev->p->knode_parent); |
1765 | klist_remove(&dev->p->knode_parent); | 1764 | dev->parent = old_parent; |
1766 | dev->parent = old_parent; | 1765 | if (old_parent) { |
1767 | if (old_parent) { | 1766 | klist_add_tail(&dev->p->knode_parent, |
1768 | klist_add_tail(&dev->p->knode_parent, | 1767 | &old_parent->p->klist_children); |
1769 | &old_parent->p->klist_children); | 1768 | set_dev_node(dev, dev_to_node(old_parent)); |
1770 | set_dev_node(dev, dev_to_node(old_parent)); | 1769 | } |
1771 | } | 1770 | } |
1771 | cleanup_glue_dir(dev, new_parent_kobj); | ||
1772 | put_device(new_parent); | ||
1773 | goto out; | ||
1772 | } | 1774 | } |
1773 | cleanup_glue_dir(dev, new_parent_kobj); | ||
1774 | put_device(new_parent); | ||
1775 | goto out; | ||
1776 | } | 1775 | } |
1777 | switch (dpm_order) { | 1776 | switch (dpm_order) { |
1778 | case DPM_ORDER_NONE: | 1777 | case DPM_ORDER_NONE: |
@@ -1787,7 +1786,7 @@ int device_move(struct device *dev, struct device *new_parent, | |||
1787 | device_pm_move_last(dev); | 1786 | device_pm_move_last(dev); |
1788 | break; | 1787 | break; |
1789 | } | 1788 | } |
1790 | out_put: | 1789 | |
1791 | put_device(old_parent); | 1790 | put_device(old_parent); |
1792 | out: | 1791 | out: |
1793 | device_pm_unlock(); | 1792 | device_pm_unlock(); |
@@ -1812,6 +1811,13 @@ void device_shutdown(void) | |||
1812 | while (!list_empty(&devices_kset->list)) { | 1811 | while (!list_empty(&devices_kset->list)) { |
1813 | dev = list_entry(devices_kset->list.prev, struct device, | 1812 | dev = list_entry(devices_kset->list.prev, struct device, |
1814 | kobj.entry); | 1813 | kobj.entry); |
1814 | |||
1815 | /* | ||
1816 | * hold reference count of device's parent to | ||
1817 | * prevent it from being freed because parent's | ||
1818 | * lock is to be held | ||
1819 | */ | ||
1820 | get_device(dev->parent); | ||
1815 | get_device(dev); | 1821 | get_device(dev); |
1816 | /* | 1822 | /* |
1817 | * Make sure the device is off the kset list, in the | 1823 | * Make sure the device is off the kset list, in the |
@@ -1820,6 +1826,11 @@ void device_shutdown(void) | |||
1820 | list_del_init(&dev->kobj.entry); | 1826 | list_del_init(&dev->kobj.entry); |
1821 | spin_unlock(&devices_kset->list_lock); | 1827 | spin_unlock(&devices_kset->list_lock); |
1822 | 1828 | ||
1829 | /* hold lock to avoid race with probe/release */ | ||
1830 | if (dev->parent) | ||
1831 | device_lock(dev->parent); | ||
1832 | device_lock(dev); | ||
1833 | |||
1823 | /* Don't allow any more runtime suspends */ | 1834 | /* Don't allow any more runtime suspends */ |
1824 | pm_runtime_get_noresume(dev); | 1835 | pm_runtime_get_noresume(dev); |
1825 | pm_runtime_barrier(dev); | 1836 | pm_runtime_barrier(dev); |
@@ -1831,7 +1842,13 @@ void device_shutdown(void) | |||
1831 | dev_dbg(dev, "shutdown\n"); | 1842 | dev_dbg(dev, "shutdown\n"); |
1832 | dev->driver->shutdown(dev); | 1843 | dev->driver->shutdown(dev); |
1833 | } | 1844 | } |
1845 | |||
1846 | device_unlock(dev); | ||
1847 | if (dev->parent) | ||
1848 | device_unlock(dev->parent); | ||
1849 | |||
1834 | put_device(dev); | 1850 | put_device(dev); |
1851 | put_device(dev->parent); | ||
1835 | 1852 | ||
1836 | spin_lock(&devices_kset->list_lock); | 1853 | spin_lock(&devices_kset->list_lock); |
1837 | } | 1854 | } |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index dcb8a6e48692..9b0aca479580 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -85,8 +85,20 @@ static void deferred_probe_work_func(struct work_struct *work) | |||
85 | * manipulate the deferred list | 85 | * manipulate the deferred list |
86 | */ | 86 | */ |
87 | mutex_unlock(&deferred_probe_mutex); | 87 | mutex_unlock(&deferred_probe_mutex); |
88 | |||
89 | /* | ||
90 | * Force the device to the end of the dpm_list since | ||
91 | * the PM code assumes that the order we add things to | ||
92 | * the list is a good order for suspend but deferred | ||
93 | * probe makes that very unsafe. | ||
94 | */ | ||
95 | device_pm_lock(); | ||
96 | device_pm_move_last(dev); | ||
97 | device_pm_unlock(); | ||
98 | |||
88 | dev_dbg(dev, "Retrying from deferred list\n"); | 99 | dev_dbg(dev, "Retrying from deferred list\n"); |
89 | bus_probe_device(dev); | 100 | bus_probe_device(dev); |
101 | |||
90 | mutex_lock(&deferred_probe_mutex); | 102 | mutex_lock(&deferred_probe_mutex); |
91 | 103 | ||
92 | put_device(dev); | 104 | put_device(dev); |
@@ -283,6 +295,7 @@ probe_failed: | |||
283 | devres_release_all(dev); | 295 | devres_release_all(dev); |
284 | driver_sysfs_remove(dev); | 296 | driver_sysfs_remove(dev); |
285 | dev->driver = NULL; | 297 | dev->driver = NULL; |
298 | dev_set_drvdata(dev, NULL); | ||
286 | 299 | ||
287 | if (ret == -EPROBE_DEFER) { | 300 | if (ret == -EPROBE_DEFER) { |
288 | /* Driver requested deferred probing */ | 301 | /* Driver requested deferred probing */ |
@@ -487,6 +500,7 @@ static void __device_release_driver(struct device *dev) | |||
487 | drv->remove(dev); | 500 | drv->remove(dev); |
488 | devres_release_all(dev); | 501 | devres_release_all(dev); |
489 | dev->driver = NULL; | 502 | dev->driver = NULL; |
503 | dev_set_drvdata(dev, NULL); | ||
490 | klist_remove(&dev->p->knode_driver); | 504 | klist_remove(&dev->p->knode_driver); |
491 | if (dev->bus) | 505 | if (dev->bus) |
492 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, | 506 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 24e88fe29ec1..c30f3e1d0efc 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c | |||
@@ -493,6 +493,7 @@ EXPORT_SYMBOL_GPL(dma_buf_vmap); | |||
493 | /** | 493 | /** |
494 | * dma_buf_vunmap - Unmap a vmap obtained by dma_buf_vmap. | 494 | * dma_buf_vunmap - Unmap a vmap obtained by dma_buf_vmap. |
495 | * @dmabuf: [in] buffer to vunmap | 495 | * @dmabuf: [in] buffer to vunmap |
496 | * @vaddr: [in] vmap to vunmap | ||
496 | */ | 497 | */ |
497 | void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) | 498 | void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) |
498 | { | 499 | { |
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c index 1b85949e3d2f..560a7173f810 100644 --- a/drivers/base/dma-coherent.c +++ b/drivers/base/dma-coherent.c | |||
@@ -186,6 +186,7 @@ EXPORT_SYMBOL(dma_release_from_coherent); | |||
186 | * @vma: vm_area for the userspace memory | 186 | * @vma: vm_area for the userspace memory |
187 | * @vaddr: cpu address returned by dma_alloc_from_coherent | 187 | * @vaddr: cpu address returned by dma_alloc_from_coherent |
188 | * @size: size of the memory buffer allocated by dma_alloc_from_coherent | 188 | * @size: size of the memory buffer allocated by dma_alloc_from_coherent |
189 | * @ret: result from remap_pfn_range() | ||
189 | * | 190 | * |
190 | * This checks whether the memory was allocated from the per-device | 191 | * This checks whether the memory was allocated from the per-device |
191 | * coherent memory pool and if so, maps that memory to the provided vma. | 192 | * coherent memory pool and if so, maps that memory to the provided vma. |
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 207c27ddf828..1b500d6fcc2e 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -187,6 +187,9 @@ int driver_register(struct device_driver *drv) | |||
187 | ret = driver_add_groups(drv, drv->groups); | 187 | ret = driver_add_groups(drv, drv->groups); |
188 | if (ret) | 188 | if (ret) |
189 | bus_remove_driver(drv); | 189 | bus_remove_driver(drv); |
190 | |||
191 | kobject_uevent(&drv->p->kobj, KOBJ_ADD); | ||
192 | |||
190 | return ret; | 193 | return ret; |
191 | } | 194 | } |
192 | EXPORT_SYMBOL_GPL(driver_register); | 195 | EXPORT_SYMBOL_GPL(driver_register); |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 5401814c874d..803cfc1597a9 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -22,8 +22,6 @@ | |||
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
24 | 24 | ||
25 | #define to_dev(obj) container_of(obj, struct device, kobj) | ||
26 | |||
27 | MODULE_AUTHOR("Manuel Estrada Sainz"); | 25 | MODULE_AUTHOR("Manuel Estrada Sainz"); |
28 | MODULE_DESCRIPTION("Multi purpose firmware loading support"); | 26 | MODULE_DESCRIPTION("Multi purpose firmware loading support"); |
29 | MODULE_LICENSE("GPL"); | 27 | MODULE_LICENSE("GPL"); |
@@ -290,7 +288,7 @@ static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj, | |||
290 | struct bin_attribute *bin_attr, | 288 | struct bin_attribute *bin_attr, |
291 | char *buffer, loff_t offset, size_t count) | 289 | char *buffer, loff_t offset, size_t count) |
292 | { | 290 | { |
293 | struct device *dev = to_dev(kobj); | 291 | struct device *dev = kobj_to_dev(kobj); |
294 | struct firmware_priv *fw_priv = to_firmware_priv(dev); | 292 | struct firmware_priv *fw_priv = to_firmware_priv(dev); |
295 | struct firmware *fw; | 293 | struct firmware *fw; |
296 | ssize_t ret_count; | 294 | ssize_t ret_count; |
@@ -384,7 +382,7 @@ static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, | |||
384 | struct bin_attribute *bin_attr, | 382 | struct bin_attribute *bin_attr, |
385 | char *buffer, loff_t offset, size_t count) | 383 | char *buffer, loff_t offset, size_t count) |
386 | { | 384 | { |
387 | struct device *dev = to_dev(kobj); | 385 | struct device *dev = kobj_to_dev(kobj); |
388 | struct firmware_priv *fw_priv = to_firmware_priv(dev); | 386 | struct firmware_priv *fw_priv = to_firmware_priv(dev); |
389 | struct firmware *fw; | 387 | struct firmware *fw; |
390 | ssize_t retval; | 388 | ssize_t retval; |
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index 29c5cf852efc..bb385ac629a8 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig | |||
@@ -29,4 +29,12 @@ config EXTCON_MAX8997 | |||
29 | Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory | 29 | Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory |
30 | detector and switch. | 30 | detector and switch. |
31 | 31 | ||
32 | config EXTCON_ARIZONA | ||
33 | tristate "Wolfson Arizona EXTCON support" | ||
34 | depends on MFD_ARIZONA | ||
35 | help | ||
36 | Say Y here to enable support for external accessory detection | ||
37 | with Wolfson Arizona devices. These are audio CODECs with | ||
38 | advanced audio accessory detection support. | ||
39 | |||
32 | endif # MULTISTATE_SWITCH | 40 | endif # MULTISTATE_SWITCH |
diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile index 86020bdb6da0..e932caaa311c 100644 --- a/drivers/extcon/Makefile +++ b/drivers/extcon/Makefile | |||
@@ -5,3 +5,4 @@ | |||
5 | obj-$(CONFIG_EXTCON) += extcon_class.o | 5 | obj-$(CONFIG_EXTCON) += extcon_class.o |
6 | obj-$(CONFIG_EXTCON_GPIO) += extcon_gpio.o | 6 | obj-$(CONFIG_EXTCON_GPIO) += extcon_gpio.o |
7 | obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o | 7 | obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o |
8 | obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o | ||
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c new file mode 100644 index 000000000000..b068bc9defe1 --- /dev/null +++ b/drivers/extcon/extcon-arizona.c | |||
@@ -0,0 +1,491 @@ | |||
1 | /* | ||
2 | * extcon-arizona.c - Extcon driver Wolfson Arizona devices | ||
3 | * | ||
4 | * Copyright (C) 2012 Wolfson Microelectronics plc | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/gpio.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/pm_runtime.h> | ||
26 | #include <linux/regulator/consumer.h> | ||
27 | #include <linux/extcon.h> | ||
28 | |||
29 | #include <linux/mfd/arizona/core.h> | ||
30 | #include <linux/mfd/arizona/pdata.h> | ||
31 | #include <linux/mfd/arizona/registers.h> | ||
32 | |||
33 | struct arizona_extcon_info { | ||
34 | struct device *dev; | ||
35 | struct arizona *arizona; | ||
36 | struct mutex lock; | ||
37 | struct regulator *micvdd; | ||
38 | |||
39 | int micd_mode; | ||
40 | const struct arizona_micd_config *micd_modes; | ||
41 | int micd_num_modes; | ||
42 | |||
43 | bool micd_reva; | ||
44 | |||
45 | bool mic; | ||
46 | bool detecting; | ||
47 | int jack_flips; | ||
48 | |||
49 | struct extcon_dev edev; | ||
50 | }; | ||
51 | |||
52 | static const struct arizona_micd_config micd_default_modes[] = { | ||
53 | { ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 }, | ||
54 | { 0, 2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 }, | ||
55 | }; | ||
56 | |||
57 | #define ARIZONA_CABLE_MECHANICAL "Mechanical" | ||
58 | #define ARIZONA_CABLE_HEADPHONE "Headphone" | ||
59 | #define ARIZONA_CABLE_HEADSET "Headset" | ||
60 | |||
61 | static const char *arizona_cable[] = { | ||
62 | ARIZONA_CABLE_MECHANICAL, | ||
63 | ARIZONA_CABLE_HEADSET, | ||
64 | ARIZONA_CABLE_HEADPHONE, | ||
65 | NULL, | ||
66 | }; | ||
67 | |||
68 | static const u32 arizona_exclusions[] = { | ||
69 | 0x6, /* Headphone and headset */ | ||
70 | 0, | ||
71 | }; | ||
72 | |||
73 | static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode) | ||
74 | { | ||
75 | struct arizona *arizona = info->arizona; | ||
76 | |||
77 | gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio, | ||
78 | info->micd_modes[mode].gpio); | ||
79 | regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, | ||
80 | ARIZONA_MICD_BIAS_SRC_MASK, | ||
81 | info->micd_modes[mode].bias); | ||
82 | regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1, | ||
83 | ARIZONA_ACCDET_SRC, info->micd_modes[mode].src); | ||
84 | |||
85 | info->micd_mode = mode; | ||
86 | |||
87 | dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode); | ||
88 | } | ||
89 | |||
90 | static void arizona_start_mic(struct arizona_extcon_info *info) | ||
91 | { | ||
92 | struct arizona *arizona = info->arizona; | ||
93 | bool change; | ||
94 | int ret; | ||
95 | |||
96 | info->detecting = true; | ||
97 | info->mic = false; | ||
98 | info->jack_flips = 0; | ||
99 | |||
100 | /* Microphone detection can't use idle mode */ | ||
101 | pm_runtime_get(info->dev); | ||
102 | |||
103 | ret = regulator_enable(info->micvdd); | ||
104 | if (ret != 0) { | ||
105 | dev_err(arizona->dev, "Failed to enable MICVDD: %d\n", | ||
106 | ret); | ||
107 | } | ||
108 | |||
109 | if (info->micd_reva) { | ||
110 | regmap_write(arizona->regmap, 0x80, 0x3); | ||
111 | regmap_write(arizona->regmap, 0x294, 0); | ||
112 | regmap_write(arizona->regmap, 0x80, 0x0); | ||
113 | } | ||
114 | |||
115 | regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, | ||
116 | ARIZONA_MICD_ENA, ARIZONA_MICD_ENA, | ||
117 | &change); | ||
118 | if (!change) { | ||
119 | regulator_disable(info->micvdd); | ||
120 | pm_runtime_put_autosuspend(info->dev); | ||
121 | } | ||
122 | } | ||
123 | |||
124 | static void arizona_stop_mic(struct arizona_extcon_info *info) | ||
125 | { | ||
126 | struct arizona *arizona = info->arizona; | ||
127 | bool change; | ||
128 | |||
129 | regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, | ||
130 | ARIZONA_MICD_ENA, 0, | ||
131 | &change); | ||
132 | |||
133 | if (info->micd_reva) { | ||
134 | regmap_write(arizona->regmap, 0x80, 0x3); | ||
135 | regmap_write(arizona->regmap, 0x294, 2); | ||
136 | regmap_write(arizona->regmap, 0x80, 0x0); | ||
137 | } | ||
138 | |||
139 | if (change) { | ||
140 | regulator_disable(info->micvdd); | ||
141 | pm_runtime_put_autosuspend(info->dev); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | static irqreturn_t arizona_micdet(int irq, void *data) | ||
146 | { | ||
147 | struct arizona_extcon_info *info = data; | ||
148 | struct arizona *arizona = info->arizona; | ||
149 | unsigned int val; | ||
150 | int ret; | ||
151 | |||
152 | mutex_lock(&info->lock); | ||
153 | |||
154 | ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); | ||
155 | if (ret != 0) { | ||
156 | dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); | ||
157 | return IRQ_NONE; | ||
158 | } | ||
159 | |||
160 | dev_dbg(arizona->dev, "MICDET: %x\n", val); | ||
161 | |||
162 | if (!(val & ARIZONA_MICD_VALID)) { | ||
163 | dev_warn(arizona->dev, "Microphone detection state invalid\n"); | ||
164 | mutex_unlock(&info->lock); | ||
165 | return IRQ_NONE; | ||
166 | } | ||
167 | |||
168 | /* Due to jack detect this should never happen */ | ||
169 | if (!(val & ARIZONA_MICD_STS)) { | ||
170 | dev_warn(arizona->dev, "Detected open circuit\n"); | ||
171 | info->detecting = false; | ||
172 | goto handled; | ||
173 | } | ||
174 | |||
175 | /* If we got a high impedence we should have a headset, report it. */ | ||
176 | if (info->detecting && (val & 0x400)) { | ||
177 | ret = extcon_set_cable_state(&info->edev, | ||
178 | ARIZONA_CABLE_HEADSET, true); | ||
179 | |||
180 | if (ret != 0) | ||
181 | dev_err(arizona->dev, "Headset report failed: %d\n", | ||
182 | ret); | ||
183 | |||
184 | info->mic = true; | ||
185 | info->detecting = false; | ||
186 | goto handled; | ||
187 | } | ||
188 | |||
189 | /* If we detected a lower impedence during initial startup | ||
190 | * then we probably have the wrong polarity, flip it. Don't | ||
191 | * do this for the lowest impedences to speed up detection of | ||
192 | * plain headphones. If both polarities report a low | ||
193 | * impedence then give up and report headphones. | ||
194 | */ | ||
195 | if (info->detecting && (val & 0x3f8)) { | ||
196 | info->jack_flips++; | ||
197 | |||
198 | if (info->jack_flips >= info->micd_num_modes) { | ||
199 | dev_dbg(arizona->dev, "Detected headphone\n"); | ||
200 | info->detecting = false; | ||
201 | ret = extcon_set_cable_state(&info->edev, | ||
202 | ARIZONA_CABLE_HEADPHONE, | ||
203 | true); | ||
204 | if (ret != 0) | ||
205 | dev_err(arizona->dev, | ||
206 | "Headphone report failed: %d\n", | ||
207 | ret); | ||
208 | } else { | ||
209 | info->micd_mode++; | ||
210 | if (info->micd_mode == info->micd_num_modes) | ||
211 | info->micd_mode = 0; | ||
212 | arizona_extcon_set_mode(info, info->micd_mode); | ||
213 | |||
214 | info->jack_flips++; | ||
215 | } | ||
216 | |||
217 | goto handled; | ||
218 | } | ||
219 | |||
220 | /* | ||
221 | * If we're still detecting and we detect a short then we've | ||
222 | * got a headphone. Otherwise it's a button press, the | ||
223 | * button reporting is stubbed out for now. | ||
224 | */ | ||
225 | if (val & 0x3fc) { | ||
226 | if (info->mic) { | ||
227 | dev_dbg(arizona->dev, "Mic button detected\n"); | ||
228 | |||
229 | } else if (info->detecting) { | ||
230 | dev_dbg(arizona->dev, "Headphone detected\n"); | ||
231 | info->detecting = false; | ||
232 | arizona_stop_mic(info); | ||
233 | |||
234 | ret = extcon_set_cable_state(&info->edev, | ||
235 | ARIZONA_CABLE_HEADPHONE, | ||
236 | true); | ||
237 | if (ret != 0) | ||
238 | dev_err(arizona->dev, | ||
239 | "Headphone report failed: %d\n", | ||
240 | ret); | ||
241 | } else { | ||
242 | dev_warn(arizona->dev, "Button with no mic: %x\n", | ||
243 | val); | ||
244 | } | ||
245 | } else { | ||
246 | dev_dbg(arizona->dev, "Mic button released\n"); | ||
247 | } | ||
248 | |||
249 | handled: | ||
250 | pm_runtime_mark_last_busy(info->dev); | ||
251 | mutex_unlock(&info->lock); | ||
252 | |||
253 | return IRQ_HANDLED; | ||
254 | } | ||
255 | |||
256 | static irqreturn_t arizona_jackdet(int irq, void *data) | ||
257 | { | ||
258 | struct arizona_extcon_info *info = data; | ||
259 | struct arizona *arizona = info->arizona; | ||
260 | unsigned int val; | ||
261 | int ret; | ||
262 | |||
263 | pm_runtime_get_sync(info->dev); | ||
264 | |||
265 | mutex_lock(&info->lock); | ||
266 | |||
267 | ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val); | ||
268 | if (ret != 0) { | ||
269 | dev_err(arizona->dev, "Failed to read jackdet status: %d\n", | ||
270 | ret); | ||
271 | mutex_unlock(&info->lock); | ||
272 | pm_runtime_put_autosuspend(info->dev); | ||
273 | return IRQ_NONE; | ||
274 | } | ||
275 | |||
276 | if (val & ARIZONA_JD1_STS) { | ||
277 | dev_dbg(arizona->dev, "Detected jack\n"); | ||
278 | ret = extcon_set_cable_state(&info->edev, | ||
279 | ARIZONA_CABLE_MECHANICAL, true); | ||
280 | |||
281 | if (ret != 0) | ||
282 | dev_err(arizona->dev, "Mechanical report failed: %d\n", | ||
283 | ret); | ||
284 | |||
285 | arizona_start_mic(info); | ||
286 | } else { | ||
287 | dev_dbg(arizona->dev, "Detected jack removal\n"); | ||
288 | |||
289 | arizona_stop_mic(info); | ||
290 | |||
291 | ret = extcon_update_state(&info->edev, 0xffffffff, 0); | ||
292 | if (ret != 0) | ||
293 | dev_err(arizona->dev, "Removal report failed: %d\n", | ||
294 | ret); | ||
295 | } | ||
296 | |||
297 | mutex_unlock(&info->lock); | ||
298 | |||
299 | pm_runtime_mark_last_busy(info->dev); | ||
300 | pm_runtime_put_autosuspend(info->dev); | ||
301 | |||
302 | return IRQ_HANDLED; | ||
303 | } | ||
304 | |||
305 | static int __devinit arizona_extcon_probe(struct platform_device *pdev) | ||
306 | { | ||
307 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); | ||
308 | struct arizona_pdata *pdata; | ||
309 | struct arizona_extcon_info *info; | ||
310 | int ret, mode; | ||
311 | |||
312 | pdata = dev_get_platdata(arizona->dev); | ||
313 | |||
314 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | ||
315 | if (!info) { | ||
316 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
317 | ret = -ENOMEM; | ||
318 | goto err; | ||
319 | } | ||
320 | |||
321 | info->micvdd = devm_regulator_get(arizona->dev, "MICVDD"); | ||
322 | if (IS_ERR(info->micvdd)) { | ||
323 | ret = PTR_ERR(info->micvdd); | ||
324 | dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret); | ||
325 | goto err; | ||
326 | } | ||
327 | |||
328 | mutex_init(&info->lock); | ||
329 | info->arizona = arizona; | ||
330 | info->dev = &pdev->dev; | ||
331 | info->detecting = true; | ||
332 | platform_set_drvdata(pdev, info); | ||
333 | |||
334 | switch (arizona->type) { | ||
335 | case WM5102: | ||
336 | switch (arizona->rev) { | ||
337 | case 0: | ||
338 | info->micd_reva = true; | ||
339 | break; | ||
340 | default: | ||
341 | break; | ||
342 | } | ||
343 | break; | ||
344 | default: | ||
345 | break; | ||
346 | } | ||
347 | |||
348 | info->edev.name = "Headset Jack"; | ||
349 | info->edev.supported_cable = arizona_cable; | ||
350 | info->edev.mutually_exclusive = arizona_exclusions; | ||
351 | |||
352 | ret = extcon_dev_register(&info->edev, arizona->dev); | ||
353 | if (ret < 0) { | ||
354 | dev_err(arizona->dev, "extcon_dev_regster() failed: %d\n", | ||
355 | ret); | ||
356 | goto err; | ||
357 | } | ||
358 | |||
359 | if (pdata->num_micd_configs) { | ||
360 | info->micd_modes = pdata->micd_configs; | ||
361 | info->micd_num_modes = pdata->num_micd_configs; | ||
362 | } else { | ||
363 | info->micd_modes = micd_default_modes; | ||
364 | info->micd_num_modes = ARRAY_SIZE(micd_default_modes); | ||
365 | } | ||
366 | |||
367 | if (arizona->pdata.micd_pol_gpio > 0) { | ||
368 | if (info->micd_modes[0].gpio) | ||
369 | mode = GPIOF_OUT_INIT_HIGH; | ||
370 | else | ||
371 | mode = GPIOF_OUT_INIT_LOW; | ||
372 | |||
373 | ret = devm_gpio_request_one(&pdev->dev, | ||
374 | arizona->pdata.micd_pol_gpio, | ||
375 | mode, | ||
376 | "MICD polarity"); | ||
377 | if (ret != 0) { | ||
378 | dev_err(arizona->dev, "Failed to request GPIO%d: %d\n", | ||
379 | arizona->pdata.micd_pol_gpio, ret); | ||
380 | goto err_register; | ||
381 | } | ||
382 | } | ||
383 | |||
384 | arizona_extcon_set_mode(info, 0); | ||
385 | |||
386 | pm_runtime_enable(&pdev->dev); | ||
387 | pm_runtime_idle(&pdev->dev); | ||
388 | pm_runtime_get_sync(&pdev->dev); | ||
389 | |||
390 | ret = arizona_request_irq(arizona, ARIZONA_IRQ_JD_RISE, | ||
391 | "JACKDET rise", arizona_jackdet, info); | ||
392 | if (ret != 0) { | ||
393 | dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n", | ||
394 | ret); | ||
395 | goto err_register; | ||
396 | } | ||
397 | |||
398 | ret = arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 1); | ||
399 | if (ret != 0) { | ||
400 | dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n", | ||
401 | ret); | ||
402 | goto err_rise; | ||
403 | } | ||
404 | |||
405 | ret = arizona_request_irq(arizona, ARIZONA_IRQ_JD_FALL, | ||
406 | "JACKDET fall", arizona_jackdet, info); | ||
407 | if (ret != 0) { | ||
408 | dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret); | ||
409 | goto err_rise_wake; | ||
410 | } | ||
411 | |||
412 | ret = arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 1); | ||
413 | if (ret != 0) { | ||
414 | dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n", | ||
415 | ret); | ||
416 | goto err_fall; | ||
417 | } | ||
418 | |||
419 | ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET, | ||
420 | "MICDET", arizona_micdet, info); | ||
421 | if (ret != 0) { | ||
422 | dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret); | ||
423 | goto err_fall_wake; | ||
424 | } | ||
425 | |||
426 | regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, | ||
427 | ARIZONA_MICD_BIAS_STARTTIME_MASK | | ||
428 | ARIZONA_MICD_RATE_MASK, | ||
429 | 7 << ARIZONA_MICD_BIAS_STARTTIME_SHIFT | | ||
430 | 8 << ARIZONA_MICD_RATE_SHIFT); | ||
431 | |||
432 | arizona_clk32k_enable(arizona); | ||
433 | regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE, | ||
434 | ARIZONA_JD1_DB, ARIZONA_JD1_DB); | ||
435 | regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, | ||
436 | ARIZONA_JD1_ENA, ARIZONA_JD1_ENA); | ||
437 | |||
438 | pm_runtime_put(&pdev->dev); | ||
439 | |||
440 | return 0; | ||
441 | |||
442 | err_fall_wake: | ||
443 | arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 0); | ||
444 | err_fall: | ||
445 | arizona_free_irq(arizona, ARIZONA_IRQ_JD_FALL, info); | ||
446 | err_rise_wake: | ||
447 | arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 0); | ||
448 | err_rise: | ||
449 | arizona_free_irq(arizona, ARIZONA_IRQ_JD_RISE, info); | ||
450 | err_register: | ||
451 | pm_runtime_disable(&pdev->dev); | ||
452 | extcon_dev_unregister(&info->edev); | ||
453 | err: | ||
454 | return ret; | ||
455 | } | ||
456 | |||
457 | static int __devexit arizona_extcon_remove(struct platform_device *pdev) | ||
458 | { | ||
459 | struct arizona_extcon_info *info = platform_get_drvdata(pdev); | ||
460 | struct arizona *arizona = info->arizona; | ||
461 | |||
462 | pm_runtime_disable(&pdev->dev); | ||
463 | |||
464 | arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 0); | ||
465 | arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 0); | ||
466 | arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info); | ||
467 | arizona_free_irq(arizona, ARIZONA_IRQ_JD_RISE, info); | ||
468 | arizona_free_irq(arizona, ARIZONA_IRQ_JD_FALL, info); | ||
469 | regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, | ||
470 | ARIZONA_JD1_ENA, 0); | ||
471 | arizona_clk32k_disable(arizona); | ||
472 | extcon_dev_unregister(&info->edev); | ||
473 | |||
474 | return 0; | ||
475 | } | ||
476 | |||
477 | static struct platform_driver arizona_extcon_driver = { | ||
478 | .driver = { | ||
479 | .name = "arizona-extcon", | ||
480 | .owner = THIS_MODULE, | ||
481 | }, | ||
482 | .probe = arizona_extcon_probe, | ||
483 | .remove = __devexit_p(arizona_extcon_remove), | ||
484 | }; | ||
485 | |||
486 | module_platform_driver(arizona_extcon_driver); | ||
487 | |||
488 | MODULE_DESCRIPTION("Arizona Extcon driver"); | ||
489 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
490 | MODULE_LICENSE("GPL"); | ||
491 | MODULE_ALIAS("platform:extcon-arizona"); | ||
diff --git a/drivers/extcon/extcon_class.c b/drivers/extcon/extcon_class.c index 159aeb07b3ba..f6419f9db76c 100644 --- a/drivers/extcon/extcon_class.c +++ b/drivers/extcon/extcon_class.c | |||
@@ -65,7 +65,7 @@ const char *extcon_cable_name[] = { | |||
65 | NULL, | 65 | NULL, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | struct class *extcon_class; | 68 | static struct class *extcon_class; |
69 | #if defined(CONFIG_ANDROID) | 69 | #if defined(CONFIG_ANDROID) |
70 | static struct class_compat *switch_class; | 70 | static struct class_compat *switch_class; |
71 | #endif /* CONFIG_ANDROID */ | 71 | #endif /* CONFIG_ANDROID */ |
diff --git a/drivers/extcon/extcon_gpio.c b/drivers/extcon/extcon_gpio.c index 8a0dcc11c7c7..fe3db45fa83c 100644 --- a/drivers/extcon/extcon_gpio.c +++ b/drivers/extcon/extcon_gpio.c | |||
@@ -105,25 +105,25 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev) | |||
105 | 105 | ||
106 | ret = extcon_dev_register(&extcon_data->edev, &pdev->dev); | 106 | ret = extcon_dev_register(&extcon_data->edev, &pdev->dev); |
107 | if (ret < 0) | 107 | if (ret < 0) |
108 | goto err_extcon_dev_register; | 108 | return ret; |
109 | 109 | ||
110 | ret = gpio_request_one(extcon_data->gpio, GPIOF_DIR_IN, pdev->name); | 110 | ret = gpio_request_one(extcon_data->gpio, GPIOF_DIR_IN, pdev->name); |
111 | if (ret < 0) | 111 | if (ret < 0) |
112 | goto err_request_gpio; | 112 | goto err; |
113 | 113 | ||
114 | INIT_DELAYED_WORK(&extcon_data->work, gpio_extcon_work); | 114 | INIT_DELAYED_WORK(&extcon_data->work, gpio_extcon_work); |
115 | 115 | ||
116 | extcon_data->irq = gpio_to_irq(extcon_data->gpio); | 116 | extcon_data->irq = gpio_to_irq(extcon_data->gpio); |
117 | if (extcon_data->irq < 0) { | 117 | if (extcon_data->irq < 0) { |
118 | ret = extcon_data->irq; | 118 | ret = extcon_data->irq; |
119 | goto err_detect_irq_num_failed; | 119 | goto err; |
120 | } | 120 | } |
121 | 121 | ||
122 | ret = request_any_context_irq(extcon_data->irq, gpio_irq_handler, | 122 | ret = request_any_context_irq(extcon_data->irq, gpio_irq_handler, |
123 | pdata->irq_flags, pdev->name, | 123 | pdata->irq_flags, pdev->name, |
124 | extcon_data); | 124 | extcon_data); |
125 | if (ret < 0) | 125 | if (ret < 0) |
126 | goto err_request_irq; | 126 | goto err; |
127 | 127 | ||
128 | platform_set_drvdata(pdev, extcon_data); | 128 | platform_set_drvdata(pdev, extcon_data); |
129 | /* Perform initial detection */ | 129 | /* Perform initial detection */ |
@@ -131,13 +131,8 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev) | |||
131 | 131 | ||
132 | return 0; | 132 | return 0; |
133 | 133 | ||
134 | err_request_irq: | 134 | err: |
135 | err_detect_irq_num_failed: | ||
136 | gpio_free(extcon_data->gpio); | ||
137 | err_request_gpio: | ||
138 | extcon_dev_unregister(&extcon_data->edev); | 135 | extcon_dev_unregister(&extcon_data->edev); |
139 | err_extcon_dev_register: | ||
140 | devm_kfree(&pdev->dev, extcon_data); | ||
141 | 136 | ||
142 | return ret; | 137 | return ret; |
143 | } | 138 | } |
@@ -148,9 +143,7 @@ static int __devexit gpio_extcon_remove(struct platform_device *pdev) | |||
148 | 143 | ||
149 | cancel_delayed_work_sync(&extcon_data->work); | 144 | cancel_delayed_work_sync(&extcon_data->work); |
150 | free_irq(extcon_data->irq, extcon_data); | 145 | free_irq(extcon_data->irq, extcon_data); |
151 | gpio_free(extcon_data->gpio); | ||
152 | extcon_dev_unregister(&extcon_data->edev); | 146 | extcon_dev_unregister(&extcon_data->edev); |
153 | devm_kfree(&pdev->dev, extcon_data); | ||
154 | 147 | ||
155 | return 0; | 148 | return 0; |
156 | } | 149 | } |
diff --git a/drivers/power/ds2780_battery.c b/drivers/power/ds2780_battery.c index de31cae1ba53..74fad941c56c 100644 --- a/drivers/power/ds2780_battery.c +++ b/drivers/power/ds2780_battery.c | |||
@@ -39,7 +39,6 @@ struct ds2780_device_info { | |||
39 | struct device *dev; | 39 | struct device *dev; |
40 | struct power_supply bat; | 40 | struct power_supply bat; |
41 | struct device *w1_dev; | 41 | struct device *w1_dev; |
42 | struct task_struct *mutex_holder; | ||
43 | }; | 42 | }; |
44 | 43 | ||
45 | enum current_types { | 44 | enum current_types { |
@@ -64,10 +63,7 @@ static inline struct power_supply *to_power_supply(struct device *dev) | |||
64 | static inline int ds2780_battery_io(struct ds2780_device_info *dev_info, | 63 | static inline int ds2780_battery_io(struct ds2780_device_info *dev_info, |
65 | char *buf, int addr, size_t count, int io) | 64 | char *buf, int addr, size_t count, int io) |
66 | { | 65 | { |
67 | if (dev_info->mutex_holder == current) | 66 | return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io); |
68 | return w1_ds2780_io_nolock(dev_info->w1_dev, buf, addr, count, io); | ||
69 | else | ||
70 | return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io); | ||
71 | } | 67 | } |
72 | 68 | ||
73 | static inline int ds2780_read8(struct ds2780_device_info *dev_info, u8 *val, | 69 | static inline int ds2780_read8(struct ds2780_device_info *dev_info, u8 *val, |
@@ -779,7 +775,6 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev) | |||
779 | dev_info->bat.properties = ds2780_battery_props; | 775 | dev_info->bat.properties = ds2780_battery_props; |
780 | dev_info->bat.num_properties = ARRAY_SIZE(ds2780_battery_props); | 776 | dev_info->bat.num_properties = ARRAY_SIZE(ds2780_battery_props); |
781 | dev_info->bat.get_property = ds2780_battery_get_property; | 777 | dev_info->bat.get_property = ds2780_battery_get_property; |
782 | dev_info->mutex_holder = current; | ||
783 | 778 | ||
784 | ret = power_supply_register(&pdev->dev, &dev_info->bat); | 779 | ret = power_supply_register(&pdev->dev, &dev_info->bat); |
785 | if (ret) { | 780 | if (ret) { |
@@ -809,8 +804,6 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev) | |||
809 | goto fail_remove_bin_file; | 804 | goto fail_remove_bin_file; |
810 | } | 805 | } |
811 | 806 | ||
812 | dev_info->mutex_holder = NULL; | ||
813 | |||
814 | return 0; | 807 | return 0; |
815 | 808 | ||
816 | fail_remove_bin_file: | 809 | fail_remove_bin_file: |
@@ -830,8 +823,6 @@ static int __devexit ds2780_battery_remove(struct platform_device *pdev) | |||
830 | { | 823 | { |
831 | struct ds2780_device_info *dev_info = platform_get_drvdata(pdev); | 824 | struct ds2780_device_info *dev_info = platform_get_drvdata(pdev); |
832 | 825 | ||
833 | dev_info->mutex_holder = current; | ||
834 | |||
835 | /* remove attributes */ | 826 | /* remove attributes */ |
836 | sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group); | 827 | sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group); |
837 | 828 | ||
diff --git a/drivers/power/ds2781_battery.c b/drivers/power/ds2781_battery.c index 975684a40f15..5f92a4bb33f9 100644 --- a/drivers/power/ds2781_battery.c +++ b/drivers/power/ds2781_battery.c | |||
@@ -37,7 +37,6 @@ struct ds2781_device_info { | |||
37 | struct device *dev; | 37 | struct device *dev; |
38 | struct power_supply bat; | 38 | struct power_supply bat; |
39 | struct device *w1_dev; | 39 | struct device *w1_dev; |
40 | struct task_struct *mutex_holder; | ||
41 | }; | 40 | }; |
42 | 41 | ||
43 | enum current_types { | 42 | enum current_types { |
@@ -62,11 +61,7 @@ static inline struct power_supply *to_power_supply(struct device *dev) | |||
62 | static inline int ds2781_battery_io(struct ds2781_device_info *dev_info, | 61 | static inline int ds2781_battery_io(struct ds2781_device_info *dev_info, |
63 | char *buf, int addr, size_t count, int io) | 62 | char *buf, int addr, size_t count, int io) |
64 | { | 63 | { |
65 | if (dev_info->mutex_holder == current) | 64 | return w1_ds2781_io(dev_info->w1_dev, buf, addr, count, io); |
66 | return w1_ds2781_io_nolock(dev_info->w1_dev, buf, addr, | ||
67 | count, io); | ||
68 | else | ||
69 | return w1_ds2781_io(dev_info->w1_dev, buf, addr, count, io); | ||
70 | } | 65 | } |
71 | 66 | ||
72 | int w1_ds2781_read(struct ds2781_device_info *dev_info, char *buf, | 67 | int w1_ds2781_read(struct ds2781_device_info *dev_info, char *buf, |
@@ -775,7 +770,6 @@ static int __devinit ds2781_battery_probe(struct platform_device *pdev) | |||
775 | dev_info->bat.properties = ds2781_battery_props; | 770 | dev_info->bat.properties = ds2781_battery_props; |
776 | dev_info->bat.num_properties = ARRAY_SIZE(ds2781_battery_props); | 771 | dev_info->bat.num_properties = ARRAY_SIZE(ds2781_battery_props); |
777 | dev_info->bat.get_property = ds2781_battery_get_property; | 772 | dev_info->bat.get_property = ds2781_battery_get_property; |
778 | dev_info->mutex_holder = current; | ||
779 | 773 | ||
780 | ret = power_supply_register(&pdev->dev, &dev_info->bat); | 774 | ret = power_supply_register(&pdev->dev, &dev_info->bat); |
781 | if (ret) { | 775 | if (ret) { |
@@ -805,8 +799,6 @@ static int __devinit ds2781_battery_probe(struct platform_device *pdev) | |||
805 | goto fail_remove_bin_file; | 799 | goto fail_remove_bin_file; |
806 | } | 800 | } |
807 | 801 | ||
808 | dev_info->mutex_holder = NULL; | ||
809 | |||
810 | return 0; | 802 | return 0; |
811 | 803 | ||
812 | fail_remove_bin_file: | 804 | fail_remove_bin_file: |
@@ -826,8 +818,6 @@ static int __devexit ds2781_battery_remove(struct platform_device *pdev) | |||
826 | { | 818 | { |
827 | struct ds2781_device_info *dev_info = platform_get_drvdata(pdev); | 819 | struct ds2781_device_info *dev_info = platform_get_drvdata(pdev); |
828 | 820 | ||
829 | dev_info->mutex_holder = current; | ||
830 | |||
831 | /* remove attributes */ | 821 | /* remove attributes */ |
832 | sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2781_attr_group); | 822 | sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2781_attr_group); |
833 | 823 | ||
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c index a0c8965c1a79..530a2d309063 100644 --- a/drivers/w1/masters/ds1wm.c +++ b/drivers/w1/masters/ds1wm.c | |||
@@ -334,7 +334,9 @@ static void ds1wm_search(void *data, struct w1_master *master_dev, | |||
334 | return; | 334 | return; |
335 | } | 335 | } |
336 | 336 | ||
337 | mutex_lock(&master_dev->bus_mutex); | ||
337 | if (ds1wm_reset(ds1wm_data)) { | 338 | if (ds1wm_reset(ds1wm_data)) { |
339 | mutex_unlock(&master_dev->bus_mutex); | ||
338 | dev_dbg(&ds1wm_data->pdev->dev, | 340 | dev_dbg(&ds1wm_data->pdev->dev, |
339 | "pass: %d reset error (or no slaves)\n", pass); | 341 | "pass: %d reset error (or no slaves)\n", pass); |
340 | break; | 342 | break; |
@@ -387,6 +389,7 @@ static void ds1wm_search(void *data, struct w1_master *master_dev, | |||
387 | 389 | ||
388 | } | 390 | } |
389 | if (ds1wm_data->read_error) { | 391 | if (ds1wm_data->read_error) { |
392 | mutex_unlock(&master_dev->bus_mutex); | ||
390 | dev_err(&ds1wm_data->pdev->dev, | 393 | dev_err(&ds1wm_data->pdev->dev, |
391 | "pass: %d read error, retrying\n", pass); | 394 | "pass: %d read error, retrying\n", pass); |
392 | break; | 395 | break; |
@@ -400,6 +403,7 @@ static void ds1wm_search(void *data, struct w1_master *master_dev, | |||
400 | dev_dbg(&ds1wm_data->pdev->dev, | 403 | dev_dbg(&ds1wm_data->pdev->dev, |
401 | "pass: %d resetting bus\n", pass); | 404 | "pass: %d resetting bus\n", pass); |
402 | ds1wm_reset(ds1wm_data); | 405 | ds1wm_reset(ds1wm_data); |
406 | mutex_unlock(&master_dev->bus_mutex); | ||
403 | if ((r_prime & ((u64)1 << 63)) && (d & ((u64)1 << 63))) { | 407 | if ((r_prime & ((u64)1 << 63)) && (d & ((u64)1 << 63))) { |
404 | dev_err(&ds1wm_data->pdev->dev, | 408 | dev_err(&ds1wm_data->pdev->dev, |
405 | "pass: %d bus error, retrying\n", pass); | 409 | "pass: %d bus error, retrying\n", pass); |
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 5ef385bfed18..848399bfb9b4 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c | |||
@@ -180,6 +180,7 @@ static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status) | |||
180 | hdq_data->hdq_irqstatus, OMAP_HDQ_TIMEOUT); | 180 | hdq_data->hdq_irqstatus, OMAP_HDQ_TIMEOUT); |
181 | if (ret == 0) { | 181 | if (ret == 0) { |
182 | dev_dbg(hdq_data->dev, "TX wait elapsed\n"); | 182 | dev_dbg(hdq_data->dev, "TX wait elapsed\n"); |
183 | ret = -ETIMEDOUT; | ||
183 | goto out; | 184 | goto out; |
184 | } | 185 | } |
185 | 186 | ||
@@ -187,7 +188,7 @@ static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status) | |||
187 | /* check irqstatus */ | 188 | /* check irqstatus */ |
188 | if (!(*status & OMAP_HDQ_INT_STATUS_TXCOMPLETE)) { | 189 | if (!(*status & OMAP_HDQ_INT_STATUS_TXCOMPLETE)) { |
189 | dev_dbg(hdq_data->dev, "timeout waiting for" | 190 | dev_dbg(hdq_data->dev, "timeout waiting for" |
190 | "TXCOMPLETE/RXCOMPLETE, %x", *status); | 191 | " TXCOMPLETE/RXCOMPLETE, %x", *status); |
191 | ret = -ETIMEDOUT; | 192 | ret = -ETIMEDOUT; |
192 | goto out; | 193 | goto out; |
193 | } | 194 | } |
@@ -198,7 +199,7 @@ static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status) | |||
198 | OMAP_HDQ_FLAG_CLEAR, &tmp_status); | 199 | OMAP_HDQ_FLAG_CLEAR, &tmp_status); |
199 | if (ret) { | 200 | if (ret) { |
200 | dev_dbg(hdq_data->dev, "timeout waiting GO bit" | 201 | dev_dbg(hdq_data->dev, "timeout waiting GO bit" |
201 | "return to zero, %x", tmp_status); | 202 | " return to zero, %x", tmp_status); |
202 | } | 203 | } |
203 | 204 | ||
204 | out: | 205 | out: |
@@ -341,7 +342,7 @@ static int omap_hdq_break(struct hdq_data *hdq_data) | |||
341 | &tmp_status); | 342 | &tmp_status); |
342 | if (ret) | 343 | if (ret) |
343 | dev_dbg(hdq_data->dev, "timeout waiting INIT&GO bits" | 344 | dev_dbg(hdq_data->dev, "timeout waiting INIT&GO bits" |
344 | "return to zero, %x", tmp_status); | 345 | " return to zero, %x", tmp_status); |
345 | 346 | ||
346 | out: | 347 | out: |
347 | mutex_unlock(&hdq_data->hdq_mutex); | 348 | mutex_unlock(&hdq_data->hdq_mutex); |
@@ -353,7 +354,6 @@ static int hdq_read_byte(struct hdq_data *hdq_data, u8 *val) | |||
353 | { | 354 | { |
354 | int ret = 0; | 355 | int ret = 0; |
355 | u8 status; | 356 | u8 status; |
356 | unsigned long timeout = jiffies + OMAP_HDQ_TIMEOUT; | ||
357 | 357 | ||
358 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | 358 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); |
359 | if (ret < 0) { | 359 | if (ret < 0) { |
@@ -371,22 +371,20 @@ static int hdq_read_byte(struct hdq_data *hdq_data, u8 *val) | |||
371 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO, | 371 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO, |
372 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO); | 372 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO); |
373 | /* | 373 | /* |
374 | * The RX comes immediately after TX. It | 374 | * The RX comes immediately after TX. |
375 | * triggers another interrupt before we | ||
376 | * sleep. So we have to wait for RXCOMPLETE bit. | ||
377 | */ | 375 | */ |
378 | while (!(hdq_data->hdq_irqstatus | 376 | wait_event_timeout(hdq_wait_queue, |
379 | & OMAP_HDQ_INT_STATUS_RXCOMPLETE) | 377 | (hdq_data->hdq_irqstatus |
380 | && time_before(jiffies, timeout)) { | 378 | & OMAP_HDQ_INT_STATUS_RXCOMPLETE), |
381 | schedule_timeout_uninterruptible(1); | 379 | OMAP_HDQ_TIMEOUT); |
382 | } | 380 | |
383 | hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, 0, | 381 | hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, 0, |
384 | OMAP_HDQ_CTRL_STATUS_DIR); | 382 | OMAP_HDQ_CTRL_STATUS_DIR); |
385 | status = hdq_data->hdq_irqstatus; | 383 | status = hdq_data->hdq_irqstatus; |
386 | /* check irqstatus */ | 384 | /* check irqstatus */ |
387 | if (!(status & OMAP_HDQ_INT_STATUS_RXCOMPLETE)) { | 385 | if (!(status & OMAP_HDQ_INT_STATUS_RXCOMPLETE)) { |
388 | dev_dbg(hdq_data->dev, "timeout waiting for" | 386 | dev_dbg(hdq_data->dev, "timeout waiting for" |
389 | "RXCOMPLETE, %x", status); | 387 | " RXCOMPLETE, %x", status); |
390 | ret = -ETIMEDOUT; | 388 | ret = -ETIMEDOUT; |
391 | goto out; | 389 | goto out; |
392 | } | 390 | } |
@@ -396,7 +394,7 @@ static int hdq_read_byte(struct hdq_data *hdq_data, u8 *val) | |||
396 | out: | 394 | out: |
397 | mutex_unlock(&hdq_data->hdq_mutex); | 395 | mutex_unlock(&hdq_data->hdq_mutex); |
398 | rtn: | 396 | rtn: |
399 | return 0; | 397 | return ret; |
400 | 398 | ||
401 | } | 399 | } |
402 | 400 | ||
@@ -470,7 +468,7 @@ static int omap_hdq_put(struct hdq_data *hdq_data) | |||
470 | 468 | ||
471 | if (0 == hdq_data->hdq_usecount) { | 469 | if (0 == hdq_data->hdq_usecount) { |
472 | dev_dbg(hdq_data->dev, "attempt to decrement use count" | 470 | dev_dbg(hdq_data->dev, "attempt to decrement use count" |
473 | "when it is zero"); | 471 | " when it is zero"); |
474 | ret = -EINVAL; | 472 | ret = -EINVAL; |
475 | } else { | 473 | } else { |
476 | hdq_data->hdq_usecount--; | 474 | hdq_data->hdq_usecount--; |
@@ -540,7 +538,7 @@ static void omap_w1_write_byte(void *_hdq, u8 byte) | |||
540 | mutex_unlock(&hdq_data->hdq_mutex); | 538 | mutex_unlock(&hdq_data->hdq_mutex); |
541 | 539 | ||
542 | ret = hdq_write_byte(hdq_data, byte, &status); | 540 | ret = hdq_write_byte(hdq_data, byte, &status); |
543 | if (ret == 0) { | 541 | if (ret < 0) { |
544 | dev_dbg(hdq_data->dev, "TX failure:Ctrl status %x\n", status); | 542 | dev_dbg(hdq_data->dev, "TX failure:Ctrl status %x\n", status); |
545 | return; | 543 | return; |
546 | } | 544 | } |
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index eb9e376d6244..67526690acbc 100644 --- a/drivers/w1/slaves/Kconfig +++ b/drivers/w1/slaves/Kconfig | |||
@@ -94,6 +94,19 @@ config W1_SLAVE_DS2781 | |||
94 | 94 | ||
95 | If you are unsure, say N. | 95 | If you are unsure, say N. |
96 | 96 | ||
97 | config W1_SLAVE_DS28E04 | ||
98 | tristate "4096-Bit Addressable 1-Wire EEPROM with PIO (DS28E04-100)" | ||
99 | depends on W1 | ||
100 | select CRC16 | ||
101 | help | ||
102 | If you enable this you will have the DS28E04-100 | ||
103 | chip support. | ||
104 | |||
105 | Say Y here if you want to use a 1-wire | ||
106 | 4kb EEPROM with PIO family device (DS28E04). | ||
107 | |||
108 | If you are unsure, say N. | ||
109 | |||
97 | config W1_SLAVE_BQ27000 | 110 | config W1_SLAVE_BQ27000 |
98 | tristate "BQ27000 slave support" | 111 | tristate "BQ27000 slave support" |
99 | depends on W1 | 112 | depends on W1 |
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile index c4f1859fb520..05188f6aab5a 100644 --- a/drivers/w1/slaves/Makefile +++ b/drivers/w1/slaves/Makefile | |||
@@ -12,3 +12,4 @@ obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o | |||
12 | obj-$(CONFIG_W1_SLAVE_DS2780) += w1_ds2780.o | 12 | obj-$(CONFIG_W1_SLAVE_DS2780) += w1_ds2780.o |
13 | obj-$(CONFIG_W1_SLAVE_DS2781) += w1_ds2781.o | 13 | obj-$(CONFIG_W1_SLAVE_DS2781) += w1_ds2781.o |
14 | obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o | 14 | obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o |
15 | obj-$(CONFIG_W1_SLAVE_DS28E04) += w1_ds28e04.o | ||
diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c index 52ad812fa1e7..773dca5beafe 100644 --- a/drivers/w1/slaves/w1_bq27000.c +++ b/drivers/w1/slaves/w1_bq27000.c | |||
@@ -31,10 +31,10 @@ static int w1_bq27000_read(struct device *dev, unsigned int reg) | |||
31 | u8 val; | 31 | u8 val; |
32 | struct w1_slave *sl = container_of(dev->parent, struct w1_slave, dev); | 32 | struct w1_slave *sl = container_of(dev->parent, struct w1_slave, dev); |
33 | 33 | ||
34 | mutex_lock(&sl->master->mutex); | 34 | mutex_lock(&sl->master->bus_mutex); |
35 | w1_write_8(sl->master, HDQ_CMD_READ | reg); | 35 | w1_write_8(sl->master, HDQ_CMD_READ | reg); |
36 | val = w1_read_8(sl->master); | 36 | val = w1_read_8(sl->master); |
37 | mutex_unlock(&sl->master->mutex); | 37 | mutex_unlock(&sl->master->bus_mutex); |
38 | 38 | ||
39 | return val; | 39 | return val; |
40 | } | 40 | } |
diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c index 8e813eed0f0a..441ad3a3b586 100644 --- a/drivers/w1/slaves/w1_ds2408.c +++ b/drivers/w1/slaves/w1_ds2408.c | |||
@@ -52,11 +52,11 @@ static int _read_reg(struct w1_slave *sl, u8 address, unsigned char* buf) | |||
52 | if (!buf) | 52 | if (!buf) |
53 | return -EINVAL; | 53 | return -EINVAL; |
54 | 54 | ||
55 | mutex_lock(&sl->master->mutex); | 55 | mutex_lock(&sl->master->bus_mutex); |
56 | dev_dbg(&sl->dev, "mutex locked"); | 56 | dev_dbg(&sl->dev, "mutex locked"); |
57 | 57 | ||
58 | if (w1_reset_select_slave(sl)) { | 58 | if (w1_reset_select_slave(sl)) { |
59 | mutex_unlock(&sl->master->mutex); | 59 | mutex_unlock(&sl->master->bus_mutex); |
60 | return -EIO; | 60 | return -EIO; |
61 | } | 61 | } |
62 | 62 | ||
@@ -66,7 +66,7 @@ static int _read_reg(struct w1_slave *sl, u8 address, unsigned char* buf) | |||
66 | w1_write_block(sl->master, wrbuf, 3); | 66 | w1_write_block(sl->master, wrbuf, 3); |
67 | *buf = w1_read_8(sl->master); | 67 | *buf = w1_read_8(sl->master); |
68 | 68 | ||
69 | mutex_unlock(&sl->master->mutex); | 69 | mutex_unlock(&sl->master->bus_mutex); |
70 | dev_dbg(&sl->dev, "mutex unlocked"); | 70 | dev_dbg(&sl->dev, "mutex unlocked"); |
71 | return 1; | 71 | return 1; |
72 | } | 72 | } |
@@ -165,7 +165,7 @@ static ssize_t w1_f29_write_output( | |||
165 | return -EFAULT; | 165 | return -EFAULT; |
166 | 166 | ||
167 | dev_dbg(&sl->dev, "locking mutex for write_output"); | 167 | dev_dbg(&sl->dev, "locking mutex for write_output"); |
168 | mutex_lock(&sl->master->mutex); | 168 | mutex_lock(&sl->master->bus_mutex); |
169 | dev_dbg(&sl->dev, "mutex locked"); | 169 | dev_dbg(&sl->dev, "mutex locked"); |
170 | 170 | ||
171 | if (w1_reset_select_slave(sl)) | 171 | if (w1_reset_select_slave(sl)) |
@@ -200,14 +200,14 @@ static ssize_t w1_f29_write_output( | |||
200 | /* read the result of the READ_PIO_REGS command */ | 200 | /* read the result of the READ_PIO_REGS command */ |
201 | if (w1_read_8(sl->master) == *buf) { | 201 | if (w1_read_8(sl->master) == *buf) { |
202 | /* success! */ | 202 | /* success! */ |
203 | mutex_unlock(&sl->master->mutex); | 203 | mutex_unlock(&sl->master->bus_mutex); |
204 | dev_dbg(&sl->dev, | 204 | dev_dbg(&sl->dev, |
205 | "mutex unlocked, retries:%d", retries); | 205 | "mutex unlocked, retries:%d", retries); |
206 | return 1; | 206 | return 1; |
207 | } | 207 | } |
208 | } | 208 | } |
209 | error: | 209 | error: |
210 | mutex_unlock(&sl->master->mutex); | 210 | mutex_unlock(&sl->master->bus_mutex); |
211 | dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", retries); | 211 | dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", retries); |
212 | 212 | ||
213 | return -EIO; | 213 | return -EIO; |
@@ -228,7 +228,7 @@ static ssize_t w1_f29_write_activity( | |||
228 | if (count != 1 || off != 0) | 228 | if (count != 1 || off != 0) |
229 | return -EFAULT; | 229 | return -EFAULT; |
230 | 230 | ||
231 | mutex_lock(&sl->master->mutex); | 231 | mutex_lock(&sl->master->bus_mutex); |
232 | 232 | ||
233 | if (w1_reset_select_slave(sl)) | 233 | if (w1_reset_select_slave(sl)) |
234 | goto error; | 234 | goto error; |
@@ -236,7 +236,7 @@ static ssize_t w1_f29_write_activity( | |||
236 | while (retries--) { | 236 | while (retries--) { |
237 | w1_write_8(sl->master, W1_F29_FUNC_RESET_ACTIVITY_LATCHES); | 237 | w1_write_8(sl->master, W1_F29_FUNC_RESET_ACTIVITY_LATCHES); |
238 | if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE) { | 238 | if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE) { |
239 | mutex_unlock(&sl->master->mutex); | 239 | mutex_unlock(&sl->master->bus_mutex); |
240 | return 1; | 240 | return 1; |
241 | } | 241 | } |
242 | if (w1_reset_resume_command(sl->master)) | 242 | if (w1_reset_resume_command(sl->master)) |
@@ -244,7 +244,7 @@ static ssize_t w1_f29_write_activity( | |||
244 | } | 244 | } |
245 | 245 | ||
246 | error: | 246 | error: |
247 | mutex_unlock(&sl->master->mutex); | 247 | mutex_unlock(&sl->master->bus_mutex); |
248 | return -EIO; | 248 | return -EIO; |
249 | } | 249 | } |
250 | 250 | ||
@@ -263,7 +263,7 @@ static ssize_t w1_f29_write_status_control( | |||
263 | if (count != 1 || off != 0) | 263 | if (count != 1 || off != 0) |
264 | return -EFAULT; | 264 | return -EFAULT; |
265 | 265 | ||
266 | mutex_lock(&sl->master->mutex); | 266 | mutex_lock(&sl->master->bus_mutex); |
267 | 267 | ||
268 | if (w1_reset_select_slave(sl)) | 268 | if (w1_reset_select_slave(sl)) |
269 | goto error; | 269 | goto error; |
@@ -285,12 +285,12 @@ static ssize_t w1_f29_write_status_control( | |||
285 | w1_write_block(sl->master, w1_buf, 3); | 285 | w1_write_block(sl->master, w1_buf, 3); |
286 | if (w1_read_8(sl->master) == *buf) { | 286 | if (w1_read_8(sl->master) == *buf) { |
287 | /* success! */ | 287 | /* success! */ |
288 | mutex_unlock(&sl->master->mutex); | 288 | mutex_unlock(&sl->master->bus_mutex); |
289 | return 1; | 289 | return 1; |
290 | } | 290 | } |
291 | } | 291 | } |
292 | error: | 292 | error: |
293 | mutex_unlock(&sl->master->mutex); | 293 | mutex_unlock(&sl->master->bus_mutex); |
294 | 294 | ||
295 | return -EIO; | 295 | return -EIO; |
296 | } | 296 | } |
diff --git a/drivers/w1/slaves/w1_ds2423.c b/drivers/w1/slaves/w1_ds2423.c index 7a7dbe5026f1..40a10b5ed120 100644 --- a/drivers/w1/slaves/w1_ds2423.c +++ b/drivers/w1/slaves/w1_ds2423.c | |||
@@ -66,7 +66,7 @@ static ssize_t w1_counter_read(struct device *device, | |||
66 | wrbuf[0] = 0xA5; | 66 | wrbuf[0] = 0xA5; |
67 | wrbuf[1] = rom_addr & 0xFF; | 67 | wrbuf[1] = rom_addr & 0xFF; |
68 | wrbuf[2] = rom_addr >> 8; | 68 | wrbuf[2] = rom_addr >> 8; |
69 | mutex_lock(&dev->mutex); | 69 | mutex_lock(&dev->bus_mutex); |
70 | if (!w1_reset_select_slave(sl)) { | 70 | if (!w1_reset_select_slave(sl)) { |
71 | w1_write_block(dev, wrbuf, 3); | 71 | w1_write_block(dev, wrbuf, 3); |
72 | read_byte_count = 0; | 72 | read_byte_count = 0; |
@@ -124,7 +124,7 @@ static ssize_t w1_counter_read(struct device *device, | |||
124 | } else { | 124 | } else { |
125 | c -= snprintf(out_buf + PAGE_SIZE - c, c, "Connection error"); | 125 | c -= snprintf(out_buf + PAGE_SIZE - c, c, "Connection error"); |
126 | } | 126 | } |
127 | mutex_unlock(&dev->mutex); | 127 | mutex_unlock(&dev->bus_mutex); |
128 | return PAGE_SIZE - c; | 128 | return PAGE_SIZE - c; |
129 | } | 129 | } |
130 | 130 | ||
diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c index 84e2410aec1d..984b30331a45 100644 --- a/drivers/w1/slaves/w1_ds2431.c +++ b/drivers/w1/slaves/w1_ds2431.c | |||
@@ -107,7 +107,7 @@ static ssize_t w1_f2d_read_bin(struct file *filp, struct kobject *kobj, | |||
107 | if (count == 0) | 107 | if (count == 0) |
108 | return 0; | 108 | return 0; |
109 | 109 | ||
110 | mutex_lock(&sl->master->mutex); | 110 | mutex_lock(&sl->master->bus_mutex); |
111 | 111 | ||
112 | /* read directly from the EEPROM in chunks of W1_F2D_READ_MAXLEN */ | 112 | /* read directly from the EEPROM in chunks of W1_F2D_READ_MAXLEN */ |
113 | while (todo > 0) { | 113 | while (todo > 0) { |
@@ -126,7 +126,7 @@ static ssize_t w1_f2d_read_bin(struct file *filp, struct kobject *kobj, | |||
126 | off += W1_F2D_READ_MAXLEN; | 126 | off += W1_F2D_READ_MAXLEN; |
127 | } | 127 | } |
128 | 128 | ||
129 | mutex_unlock(&sl->master->mutex); | 129 | mutex_unlock(&sl->master->bus_mutex); |
130 | 130 | ||
131 | return count; | 131 | return count; |
132 | } | 132 | } |
@@ -214,7 +214,7 @@ static ssize_t w1_f2d_write_bin(struct file *filp, struct kobject *kobj, | |||
214 | if (count == 0) | 214 | if (count == 0) |
215 | return 0; | 215 | return 0; |
216 | 216 | ||
217 | mutex_lock(&sl->master->mutex); | 217 | mutex_lock(&sl->master->bus_mutex); |
218 | 218 | ||
219 | /* Can only write data in blocks of the size of the scratchpad */ | 219 | /* Can only write data in blocks of the size of the scratchpad */ |
220 | addr = off; | 220 | addr = off; |
@@ -259,7 +259,7 @@ static ssize_t w1_f2d_write_bin(struct file *filp, struct kobject *kobj, | |||
259 | } | 259 | } |
260 | 260 | ||
261 | out_up: | 261 | out_up: |
262 | mutex_unlock(&sl->master->mutex); | 262 | mutex_unlock(&sl->master->bus_mutex); |
263 | 263 | ||
264 | return count; | 264 | return count; |
265 | } | 265 | } |
diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c index 0f7b8f9c509a..85f2cdb27fa2 100644 --- a/drivers/w1/slaves/w1_ds2433.c +++ b/drivers/w1/slaves/w1_ds2433.c | |||
@@ -107,7 +107,7 @@ static ssize_t w1_f23_read_bin(struct file *filp, struct kobject *kobj, | |||
107 | if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0) | 107 | if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0) |
108 | return 0; | 108 | return 0; |
109 | 109 | ||
110 | mutex_lock(&sl->master->mutex); | 110 | mutex_lock(&sl->master->bus_mutex); |
111 | 111 | ||
112 | #ifdef CONFIG_W1_SLAVE_DS2433_CRC | 112 | #ifdef CONFIG_W1_SLAVE_DS2433_CRC |
113 | 113 | ||
@@ -138,7 +138,7 @@ static ssize_t w1_f23_read_bin(struct file *filp, struct kobject *kobj, | |||
138 | #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ | 138 | #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ |
139 | 139 | ||
140 | out_up: | 140 | out_up: |
141 | mutex_unlock(&sl->master->mutex); | 141 | mutex_unlock(&sl->master->bus_mutex); |
142 | 142 | ||
143 | return count; | 143 | return count; |
144 | } | 144 | } |
@@ -233,7 +233,7 @@ static ssize_t w1_f23_write_bin(struct file *filp, struct kobject *kobj, | |||
233 | } | 233 | } |
234 | #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ | 234 | #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ |
235 | 235 | ||
236 | mutex_lock(&sl->master->mutex); | 236 | mutex_lock(&sl->master->bus_mutex); |
237 | 237 | ||
238 | /* Can only write data to one page at a time */ | 238 | /* Can only write data to one page at a time */ |
239 | idx = 0; | 239 | idx = 0; |
@@ -251,7 +251,7 @@ static ssize_t w1_f23_write_bin(struct file *filp, struct kobject *kobj, | |||
251 | } | 251 | } |
252 | 252 | ||
253 | out_up: | 253 | out_up: |
254 | mutex_unlock(&sl->master->mutex); | 254 | mutex_unlock(&sl->master->bus_mutex); |
255 | 255 | ||
256 | return count; | 256 | return count; |
257 | } | 257 | } |
diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c index 5754c9a4f58b..aa7bd5fa2fa8 100644 --- a/drivers/w1/slaves/w1_ds2760.c +++ b/drivers/w1/slaves/w1_ds2760.c | |||
@@ -31,7 +31,7 @@ static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count, | |||
31 | if (!dev) | 31 | if (!dev) |
32 | return 0; | 32 | return 0; |
33 | 33 | ||
34 | mutex_lock(&sl->master->mutex); | 34 | mutex_lock(&sl->master->bus_mutex); |
35 | 35 | ||
36 | if (addr > DS2760_DATA_SIZE || addr < 0) { | 36 | if (addr > DS2760_DATA_SIZE || addr < 0) { |
37 | count = 0; | 37 | count = 0; |
@@ -54,7 +54,7 @@ static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count, | |||
54 | } | 54 | } |
55 | 55 | ||
56 | out: | 56 | out: |
57 | mutex_unlock(&sl->master->mutex); | 57 | mutex_unlock(&sl->master->bus_mutex); |
58 | 58 | ||
59 | return count; | 59 | return count; |
60 | } | 60 | } |
@@ -76,14 +76,14 @@ static int w1_ds2760_eeprom_cmd(struct device *dev, int addr, int cmd) | |||
76 | if (!dev) | 76 | if (!dev) |
77 | return -EINVAL; | 77 | return -EINVAL; |
78 | 78 | ||
79 | mutex_lock(&sl->master->mutex); | 79 | mutex_lock(&sl->master->bus_mutex); |
80 | 80 | ||
81 | if (w1_reset_select_slave(sl) == 0) { | 81 | if (w1_reset_select_slave(sl) == 0) { |
82 | w1_write_8(sl->master, cmd); | 82 | w1_write_8(sl->master, cmd); |
83 | w1_write_8(sl->master, addr); | 83 | w1_write_8(sl->master, addr); |
84 | } | 84 | } |
85 | 85 | ||
86 | mutex_unlock(&sl->master->mutex); | 86 | mutex_unlock(&sl->master->bus_mutex); |
87 | return 0; | 87 | return 0; |
88 | } | 88 | } |
89 | 89 | ||
diff --git a/drivers/w1/slaves/w1_ds2780.c b/drivers/w1/slaves/w1_ds2780.c index 39f78c0b143c..7b09307de0ef 100644 --- a/drivers/w1/slaves/w1_ds2780.c +++ b/drivers/w1/slaves/w1_ds2780.c | |||
@@ -60,30 +60,16 @@ int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count, | |||
60 | if (!dev) | 60 | if (!dev) |
61 | return -ENODEV; | 61 | return -ENODEV; |
62 | 62 | ||
63 | mutex_lock(&sl->master->mutex); | 63 | mutex_lock(&sl->master->bus_mutex); |
64 | 64 | ||
65 | ret = w1_ds2780_do_io(dev, buf, addr, count, io); | 65 | ret = w1_ds2780_do_io(dev, buf, addr, count, io); |
66 | 66 | ||
67 | mutex_unlock(&sl->master->mutex); | 67 | mutex_unlock(&sl->master->bus_mutex); |
68 | 68 | ||
69 | return ret; | 69 | return ret; |
70 | } | 70 | } |
71 | EXPORT_SYMBOL(w1_ds2780_io); | 71 | EXPORT_SYMBOL(w1_ds2780_io); |
72 | 72 | ||
73 | int w1_ds2780_io_nolock(struct device *dev, char *buf, int addr, size_t count, | ||
74 | int io) | ||
75 | { | ||
76 | int ret; | ||
77 | |||
78 | if (!dev) | ||
79 | return -ENODEV; | ||
80 | |||
81 | ret = w1_ds2780_do_io(dev, buf, addr, count, io); | ||
82 | |||
83 | return ret; | ||
84 | } | ||
85 | EXPORT_SYMBOL(w1_ds2780_io_nolock); | ||
86 | |||
87 | int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd) | 73 | int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd) |
88 | { | 74 | { |
89 | struct w1_slave *sl = container_of(dev, struct w1_slave, dev); | 75 | struct w1_slave *sl = container_of(dev, struct w1_slave, dev); |
@@ -91,14 +77,14 @@ int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd) | |||
91 | if (!dev) | 77 | if (!dev) |
92 | return -EINVAL; | 78 | return -EINVAL; |
93 | 79 | ||
94 | mutex_lock(&sl->master->mutex); | 80 | mutex_lock(&sl->master->bus_mutex); |
95 | 81 | ||
96 | if (w1_reset_select_slave(sl) == 0) { | 82 | if (w1_reset_select_slave(sl) == 0) { |
97 | w1_write_8(sl->master, cmd); | 83 | w1_write_8(sl->master, cmd); |
98 | w1_write_8(sl->master, addr); | 84 | w1_write_8(sl->master, addr); |
99 | } | 85 | } |
100 | 86 | ||
101 | mutex_unlock(&sl->master->mutex); | 87 | mutex_unlock(&sl->master->bus_mutex); |
102 | return 0; | 88 | return 0; |
103 | } | 89 | } |
104 | EXPORT_SYMBOL(w1_ds2780_eeprom_cmd); | 90 | EXPORT_SYMBOL(w1_ds2780_eeprom_cmd); |
diff --git a/drivers/w1/slaves/w1_ds2780.h b/drivers/w1/slaves/w1_ds2780.h index 737379365021..a1fba79eb1b5 100644 --- a/drivers/w1/slaves/w1_ds2780.h +++ b/drivers/w1/slaves/w1_ds2780.h | |||
@@ -124,8 +124,6 @@ | |||
124 | 124 | ||
125 | extern int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count, | 125 | extern int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count, |
126 | int io); | 126 | int io); |
127 | extern int w1_ds2780_io_nolock(struct device *dev, char *buf, int addr, | ||
128 | size_t count, int io); | ||
129 | extern int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd); | 127 | extern int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd); |
130 | 128 | ||
131 | #endif /* !_W1_DS2780_H */ | 129 | #endif /* !_W1_DS2780_H */ |
diff --git a/drivers/w1/slaves/w1_ds2781.c b/drivers/w1/slaves/w1_ds2781.c index 0d0c7985293f..877daf74159c 100644 --- a/drivers/w1/slaves/w1_ds2781.c +++ b/drivers/w1/slaves/w1_ds2781.c | |||
@@ -58,30 +58,16 @@ int w1_ds2781_io(struct device *dev, char *buf, int addr, size_t count, | |||
58 | if (!dev) | 58 | if (!dev) |
59 | return -ENODEV; | 59 | return -ENODEV; |
60 | 60 | ||
61 | mutex_lock(&sl->master->mutex); | 61 | mutex_lock(&sl->master->bus_mutex); |
62 | 62 | ||
63 | ret = w1_ds2781_do_io(dev, buf, addr, count, io); | 63 | ret = w1_ds2781_do_io(dev, buf, addr, count, io); |
64 | 64 | ||
65 | mutex_unlock(&sl->master->mutex); | 65 | mutex_unlock(&sl->master->bus_mutex); |
66 | 66 | ||
67 | return ret; | 67 | return ret; |
68 | } | 68 | } |
69 | EXPORT_SYMBOL(w1_ds2781_io); | 69 | EXPORT_SYMBOL(w1_ds2781_io); |
70 | 70 | ||
71 | int w1_ds2781_io_nolock(struct device *dev, char *buf, int addr, size_t count, | ||
72 | int io) | ||
73 | { | ||
74 | int ret; | ||
75 | |||
76 | if (!dev) | ||
77 | return -ENODEV; | ||
78 | |||
79 | ret = w1_ds2781_do_io(dev, buf, addr, count, io); | ||
80 | |||
81 | return ret; | ||
82 | } | ||
83 | EXPORT_SYMBOL(w1_ds2781_io_nolock); | ||
84 | |||
85 | int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd) | 71 | int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd) |
86 | { | 72 | { |
87 | struct w1_slave *sl = container_of(dev, struct w1_slave, dev); | 73 | struct w1_slave *sl = container_of(dev, struct w1_slave, dev); |
@@ -89,14 +75,14 @@ int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd) | |||
89 | if (!dev) | 75 | if (!dev) |
90 | return -EINVAL; | 76 | return -EINVAL; |
91 | 77 | ||
92 | mutex_lock(&sl->master->mutex); | 78 | mutex_lock(&sl->master->bus_mutex); |
93 | 79 | ||
94 | if (w1_reset_select_slave(sl) == 0) { | 80 | if (w1_reset_select_slave(sl) == 0) { |
95 | w1_write_8(sl->master, cmd); | 81 | w1_write_8(sl->master, cmd); |
96 | w1_write_8(sl->master, addr); | 82 | w1_write_8(sl->master, addr); |
97 | } | 83 | } |
98 | 84 | ||
99 | mutex_unlock(&sl->master->mutex); | 85 | mutex_unlock(&sl->master->bus_mutex); |
100 | return 0; | 86 | return 0; |
101 | } | 87 | } |
102 | EXPORT_SYMBOL(w1_ds2781_eeprom_cmd); | 88 | EXPORT_SYMBOL(w1_ds2781_eeprom_cmd); |
diff --git a/drivers/w1/slaves/w1_ds2781.h b/drivers/w1/slaves/w1_ds2781.h index 82bc66497b43..557dfb0b4f64 100644 --- a/drivers/w1/slaves/w1_ds2781.h +++ b/drivers/w1/slaves/w1_ds2781.h | |||
@@ -129,8 +129,6 @@ | |||
129 | 129 | ||
130 | extern int w1_ds2781_io(struct device *dev, char *buf, int addr, size_t count, | 130 | extern int w1_ds2781_io(struct device *dev, char *buf, int addr, size_t count, |
131 | int io); | 131 | int io); |
132 | extern int w1_ds2781_io_nolock(struct device *dev, char *buf, int addr, | ||
133 | size_t count, int io); | ||
134 | extern int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd); | 132 | extern int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd); |
135 | 133 | ||
136 | #endif /* !_W1_DS2781_H */ | 134 | #endif /* !_W1_DS2781_H */ |
diff --git a/drivers/w1/slaves/w1_ds28e04.c b/drivers/w1/slaves/w1_ds28e04.c new file mode 100644 index 000000000000..98117db595bb --- /dev/null +++ b/drivers/w1/slaves/w1_ds28e04.c | |||
@@ -0,0 +1,469 @@ | |||
1 | /* | ||
2 | * w1_ds28e04.c - w1 family 1C (DS28E04) driver | ||
3 | * | ||
4 | * Copyright (c) 2012 Markus Franke <franke.m@sebakmt.com> | ||
5 | * | ||
6 | * This source code is licensed under the GNU General Public License, | ||
7 | * Version 2. See the file COPYING for more details. | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/moduleparam.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/crc16.h> | ||
18 | #include <linux/uaccess.h> | ||
19 | |||
20 | #define CRC16_INIT 0 | ||
21 | #define CRC16_VALID 0xb001 | ||
22 | |||
23 | #include "../w1.h" | ||
24 | #include "../w1_int.h" | ||
25 | #include "../w1_family.h" | ||
26 | |||
27 | MODULE_LICENSE("GPL"); | ||
28 | MODULE_AUTHOR("Markus Franke <franke.m@sebakmt.com>, <franm@hrz.tu-chemnitz.de>"); | ||
29 | MODULE_DESCRIPTION("w1 family 1C driver for DS28E04, 4kb EEPROM and PIO"); | ||
30 | |||
31 | /* Allow the strong pullup to be disabled, but default to enabled. | ||
32 | * If it was disabled a parasite powered device might not get the required | ||
33 | * current to copy the data from the scratchpad to EEPROM. If it is enabled | ||
34 | * parasite powered devices have a better chance of getting the current | ||
35 | * required. | ||
36 | */ | ||
37 | static int w1_strong_pullup = 1; | ||
38 | module_param_named(strong_pullup, w1_strong_pullup, int, 0); | ||
39 | |||
40 | /* enable/disable CRC checking on DS28E04-100 memory accesses */ | ||
41 | static char w1_enable_crccheck = 1; | ||
42 | |||
43 | #define W1_EEPROM_SIZE 512 | ||
44 | #define W1_PAGE_COUNT 16 | ||
45 | #define W1_PAGE_SIZE 32 | ||
46 | #define W1_PAGE_BITS 5 | ||
47 | #define W1_PAGE_MASK 0x1F | ||
48 | |||
49 | #define W1_F1C_READ_EEPROM 0xF0 | ||
50 | #define W1_F1C_WRITE_SCRATCH 0x0F | ||
51 | #define W1_F1C_READ_SCRATCH 0xAA | ||
52 | #define W1_F1C_COPY_SCRATCH 0x55 | ||
53 | #define W1_F1C_ACCESS_WRITE 0x5A | ||
54 | |||
55 | #define W1_1C_REG_LOGIC_STATE 0x220 | ||
56 | |||
57 | struct w1_f1C_data { | ||
58 | u8 memory[W1_EEPROM_SIZE]; | ||
59 | u32 validcrc; | ||
60 | }; | ||
61 | |||
62 | /** | ||
63 | * Check the file size bounds and adjusts count as needed. | ||
64 | * This would not be needed if the file size didn't reset to 0 after a write. | ||
65 | */ | ||
66 | static inline size_t w1_f1C_fix_count(loff_t off, size_t count, size_t size) | ||
67 | { | ||
68 | if (off > size) | ||
69 | return 0; | ||
70 | |||
71 | if ((off + count) > size) | ||
72 | return size - off; | ||
73 | |||
74 | return count; | ||
75 | } | ||
76 | |||
77 | static int w1_f1C_refresh_block(struct w1_slave *sl, struct w1_f1C_data *data, | ||
78 | int block) | ||
79 | { | ||
80 | u8 wrbuf[3]; | ||
81 | int off = block * W1_PAGE_SIZE; | ||
82 | |||
83 | if (data->validcrc & (1 << block)) | ||
84 | return 0; | ||
85 | |||
86 | if (w1_reset_select_slave(sl)) { | ||
87 | data->validcrc = 0; | ||
88 | return -EIO; | ||
89 | } | ||
90 | |||
91 | wrbuf[0] = W1_F1C_READ_EEPROM; | ||
92 | wrbuf[1] = off & 0xff; | ||
93 | wrbuf[2] = off >> 8; | ||
94 | w1_write_block(sl->master, wrbuf, 3); | ||
95 | w1_read_block(sl->master, &data->memory[off], W1_PAGE_SIZE); | ||
96 | |||
97 | /* cache the block if the CRC is valid */ | ||
98 | if (crc16(CRC16_INIT, &data->memory[off], W1_PAGE_SIZE) == CRC16_VALID) | ||
99 | data->validcrc |= (1 << block); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int w1_f1C_read(struct w1_slave *sl, int addr, int len, char *data) | ||
105 | { | ||
106 | u8 wrbuf[3]; | ||
107 | |||
108 | /* read directly from the EEPROM */ | ||
109 | if (w1_reset_select_slave(sl)) | ||
110 | return -EIO; | ||
111 | |||
112 | wrbuf[0] = W1_F1C_READ_EEPROM; | ||
113 | wrbuf[1] = addr & 0xff; | ||
114 | wrbuf[2] = addr >> 8; | ||
115 | |||
116 | w1_write_block(sl->master, wrbuf, sizeof(wrbuf)); | ||
117 | return w1_read_block(sl->master, data, len); | ||
118 | } | ||
119 | |||
120 | static ssize_t w1_f1C_read_bin(struct file *filp, struct kobject *kobj, | ||
121 | struct bin_attribute *bin_attr, | ||
122 | char *buf, loff_t off, size_t count) | ||
123 | { | ||
124 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | ||
125 | struct w1_f1C_data *data = sl->family_data; | ||
126 | int i, min_page, max_page; | ||
127 | |||
128 | count = w1_f1C_fix_count(off, count, W1_EEPROM_SIZE); | ||
129 | if (count == 0) | ||
130 | return 0; | ||
131 | |||
132 | mutex_lock(&sl->master->mutex); | ||
133 | |||
134 | if (w1_enable_crccheck) { | ||
135 | min_page = (off >> W1_PAGE_BITS); | ||
136 | max_page = (off + count - 1) >> W1_PAGE_BITS; | ||
137 | for (i = min_page; i <= max_page; i++) { | ||
138 | if (w1_f1C_refresh_block(sl, data, i)) { | ||
139 | count = -EIO; | ||
140 | goto out_up; | ||
141 | } | ||
142 | } | ||
143 | memcpy(buf, &data->memory[off], count); | ||
144 | } else { | ||
145 | count = w1_f1C_read(sl, off, count, buf); | ||
146 | } | ||
147 | |||
148 | out_up: | ||
149 | mutex_unlock(&sl->master->mutex); | ||
150 | |||
151 | return count; | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * Writes to the scratchpad and reads it back for verification. | ||
156 | * Then copies the scratchpad to EEPROM. | ||
157 | * The data must be on one page. | ||
158 | * The master must be locked. | ||
159 | * | ||
160 | * @param sl The slave structure | ||
161 | * @param addr Address for the write | ||
162 | * @param len length must be <= (W1_PAGE_SIZE - (addr & W1_PAGE_MASK)) | ||
163 | * @param data The data to write | ||
164 | * @return 0=Success -1=failure | ||
165 | */ | ||
166 | static int w1_f1C_write(struct w1_slave *sl, int addr, int len, const u8 *data) | ||
167 | { | ||
168 | u8 wrbuf[4]; | ||
169 | u8 rdbuf[W1_PAGE_SIZE + 3]; | ||
170 | u8 es = (addr + len - 1) & 0x1f; | ||
171 | unsigned int tm = 10; | ||
172 | int i; | ||
173 | struct w1_f1C_data *f1C = sl->family_data; | ||
174 | |||
175 | /* Write the data to the scratchpad */ | ||
176 | if (w1_reset_select_slave(sl)) | ||
177 | return -1; | ||
178 | |||
179 | wrbuf[0] = W1_F1C_WRITE_SCRATCH; | ||
180 | wrbuf[1] = addr & 0xff; | ||
181 | wrbuf[2] = addr >> 8; | ||
182 | |||
183 | w1_write_block(sl->master, wrbuf, 3); | ||
184 | w1_write_block(sl->master, data, len); | ||
185 | |||
186 | /* Read the scratchpad and verify */ | ||
187 | if (w1_reset_select_slave(sl)) | ||
188 | return -1; | ||
189 | |||
190 | w1_write_8(sl->master, W1_F1C_READ_SCRATCH); | ||
191 | w1_read_block(sl->master, rdbuf, len + 3); | ||
192 | |||
193 | /* Compare what was read against the data written */ | ||
194 | if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) || | ||
195 | (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0)) | ||
196 | return -1; | ||
197 | |||
198 | /* Copy the scratchpad to EEPROM */ | ||
199 | if (w1_reset_select_slave(sl)) | ||
200 | return -1; | ||
201 | |||
202 | wrbuf[0] = W1_F1C_COPY_SCRATCH; | ||
203 | wrbuf[3] = es; | ||
204 | |||
205 | for (i = 0; i < sizeof(wrbuf); ++i) { | ||
206 | /* issue 10ms strong pullup (or delay) on the last byte | ||
207 | for writing the data from the scratchpad to EEPROM */ | ||
208 | if (w1_strong_pullup && i == sizeof(wrbuf)-1) | ||
209 | w1_next_pullup(sl->master, tm); | ||
210 | |||
211 | w1_write_8(sl->master, wrbuf[i]); | ||
212 | } | ||
213 | |||
214 | if (!w1_strong_pullup) | ||
215 | msleep(tm); | ||
216 | |||
217 | if (w1_enable_crccheck) { | ||
218 | /* invalidate cached data */ | ||
219 | f1C->validcrc &= ~(1 << (addr >> W1_PAGE_BITS)); | ||
220 | } | ||
221 | |||
222 | /* Reset the bus to wake up the EEPROM (this may not be needed) */ | ||
223 | w1_reset_bus(sl->master); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static ssize_t w1_f1C_write_bin(struct file *filp, struct kobject *kobj, | ||
229 | struct bin_attribute *bin_attr, | ||
230 | char *buf, loff_t off, size_t count) | ||
231 | |||
232 | { | ||
233 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | ||
234 | int addr, len, idx; | ||
235 | |||
236 | count = w1_f1C_fix_count(off, count, W1_EEPROM_SIZE); | ||
237 | if (count == 0) | ||
238 | return 0; | ||
239 | |||
240 | if (w1_enable_crccheck) { | ||
241 | /* can only write full blocks in cached mode */ | ||
242 | if ((off & W1_PAGE_MASK) || (count & W1_PAGE_MASK)) { | ||
243 | dev_err(&sl->dev, "invalid offset/count off=%d cnt=%zd\n", | ||
244 | (int)off, count); | ||
245 | return -EINVAL; | ||
246 | } | ||
247 | |||
248 | /* make sure the block CRCs are valid */ | ||
249 | for (idx = 0; idx < count; idx += W1_PAGE_SIZE) { | ||
250 | if (crc16(CRC16_INIT, &buf[idx], W1_PAGE_SIZE) | ||
251 | != CRC16_VALID) { | ||
252 | dev_err(&sl->dev, "bad CRC at offset %d\n", | ||
253 | (int)off); | ||
254 | return -EINVAL; | ||
255 | } | ||
256 | } | ||
257 | } | ||
258 | |||
259 | mutex_lock(&sl->master->mutex); | ||
260 | |||
261 | /* Can only write data to one page at a time */ | ||
262 | idx = 0; | ||
263 | while (idx < count) { | ||
264 | addr = off + idx; | ||
265 | len = W1_PAGE_SIZE - (addr & W1_PAGE_MASK); | ||
266 | if (len > (count - idx)) | ||
267 | len = count - idx; | ||
268 | |||
269 | if (w1_f1C_write(sl, addr, len, &buf[idx]) < 0) { | ||
270 | count = -EIO; | ||
271 | goto out_up; | ||
272 | } | ||
273 | idx += len; | ||
274 | } | ||
275 | |||
276 | out_up: | ||
277 | mutex_unlock(&sl->master->mutex); | ||
278 | |||
279 | return count; | ||
280 | } | ||
281 | |||
282 | static ssize_t w1_f1C_read_pio(struct file *filp, struct kobject *kobj, | ||
283 | struct bin_attribute *bin_attr, | ||
284 | char *buf, loff_t off, size_t count) | ||
285 | |||
286 | { | ||
287 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | ||
288 | int ret; | ||
289 | |||
290 | /* check arguments */ | ||
291 | if (off != 0 || count != 1 || buf == NULL) | ||
292 | return -EINVAL; | ||
293 | |||
294 | mutex_lock(&sl->master->mutex); | ||
295 | ret = w1_f1C_read(sl, W1_1C_REG_LOGIC_STATE, count, buf); | ||
296 | mutex_unlock(&sl->master->mutex); | ||
297 | |||
298 | return ret; | ||
299 | } | ||
300 | |||
301 | static ssize_t w1_f1C_write_pio(struct file *filp, struct kobject *kobj, | ||
302 | struct bin_attribute *bin_attr, | ||
303 | char *buf, loff_t off, size_t count) | ||
304 | |||
305 | { | ||
306 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | ||
307 | u8 wrbuf[3]; | ||
308 | u8 ack; | ||
309 | |||
310 | /* check arguments */ | ||
311 | if (off != 0 || count != 1 || buf == NULL) | ||
312 | return -EINVAL; | ||
313 | |||
314 | mutex_lock(&sl->master->mutex); | ||
315 | |||
316 | /* Write the PIO data */ | ||
317 | if (w1_reset_select_slave(sl)) { | ||
318 | mutex_unlock(&sl->master->mutex); | ||
319 | return -1; | ||
320 | } | ||
321 | |||
322 | /* set bit 7..2 to value '1' */ | ||
323 | *buf = *buf | 0xFC; | ||
324 | |||
325 | wrbuf[0] = W1_F1C_ACCESS_WRITE; | ||
326 | wrbuf[1] = *buf; | ||
327 | wrbuf[2] = ~(*buf); | ||
328 | w1_write_block(sl->master, wrbuf, 3); | ||
329 | |||
330 | w1_read_block(sl->master, &ack, sizeof(ack)); | ||
331 | |||
332 | mutex_unlock(&sl->master->mutex); | ||
333 | |||
334 | /* check for acknowledgement */ | ||
335 | if (ack != 0xAA) | ||
336 | return -EIO; | ||
337 | |||
338 | return count; | ||
339 | } | ||
340 | |||
341 | static ssize_t w1_f1C_show_crccheck(struct device *dev, | ||
342 | struct device_attribute *attr, char *buf) | ||
343 | { | ||
344 | if (put_user(w1_enable_crccheck + 0x30, buf)) | ||
345 | return -EFAULT; | ||
346 | |||
347 | return sizeof(w1_enable_crccheck); | ||
348 | } | ||
349 | |||
350 | static ssize_t w1_f1C_store_crccheck(struct device *dev, | ||
351 | struct device_attribute *attr, | ||
352 | const char *buf, size_t count) | ||
353 | { | ||
354 | char val; | ||
355 | |||
356 | if (count != 1 || !buf) | ||
357 | return -EINVAL; | ||
358 | |||
359 | if (get_user(val, buf)) | ||
360 | return -EFAULT; | ||
361 | |||
362 | /* convert to decimal */ | ||
363 | val = val - 0x30; | ||
364 | if (val != 0 && val != 1) | ||
365 | return -EINVAL; | ||
366 | |||
367 | /* set the new value */ | ||
368 | w1_enable_crccheck = val; | ||
369 | |||
370 | return sizeof(w1_enable_crccheck); | ||
371 | } | ||
372 | |||
373 | #define NB_SYSFS_BIN_FILES 2 | ||
374 | static struct bin_attribute w1_f1C_bin_attr[NB_SYSFS_BIN_FILES] = { | ||
375 | { | ||
376 | .attr = { | ||
377 | .name = "eeprom", | ||
378 | .mode = S_IRUGO | S_IWUSR, | ||
379 | }, | ||
380 | .size = W1_EEPROM_SIZE, | ||
381 | .read = w1_f1C_read_bin, | ||
382 | .write = w1_f1C_write_bin, | ||
383 | }, | ||
384 | { | ||
385 | .attr = { | ||
386 | .name = "pio", | ||
387 | .mode = S_IRUGO | S_IWUSR, | ||
388 | }, | ||
389 | .size = 1, | ||
390 | .read = w1_f1C_read_pio, | ||
391 | .write = w1_f1C_write_pio, | ||
392 | } | ||
393 | }; | ||
394 | |||
395 | static DEVICE_ATTR(crccheck, S_IWUSR | S_IRUGO, | ||
396 | w1_f1C_show_crccheck, w1_f1C_store_crccheck); | ||
397 | |||
398 | static int w1_f1C_add_slave(struct w1_slave *sl) | ||
399 | { | ||
400 | int err = 0; | ||
401 | int i; | ||
402 | struct w1_f1C_data *data = NULL; | ||
403 | |||
404 | if (w1_enable_crccheck) { | ||
405 | data = kzalloc(sizeof(struct w1_f1C_data), GFP_KERNEL); | ||
406 | if (!data) | ||
407 | return -ENOMEM; | ||
408 | sl->family_data = data; | ||
409 | } | ||
410 | |||
411 | /* create binary sysfs attributes */ | ||
412 | for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i) | ||
413 | err = sysfs_create_bin_file( | ||
414 | &sl->dev.kobj, &(w1_f1C_bin_attr[i])); | ||
415 | |||
416 | if (!err) { | ||
417 | /* create device attributes */ | ||
418 | err = device_create_file(&sl->dev, &dev_attr_crccheck); | ||
419 | } | ||
420 | |||
421 | if (err) { | ||
422 | /* remove binary sysfs attributes */ | ||
423 | for (i = 0; i < NB_SYSFS_BIN_FILES; ++i) | ||
424 | sysfs_remove_bin_file( | ||
425 | &sl->dev.kobj, &(w1_f1C_bin_attr[i])); | ||
426 | |||
427 | kfree(data); | ||
428 | } | ||
429 | |||
430 | return err; | ||
431 | } | ||
432 | |||
433 | static void w1_f1C_remove_slave(struct w1_slave *sl) | ||
434 | { | ||
435 | int i; | ||
436 | |||
437 | kfree(sl->family_data); | ||
438 | sl->family_data = NULL; | ||
439 | |||
440 | /* remove device attributes */ | ||
441 | device_remove_file(&sl->dev, &dev_attr_crccheck); | ||
442 | |||
443 | /* remove binary sysfs attributes */ | ||
444 | for (i = 0; i < NB_SYSFS_BIN_FILES; ++i) | ||
445 | sysfs_remove_bin_file(&sl->dev.kobj, &(w1_f1C_bin_attr[i])); | ||
446 | } | ||
447 | |||
448 | static struct w1_family_ops w1_f1C_fops = { | ||
449 | .add_slave = w1_f1C_add_slave, | ||
450 | .remove_slave = w1_f1C_remove_slave, | ||
451 | }; | ||
452 | |||
453 | static struct w1_family w1_family_1C = { | ||
454 | .fid = W1_FAMILY_DS28E04, | ||
455 | .fops = &w1_f1C_fops, | ||
456 | }; | ||
457 | |||
458 | static int __init w1_f1C_init(void) | ||
459 | { | ||
460 | return w1_register_family(&w1_family_1C); | ||
461 | } | ||
462 | |||
463 | static void __exit w1_f1C_fini(void) | ||
464 | { | ||
465 | w1_unregister_family(&w1_family_1C); | ||
466 | } | ||
467 | |||
468 | module_init(w1_f1C_init); | ||
469 | module_exit(w1_f1C_fini); | ||
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index ff29ae747ee8..d90062b211f8 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c | |||
@@ -179,7 +179,7 @@ static ssize_t w1_therm_read(struct device *device, | |||
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 | i = mutex_lock_interruptible(&dev->mutex); | 182 | i = mutex_lock_interruptible(&dev->bus_mutex); |
183 | if (i != 0) | 183 | if (i != 0) |
184 | return i; | 184 | return i; |
185 | 185 | ||
@@ -207,19 +207,19 @@ static ssize_t w1_therm_read(struct device *device, | |||
207 | w1_write_8(dev, W1_CONVERT_TEMP); | 207 | w1_write_8(dev, W1_CONVERT_TEMP); |
208 | 208 | ||
209 | if (external_power) { | 209 | if (external_power) { |
210 | mutex_unlock(&dev->mutex); | 210 | mutex_unlock(&dev->bus_mutex); |
211 | 211 | ||
212 | sleep_rem = msleep_interruptible(tm); | 212 | sleep_rem = msleep_interruptible(tm); |
213 | if (sleep_rem != 0) | 213 | if (sleep_rem != 0) |
214 | return -EINTR; | 214 | return -EINTR; |
215 | 215 | ||
216 | i = mutex_lock_interruptible(&dev->mutex); | 216 | i = mutex_lock_interruptible(&dev->bus_mutex); |
217 | if (i != 0) | 217 | if (i != 0) |
218 | return i; | 218 | return i; |
219 | } else if (!w1_strong_pullup) { | 219 | } else if (!w1_strong_pullup) { |
220 | sleep_rem = msleep_interruptible(tm); | 220 | sleep_rem = msleep_interruptible(tm); |
221 | if (sleep_rem != 0) { | 221 | if (sleep_rem != 0) { |
222 | mutex_unlock(&dev->mutex); | 222 | mutex_unlock(&dev->bus_mutex); |
223 | return -EINTR; | 223 | return -EINTR; |
224 | } | 224 | } |
225 | } | 225 | } |
@@ -258,7 +258,7 @@ static ssize_t w1_therm_read(struct device *device, | |||
258 | 258 | ||
259 | c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n", | 259 | c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n", |
260 | w1_convert_temp(rom, sl->family->fid)); | 260 | w1_convert_temp(rom, sl->family->fid)); |
261 | mutex_unlock(&dev->mutex); | 261 | mutex_unlock(&dev->bus_mutex); |
262 | 262 | ||
263 | return PAGE_SIZE - c; | 263 | return PAGE_SIZE - c; |
264 | } | 264 | } |
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 2f2e894ea0c8..1a574370d2cd 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c | |||
@@ -557,7 +557,7 @@ static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
557 | struct w1_master *md = NULL; | 557 | struct w1_master *md = NULL; |
558 | struct w1_slave *sl = NULL; | 558 | struct w1_slave *sl = NULL; |
559 | char *event_owner, *name; | 559 | char *event_owner, *name; |
560 | int err; | 560 | int err = 0; |
561 | 561 | ||
562 | if (dev->driver == &w1_master_driver) { | 562 | if (dev->driver == &w1_master_driver) { |
563 | md = container_of(dev, struct w1_master, dev); | 563 | md = container_of(dev, struct w1_master, dev); |
@@ -576,19 +576,17 @@ static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
576 | event_owner, name, dev_name(dev)); | 576 | event_owner, name, dev_name(dev)); |
577 | 577 | ||
578 | if (dev->driver != &w1_slave_driver || !sl) | 578 | if (dev->driver != &w1_slave_driver || !sl) |
579 | return 0; | 579 | goto end; |
580 | 580 | ||
581 | err = add_uevent_var(env, "W1_FID=%02X", sl->reg_num.family); | 581 | err = add_uevent_var(env, "W1_FID=%02X", sl->reg_num.family); |
582 | if (err) | 582 | if (err) |
583 | return err; | 583 | goto end; |
584 | 584 | ||
585 | err = add_uevent_var(env, "W1_SLAVE_ID=%024LX", | 585 | err = add_uevent_var(env, "W1_SLAVE_ID=%024LX", |
586 | (unsigned long long)sl->reg_num.id); | 586 | (unsigned long long)sl->reg_num.id); |
587 | if (err) | 587 | end: |
588 | return err; | 588 | return err; |
589 | 589 | } | |
590 | return 0; | ||
591 | }; | ||
592 | #else | 590 | #else |
593 | static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) | 591 | static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) |
594 | { | 592 | { |
@@ -887,16 +885,21 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb | |||
887 | * | 885 | * |
888 | * Return 0 - device(s) present, 1 - no devices present. | 886 | * Return 0 - device(s) present, 1 - no devices present. |
889 | */ | 887 | */ |
888 | mutex_lock(&dev->bus_mutex); | ||
890 | if (w1_reset_bus(dev)) { | 889 | if (w1_reset_bus(dev)) { |
890 | mutex_unlock(&dev->bus_mutex); | ||
891 | dev_dbg(&dev->dev, "No devices present on the wire.\n"); | 891 | dev_dbg(&dev->dev, "No devices present on the wire.\n"); |
892 | break; | 892 | break; |
893 | } | 893 | } |
894 | 894 | ||
895 | /* Do fast search on single slave bus */ | 895 | /* Do fast search on single slave bus */ |
896 | if (dev->max_slave_count == 1) { | 896 | if (dev->max_slave_count == 1) { |
897 | int rv; | ||
897 | w1_write_8(dev, W1_READ_ROM); | 898 | w1_write_8(dev, W1_READ_ROM); |
899 | rv = w1_read_block(dev, (u8 *)&rn, 8); | ||
900 | mutex_unlock(&dev->bus_mutex); | ||
898 | 901 | ||
899 | if (w1_read_block(dev, (u8 *)&rn, 8) == 8 && rn) | 902 | if (rv == 8 && rn) |
900 | cb(dev, rn); | 903 | cb(dev, rn); |
901 | 904 | ||
902 | break; | 905 | break; |
@@ -929,10 +932,12 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb | |||
929 | rn |= (tmp64 << i); | 932 | rn |= (tmp64 << i); |
930 | 933 | ||
931 | if (kthread_should_stop()) { | 934 | if (kthread_should_stop()) { |
935 | mutex_unlock(&dev->bus_mutex); | ||
932 | dev_dbg(&dev->dev, "Abort w1_search\n"); | 936 | dev_dbg(&dev->dev, "Abort w1_search\n"); |
933 | return; | 937 | return; |
934 | } | 938 | } |
935 | } | 939 | } |
940 | mutex_unlock(&dev->bus_mutex); | ||
936 | 941 | ||
937 | if ( (triplet_ret & 0x03) != 0x03 ) { | 942 | if ( (triplet_ret & 0x03) != 0x03 ) { |
938 | if ( (desc_bit == last_zero) || (last_zero < 0)) | 943 | if ( (desc_bit == last_zero) || (last_zero < 0)) |
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h index 4d012ca3f32c..45908e56c2f8 100644 --- a/drivers/w1/w1.h +++ b/drivers/w1/w1.h | |||
@@ -180,6 +180,7 @@ struct w1_master | |||
180 | 180 | ||
181 | struct task_struct *thread; | 181 | struct task_struct *thread; |
182 | struct mutex mutex; | 182 | struct mutex mutex; |
183 | struct mutex bus_mutex; | ||
183 | 184 | ||
184 | struct device_driver *driver; | 185 | struct device_driver *driver; |
185 | struct device dev; | 186 | struct device dev; |
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h index 874aeb05011b..b00ada44a89b 100644 --- a/drivers/w1/w1_family.h +++ b/drivers/w1/w1_family.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #define W1_FAMILY_SMEM_01 0x01 | 30 | #define W1_FAMILY_SMEM_01 0x01 |
31 | #define W1_FAMILY_SMEM_81 0x81 | 31 | #define W1_FAMILY_SMEM_81 0x81 |
32 | #define W1_THERM_DS18S20 0x10 | 32 | #define W1_THERM_DS18S20 0x10 |
33 | #define W1_FAMILY_DS28E04 0x1C | ||
33 | #define W1_COUNTER_DS2423 0x1D | 34 | #define W1_COUNTER_DS2423 0x1D |
34 | #define W1_THERM_DS1822 0x22 | 35 | #define W1_THERM_DS1822 0x22 |
35 | #define W1_EEPROM_DS2433 0x23 | 36 | #define W1_EEPROM_DS2433 0x23 |
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index 68288355727a..5a98649f6abc 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c | |||
@@ -76,6 +76,7 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl, | |||
76 | 76 | ||
77 | INIT_LIST_HEAD(&dev->slist); | 77 | INIT_LIST_HEAD(&dev->slist); |
78 | mutex_init(&dev->mutex); | 78 | mutex_init(&dev->mutex); |
79 | mutex_init(&dev->bus_mutex); | ||
79 | 80 | ||
80 | memcpy(&dev->dev, device, sizeof(struct device)); | 81 | memcpy(&dev->dev, device, sizeof(struct device)); |
81 | dev_set_name(&dev->dev, "w1_bus_master%u", dev->id); | 82 | dev_set_name(&dev->dev, "w1_bus_master%u", dev->id); |
@@ -117,7 +118,7 @@ int w1_add_master_device(struct w1_bus_master *master) | |||
117 | return(-EINVAL); | 118 | return(-EINVAL); |
118 | } | 119 | } |
119 | /* While it would be electrically possible to make a device that | 120 | /* While it would be electrically possible to make a device that |
120 | * generated a strong pullup in bit bang mode, only hardare that | 121 | * generated a strong pullup in bit bang mode, only hardware that |
121 | * controls 1-wire time frames are even expected to support a strong | 122 | * controls 1-wire time frames are even expected to support a strong |
122 | * pullup. w1_io.c would need to support calling set_pullup before | 123 | * pullup. w1_io.c would need to support calling set_pullup before |
123 | * the last write_bit operation of a w1_write_8 which it currently | 124 | * the last write_bit operation of a w1_write_8 which it currently |
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index b80bc846a15a..0de5e26870c3 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -498,7 +498,7 @@ void debugfs_remove(struct dentry *dentry) | |||
498 | struct dentry *parent; | 498 | struct dentry *parent; |
499 | int ret; | 499 | int ret; |
500 | 500 | ||
501 | if (!dentry) | 501 | if (IS_ERR_OR_NULL(dentry)) |
502 | return; | 502 | return; |
503 | 503 | ||
504 | parent = dentry->d_parent; | 504 | parent = dentry->d_parent; |
@@ -530,7 +530,7 @@ void debugfs_remove_recursive(struct dentry *dentry) | |||
530 | struct dentry *child; | 530 | struct dentry *child; |
531 | struct dentry *parent; | 531 | struct dentry *parent; |
532 | 532 | ||
533 | if (!dentry) | 533 | if (IS_ERR_OR_NULL(dentry)) |
534 | return; | 534 | return; |
535 | 535 | ||
536 | parent = dentry->d_parent; | 536 | parent = dentry->d_parent; |
diff --git a/include/linux/device.h b/include/linux/device.h index 161d96241b1b..5c4495c8fe3f 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -689,6 +689,11 @@ struct device { | |||
689 | void (*release)(struct device *dev); | 689 | void (*release)(struct device *dev); |
690 | }; | 690 | }; |
691 | 691 | ||
692 | static inline struct device *kobj_to_dev(struct kobject *kobj) | ||
693 | { | ||
694 | return container_of(kobj, struct device, kobj); | ||
695 | } | ||
696 | |||
692 | /* Get the wakeup routines, which depend on struct device */ | 697 | /* Get the wakeup routines, which depend on struct device */ |
693 | #include <linux/pm_wakeup.h> | 698 | #include <linux/pm_wakeup.h> |
694 | 699 | ||
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 017a7fb5a1fc..ae0aaa9d42fa 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -16,7 +16,6 @@ | |||
16 | 16 | ||
17 | #ifdef CONFIG_BLOCK | 17 | #ifdef CONFIG_BLOCK |
18 | 18 | ||
19 | #define kobj_to_dev(k) container_of((k), struct device, kobj) | ||
20 | #define dev_to_disk(device) container_of((device), struct gendisk, part0.__dev) | 19 | #define dev_to_disk(device) container_of((device), struct gendisk, part0.__dev) |
21 | #define dev_to_part(device) container_of((device), struct hd_struct, __dev) | 20 | #define dev_to_part(device) container_of((device), struct hd_struct, __dev) |
22 | #define disk_to_dev(disk) (&(disk)->part0.__dev) | 21 | #define disk_to_dev(disk) (&(disk)->part0.__dev) |