diff options
47 files changed, 2159 insertions, 227 deletions
diff --git a/Documentation/ABI/stable/sysfs-driver-w1_ds28e04 b/Documentation/ABI/stable/sysfs-driver-w1_ds28e04 new file mode 100644 index 00000000000..26579ee868c --- /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/ABI/testing/dev-kmsg b/Documentation/ABI/testing/dev-kmsg index 281ecc5f970..7e7e07a82e0 100644 --- a/Documentation/ABI/testing/dev-kmsg +++ b/Documentation/ABI/testing/dev-kmsg | |||
@@ -58,16 +58,18 @@ Description: The /dev/kmsg character device node provides userspace access | |||
58 | 58 | ||
59 | The output format consists of a prefix carrying the syslog | 59 | The output format consists of a prefix carrying the syslog |
60 | prefix including priority and facility, the 64 bit message | 60 | prefix including priority and facility, the 64 bit message |
61 | sequence number and the monotonic timestamp in microseconds. | 61 | sequence number and the monotonic timestamp in microseconds, |
62 | The values are separated by a ','. Future extensions might | 62 | and a flag field. All fields are separated by a ','. |
63 | add more comma separated values before the terminating ';'. | 63 | |
64 | Unknown values should be gracefully ignored. | 64 | Future extensions might add more comma separated values before |
65 | the terminating ';'. Unknown fields and values should be | ||
66 | gracefully ignored. | ||
65 | 67 | ||
66 | The human readable text string starts directly after the ';' | 68 | The human readable text string starts directly after the ';' |
67 | and is terminated by a '\n'. Untrusted values derived from | 69 | and is terminated by a '\n'. Untrusted values derived from |
68 | hardware or other facilities are printed, therefore | 70 | hardware or other facilities are printed, therefore |
69 | all non-printable characters in the log message are escaped | 71 | all non-printable characters and '\' itself in the log message |
70 | by "\x00" C-style hex encoding. | 72 | are escaped by "\x00" C-style hex encoding. |
71 | 73 | ||
72 | A line starting with ' ', is a continuation line, adding | 74 | A line starting with ' ', is a continuation line, adding |
73 | key/value pairs to the log message, which provide the machine | 75 | key/value pairs to the log message, which provide the machine |
@@ -75,11 +77,11 @@ Description: The /dev/kmsg character device node provides userspace access | |||
75 | userspace. | 77 | userspace. |
76 | 78 | ||
77 | Example: | 79 | Example: |
78 | 7,160,424069;pci_root PNP0A03:00: host bridge window [io 0x0000-0x0cf7] (ignored) | 80 | 7,160,424069,-;pci_root PNP0A03:00: host bridge window [io 0x0000-0x0cf7] (ignored) |
79 | SUBSYSTEM=acpi | 81 | SUBSYSTEM=acpi |
80 | DEVICE=+acpi:PNP0A03:00 | 82 | DEVICE=+acpi:PNP0A03:00 |
81 | 6,339,5140900;NET: Registered protocol family 10 | 83 | 6,339,5140900,-;NET: Registered protocol family 10 |
82 | 30,340,5690716;udevd[80]: starting version 181 | 84 | 30,340,5690716,-;udevd[80]: starting version 181 |
83 | 85 | ||
84 | The DEVICE= key uniquely identifies devices the following way: | 86 | The DEVICE= key uniquely identifies devices the following way: |
85 | b12:8 - block dev_t | 87 | b12:8 - block dev_t |
@@ -87,4 +89,13 @@ Description: The /dev/kmsg character device node provides userspace access | |||
87 | n8 - netdev ifindex | 89 | n8 - netdev ifindex |
88 | +sound:card0 - subsystem:devname | 90 | +sound:card0 - subsystem:devname |
89 | 91 | ||
92 | The flags field carries '-' by default. A 'c' indicates a | ||
93 | fragment of a line. All following fragments are flagged with | ||
94 | '+'. Note, that these hints about continuation lines are not | ||
95 | neccessarily correct, and the stream could be interleaved with | ||
96 | unrelated messages, but merging the lines in the output | ||
97 | usually produces better human readable results. A similar | ||
98 | logic is used internally when messages are printed to the | ||
99 | console, /proc/kmsg or the syslog() syscall. | ||
100 | |||
90 | Users: dmesg(1), userspace kernel log consumers | 101 | Users: dmesg(1), userspace kernel log consumers |
diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt index 4a7b54bd37e..b0714d8f678 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 00000000000..85bc9a7e02f --- /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 9b8a5daaf40..429e72cc13f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2728,6 +2728,14 @@ M: Mimi Zohar <zohar@us.ibm.com> | |||
2728 | S: Supported | 2728 | S: Supported |
2729 | F: security/integrity/evm/ | 2729 | F: security/integrity/evm/ |
2730 | 2730 | ||
2731 | EXTERNAL CONNECTOR SUBSYSTEM (EXTCON) | ||
2732 | M: MyungJoo Ham <myungjoo.ham@samsung.com> | ||
2733 | M: Chanwoo Choi <cw00.choi@samsung.com> | ||
2734 | L: linux-kernel@vger.kernel.org | ||
2735 | S: Maintained | ||
2736 | F: drivers/extcon/ | ||
2737 | F: Documentation/extcon/ | ||
2738 | |||
2731 | EXYNOS DP DRIVER | 2739 | EXYNOS DP DRIVER |
2732 | M: Jingoo Han <jg1.han@samsung.com> | 2740 | M: Jingoo Han <jg1.han@samsung.com> |
2733 | L: linux-fbdev@vger.kernel.org | 2741 | L: linux-fbdev@vger.kernel.org |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 2bcef657a60..181ed2660b3 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 346be8b78b2..f338037a4f3 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 dcb8a6e4869..e3bbed8a617 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 */ |
@@ -356,10 +369,9 @@ int driver_probe_device(struct device_driver *drv, struct device *dev) | |||
356 | pr_debug("bus: '%s': %s: matched device %s with driver %s\n", | 369 | pr_debug("bus: '%s': %s: matched device %s with driver %s\n", |
357 | drv->bus->name, __func__, dev_name(dev), drv->name); | 370 | drv->bus->name, __func__, dev_name(dev), drv->name); |
358 | 371 | ||
359 | pm_runtime_get_noresume(dev); | ||
360 | pm_runtime_barrier(dev); | 372 | pm_runtime_barrier(dev); |
361 | ret = really_probe(dev, drv); | 373 | ret = really_probe(dev, drv); |
362 | pm_runtime_put_sync(dev); | 374 | pm_runtime_idle(dev); |
363 | 375 | ||
364 | return ret; | 376 | return ret; |
365 | } | 377 | } |
@@ -406,9 +418,8 @@ int device_attach(struct device *dev) | |||
406 | ret = 0; | 418 | ret = 0; |
407 | } | 419 | } |
408 | } else { | 420 | } else { |
409 | pm_runtime_get_noresume(dev); | ||
410 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); | 421 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); |
411 | pm_runtime_put_sync(dev); | 422 | pm_runtime_idle(dev); |
412 | } | 423 | } |
413 | out_unlock: | 424 | out_unlock: |
414 | device_unlock(dev); | 425 | device_unlock(dev); |
@@ -487,6 +498,7 @@ static void __device_release_driver(struct device *dev) | |||
487 | drv->remove(dev); | 498 | drv->remove(dev); |
488 | devres_release_all(dev); | 499 | devres_release_all(dev); |
489 | dev->driver = NULL; | 500 | dev->driver = NULL; |
501 | dev_set_drvdata(dev, NULL); | ||
490 | klist_remove(&dev->p->knode_driver); | 502 | klist_remove(&dev->p->knode_driver); |
491 | if (dev->bus) | 503 | if (dev->bus) |
492 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, | 504 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 24e88fe29ec..c30f3e1d0ef 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 1b85949e3d2..560a7173f81 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 207c27ddf82..974e301a1ef 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -185,8 +185,12 @@ int driver_register(struct device_driver *drv) | |||
185 | if (ret) | 185 | if (ret) |
186 | return ret; | 186 | return ret; |
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 | return ret; | ||
191 | } | ||
192 | kobject_uevent(&drv->p->kobj, KOBJ_ADD); | ||
193 | |||
190 | return ret; | 194 | return ret; |
191 | } | 195 | } |
192 | EXPORT_SYMBOL_GPL(driver_register); | 196 | EXPORT_SYMBOL_GPL(driver_register); |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 5401814c874..803cfc1597a 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 29c5cf852ef..16716356d1f 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig | |||
@@ -21,6 +21,16 @@ config EXTCON_GPIO | |||
21 | Say Y here to enable GPIO based extcon support. Note that GPIO | 21 | Say Y here to enable GPIO based extcon support. Note that GPIO |
22 | extcon supports single state per extcon instance. | 22 | extcon supports single state per extcon instance. |
23 | 23 | ||
24 | config EXTCON_MAX77693 | ||
25 | tristate "MAX77693 EXTCON Support" | ||
26 | depends on MFD_MAX77693 | ||
27 | select IRQ_DOMAIN | ||
28 | select REGMAP_I2C | ||
29 | help | ||
30 | If you say yes here you get support for the MUIC device of | ||
31 | Maxim MAX77693 PMIC. The MAX77693 MUIC is a USB port accessory | ||
32 | detector and switch. | ||
33 | |||
24 | config EXTCON_MAX8997 | 34 | config EXTCON_MAX8997 |
25 | tristate "MAX8997 EXTCON Support" | 35 | tristate "MAX8997 EXTCON Support" |
26 | depends on MFD_MAX8997 | 36 | depends on MFD_MAX8997 |
@@ -29,4 +39,12 @@ config EXTCON_MAX8997 | |||
29 | Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory | 39 | Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory |
30 | detector and switch. | 40 | detector and switch. |
31 | 41 | ||
42 | config EXTCON_ARIZONA | ||
43 | tristate "Wolfson Arizona EXTCON support" | ||
44 | depends on MFD_ARIZONA | ||
45 | help | ||
46 | Say Y here to enable support for external accessory detection | ||
47 | with Wolfson Arizona devices. These are audio CODECs with | ||
48 | advanced audio accessory detection support. | ||
49 | |||
32 | endif # MULTISTATE_SWITCH | 50 | endif # MULTISTATE_SWITCH |
diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile index 86020bdb6da..88961b33234 100644 --- a/drivers/extcon/Makefile +++ b/drivers/extcon/Makefile | |||
@@ -4,4 +4,6 @@ | |||
4 | 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_MAX77693) += extcon-max77693.o | ||
7 | obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o | 8 | obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o |
9 | 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 00000000000..427a289f32a --- /dev/null +++ b/drivers/extcon/extcon-arizona.c | |||
@@ -0,0 +1,490 @@ | |||
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 0 | ||
58 | #define ARIZONA_CABLE_MICROPHONE 1 | ||
59 | #define ARIZONA_CABLE_HEADPHONE 2 | ||
60 | |||
61 | static const char *arizona_cable[] = { | ||
62 | "Mechanical", | ||
63 | "Microphone", | ||
64 | "Headphone", | ||
65 | NULL, | ||
66 | }; | ||
67 | |||
68 | static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode) | ||
69 | { | ||
70 | struct arizona *arizona = info->arizona; | ||
71 | |||
72 | gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio, | ||
73 | info->micd_modes[mode].gpio); | ||
74 | regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, | ||
75 | ARIZONA_MICD_BIAS_SRC_MASK, | ||
76 | info->micd_modes[mode].bias); | ||
77 | regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1, | ||
78 | ARIZONA_ACCDET_SRC, info->micd_modes[mode].src); | ||
79 | |||
80 | info->micd_mode = mode; | ||
81 | |||
82 | dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode); | ||
83 | } | ||
84 | |||
85 | static void arizona_start_mic(struct arizona_extcon_info *info) | ||
86 | { | ||
87 | struct arizona *arizona = info->arizona; | ||
88 | bool change; | ||
89 | int ret; | ||
90 | |||
91 | info->detecting = true; | ||
92 | info->mic = false; | ||
93 | info->jack_flips = 0; | ||
94 | |||
95 | /* Microphone detection can't use idle mode */ | ||
96 | pm_runtime_get(info->dev); | ||
97 | |||
98 | ret = regulator_enable(info->micvdd); | ||
99 | if (ret != 0) { | ||
100 | dev_err(arizona->dev, "Failed to enable MICVDD: %d\n", | ||
101 | ret); | ||
102 | } | ||
103 | |||
104 | if (info->micd_reva) { | ||
105 | regmap_write(arizona->regmap, 0x80, 0x3); | ||
106 | regmap_write(arizona->regmap, 0x294, 0); | ||
107 | regmap_write(arizona->regmap, 0x80, 0x0); | ||
108 | } | ||
109 | |||
110 | regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, | ||
111 | ARIZONA_MICD_ENA, ARIZONA_MICD_ENA, | ||
112 | &change); | ||
113 | if (!change) { | ||
114 | regulator_disable(info->micvdd); | ||
115 | pm_runtime_put_autosuspend(info->dev); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | static void arizona_stop_mic(struct arizona_extcon_info *info) | ||
120 | { | ||
121 | struct arizona *arizona = info->arizona; | ||
122 | bool change; | ||
123 | |||
124 | regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, | ||
125 | ARIZONA_MICD_ENA, 0, | ||
126 | &change); | ||
127 | |||
128 | if (info->micd_reva) { | ||
129 | regmap_write(arizona->regmap, 0x80, 0x3); | ||
130 | regmap_write(arizona->regmap, 0x294, 2); | ||
131 | regmap_write(arizona->regmap, 0x80, 0x0); | ||
132 | } | ||
133 | |||
134 | if (change) { | ||
135 | regulator_disable(info->micvdd); | ||
136 | pm_runtime_put_autosuspend(info->dev); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | static irqreturn_t arizona_micdet(int irq, void *data) | ||
141 | { | ||
142 | struct arizona_extcon_info *info = data; | ||
143 | struct arizona *arizona = info->arizona; | ||
144 | unsigned int val; | ||
145 | int ret; | ||
146 | |||
147 | mutex_lock(&info->lock); | ||
148 | |||
149 | ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); | ||
150 | if (ret != 0) { | ||
151 | dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); | ||
152 | return IRQ_NONE; | ||
153 | } | ||
154 | |||
155 | dev_dbg(arizona->dev, "MICDET: %x\n", val); | ||
156 | |||
157 | if (!(val & ARIZONA_MICD_VALID)) { | ||
158 | dev_warn(arizona->dev, "Microphone detection state invalid\n"); | ||
159 | mutex_unlock(&info->lock); | ||
160 | return IRQ_NONE; | ||
161 | } | ||
162 | |||
163 | /* Due to jack detect this should never happen */ | ||
164 | if (!(val & ARIZONA_MICD_STS)) { | ||
165 | dev_warn(arizona->dev, "Detected open circuit\n"); | ||
166 | info->detecting = false; | ||
167 | goto handled; | ||
168 | } | ||
169 | |||
170 | /* If we got a high impedence we should have a headset, report it. */ | ||
171 | if (info->detecting && (val & 0x400)) { | ||
172 | ret = extcon_update_state(&info->edev, | ||
173 | 1 << ARIZONA_CABLE_MICROPHONE | | ||
174 | 1 << ARIZONA_CABLE_HEADPHONE, | ||
175 | 1 << ARIZONA_CABLE_MICROPHONE | | ||
176 | 1 << ARIZONA_CABLE_HEADPHONE); | ||
177 | |||
178 | if (ret != 0) | ||
179 | dev_err(arizona->dev, "Headset report failed: %d\n", | ||
180 | ret); | ||
181 | |||
182 | info->mic = true; | ||
183 | info->detecting = false; | ||
184 | goto handled; | ||
185 | } | ||
186 | |||
187 | /* If we detected a lower impedence during initial startup | ||
188 | * then we probably have the wrong polarity, flip it. Don't | ||
189 | * do this for the lowest impedences to speed up detection of | ||
190 | * plain headphones. If both polarities report a low | ||
191 | * impedence then give up and report headphones. | ||
192 | */ | ||
193 | if (info->detecting && (val & 0x3f8)) { | ||
194 | info->jack_flips++; | ||
195 | |||
196 | if (info->jack_flips >= info->micd_num_modes) { | ||
197 | dev_dbg(arizona->dev, "Detected headphone\n"); | ||
198 | info->detecting = false; | ||
199 | arizona_stop_mic(info); | ||
200 | |||
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 | |||
351 | ret = extcon_dev_register(&info->edev, arizona->dev); | ||
352 | if (ret < 0) { | ||
353 | dev_err(arizona->dev, "extcon_dev_regster() failed: %d\n", | ||
354 | ret); | ||
355 | goto err; | ||
356 | } | ||
357 | |||
358 | if (pdata->num_micd_configs) { | ||
359 | info->micd_modes = pdata->micd_configs; | ||
360 | info->micd_num_modes = pdata->num_micd_configs; | ||
361 | } else { | ||
362 | info->micd_modes = micd_default_modes; | ||
363 | info->micd_num_modes = ARRAY_SIZE(micd_default_modes); | ||
364 | } | ||
365 | |||
366 | if (arizona->pdata.micd_pol_gpio > 0) { | ||
367 | if (info->micd_modes[0].gpio) | ||
368 | mode = GPIOF_OUT_INIT_HIGH; | ||
369 | else | ||
370 | mode = GPIOF_OUT_INIT_LOW; | ||
371 | |||
372 | ret = devm_gpio_request_one(&pdev->dev, | ||
373 | arizona->pdata.micd_pol_gpio, | ||
374 | mode, | ||
375 | "MICD polarity"); | ||
376 | if (ret != 0) { | ||
377 | dev_err(arizona->dev, "Failed to request GPIO%d: %d\n", | ||
378 | arizona->pdata.micd_pol_gpio, ret); | ||
379 | goto err_register; | ||
380 | } | ||
381 | } | ||
382 | |||
383 | arizona_extcon_set_mode(info, 0); | ||
384 | |||
385 | pm_runtime_enable(&pdev->dev); | ||
386 | pm_runtime_idle(&pdev->dev); | ||
387 | pm_runtime_get_sync(&pdev->dev); | ||
388 | |||
389 | ret = arizona_request_irq(arizona, ARIZONA_IRQ_JD_RISE, | ||
390 | "JACKDET rise", arizona_jackdet, info); | ||
391 | if (ret != 0) { | ||
392 | dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n", | ||
393 | ret); | ||
394 | goto err_register; | ||
395 | } | ||
396 | |||
397 | ret = arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 1); | ||
398 | if (ret != 0) { | ||
399 | dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n", | ||
400 | ret); | ||
401 | goto err_rise; | ||
402 | } | ||
403 | |||
404 | ret = arizona_request_irq(arizona, ARIZONA_IRQ_JD_FALL, | ||
405 | "JACKDET fall", arizona_jackdet, info); | ||
406 | if (ret != 0) { | ||
407 | dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret); | ||
408 | goto err_rise_wake; | ||
409 | } | ||
410 | |||
411 | ret = arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 1); | ||
412 | if (ret != 0) { | ||
413 | dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n", | ||
414 | ret); | ||
415 | goto err_fall; | ||
416 | } | ||
417 | |||
418 | ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET, | ||
419 | "MICDET", arizona_micdet, info); | ||
420 | if (ret != 0) { | ||
421 | dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret); | ||
422 | goto err_fall_wake; | ||
423 | } | ||
424 | |||
425 | regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, | ||
426 | ARIZONA_MICD_BIAS_STARTTIME_MASK | | ||
427 | ARIZONA_MICD_RATE_MASK, | ||
428 | 7 << ARIZONA_MICD_BIAS_STARTTIME_SHIFT | | ||
429 | 8 << ARIZONA_MICD_RATE_SHIFT); | ||
430 | |||
431 | arizona_clk32k_enable(arizona); | ||
432 | regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE, | ||
433 | ARIZONA_JD1_DB, ARIZONA_JD1_DB); | ||
434 | regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, | ||
435 | ARIZONA_JD1_ENA, ARIZONA_JD1_ENA); | ||
436 | |||
437 | pm_runtime_put(&pdev->dev); | ||
438 | |||
439 | return 0; | ||
440 | |||
441 | err_fall_wake: | ||
442 | arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 0); | ||
443 | err_fall: | ||
444 | arizona_free_irq(arizona, ARIZONA_IRQ_JD_FALL, info); | ||
445 | err_rise_wake: | ||
446 | arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 0); | ||
447 | err_rise: | ||
448 | arizona_free_irq(arizona, ARIZONA_IRQ_JD_RISE, info); | ||
449 | err_register: | ||
450 | pm_runtime_disable(&pdev->dev); | ||
451 | extcon_dev_unregister(&info->edev); | ||
452 | err: | ||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | static int __devexit arizona_extcon_remove(struct platform_device *pdev) | ||
457 | { | ||
458 | struct arizona_extcon_info *info = platform_get_drvdata(pdev); | ||
459 | struct arizona *arizona = info->arizona; | ||
460 | |||
461 | pm_runtime_disable(&pdev->dev); | ||
462 | |||
463 | arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 0); | ||
464 | arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 0); | ||
465 | arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info); | ||
466 | arizona_free_irq(arizona, ARIZONA_IRQ_JD_RISE, info); | ||
467 | arizona_free_irq(arizona, ARIZONA_IRQ_JD_FALL, info); | ||
468 | regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, | ||
469 | ARIZONA_JD1_ENA, 0); | ||
470 | arizona_clk32k_disable(arizona); | ||
471 | extcon_dev_unregister(&info->edev); | ||
472 | |||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static struct platform_driver arizona_extcon_driver = { | ||
477 | .driver = { | ||
478 | .name = "arizona-extcon", | ||
479 | .owner = THIS_MODULE, | ||
480 | }, | ||
481 | .probe = arizona_extcon_probe, | ||
482 | .remove = __devexit_p(arizona_extcon_remove), | ||
483 | }; | ||
484 | |||
485 | module_platform_driver(arizona_extcon_driver); | ||
486 | |||
487 | MODULE_DESCRIPTION("Arizona Extcon driver"); | ||
488 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
489 | MODULE_LICENSE("GPL"); | ||
490 | MODULE_ALIAS("platform:extcon-arizona"); | ||
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c new file mode 100644 index 00000000000..920a609b2c3 --- /dev/null +++ b/drivers/extcon/extcon-max77693.c | |||
@@ -0,0 +1,779 @@ | |||
1 | /* | ||
2 | * extcon-max77693.c - MAX77693 extcon driver to support MAX77693 MUIC | ||
3 | * | ||
4 | * Copyright (C) 2012 Samsung Electrnoics | ||
5 | * Chanwoo Choi <cw00.choi@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/err.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/mfd/max77693.h> | ||
26 | #include <linux/mfd/max77693-private.h> | ||
27 | #include <linux/extcon.h> | ||
28 | #include <linux/regmap.h> | ||
29 | #include <linux/irqdomain.h> | ||
30 | |||
31 | #define DEV_NAME "max77693-muic" | ||
32 | |||
33 | /* MAX77693 MUIC - STATUS1~3 Register */ | ||
34 | #define STATUS1_ADC_SHIFT (0) | ||
35 | #define STATUS1_ADCLOW_SHIFT (5) | ||
36 | #define STATUS1_ADCERR_SHIFT (6) | ||
37 | #define STATUS1_ADC1K_SHIFT (7) | ||
38 | #define STATUS1_ADC_MASK (0x1f << STATUS1_ADC_SHIFT) | ||
39 | #define STATUS1_ADCLOW_MASK (0x1 << STATUS1_ADCLOW_SHIFT) | ||
40 | #define STATUS1_ADCERR_MASK (0x1 << STATUS1_ADCERR_SHIFT) | ||
41 | #define STATUS1_ADC1K_MASK (0x1 << STATUS1_ADC1K_SHIFT) | ||
42 | |||
43 | #define STATUS2_CHGTYP_SHIFT (0) | ||
44 | #define STATUS2_CHGDETRUN_SHIFT (3) | ||
45 | #define STATUS2_DCDTMR_SHIFT (4) | ||
46 | #define STATUS2_DXOVP_SHIFT (5) | ||
47 | #define STATUS2_VBVOLT_SHIFT (6) | ||
48 | #define STATUS2_VIDRM_SHIFT (7) | ||
49 | #define STATUS2_CHGTYP_MASK (0x7 << STATUS2_CHGTYP_SHIFT) | ||
50 | #define STATUS2_CHGDETRUN_MASK (0x1 << STATUS2_CHGDETRUN_SHIFT) | ||
51 | #define STATUS2_DCDTMR_MASK (0x1 << STATUS2_DCDTMR_SHIFT) | ||
52 | #define STATUS2_DXOVP_MASK (0x1 << STATUS2_DXOVP_SHIFT) | ||
53 | #define STATUS2_VBVOLT_MASK (0x1 << STATUS2_VBVOLT_SHIFT) | ||
54 | #define STATUS2_VIDRM_MASK (0x1 << STATUS2_VIDRM_SHIFT) | ||
55 | |||
56 | #define STATUS3_OVP_SHIFT (2) | ||
57 | #define STATUS3_OVP_MASK (0x1 << STATUS3_OVP_SHIFT) | ||
58 | |||
59 | /* MAX77693 CDETCTRL1~2 register */ | ||
60 | #define CDETCTRL1_CHGDETEN_SHIFT (0) | ||
61 | #define CDETCTRL1_CHGTYPMAN_SHIFT (1) | ||
62 | #define CDETCTRL1_DCDEN_SHIFT (2) | ||
63 | #define CDETCTRL1_DCD2SCT_SHIFT (3) | ||
64 | #define CDETCTRL1_CDDELAY_SHIFT (4) | ||
65 | #define CDETCTRL1_DCDCPL_SHIFT (5) | ||
66 | #define CDETCTRL1_CDPDET_SHIFT (7) | ||
67 | #define CDETCTRL1_CHGDETEN_MASK (0x1 << CDETCTRL1_CHGDETEN_SHIFT) | ||
68 | #define CDETCTRL1_CHGTYPMAN_MASK (0x1 << CDETCTRL1_CHGTYPMAN_SHIFT) | ||
69 | #define CDETCTRL1_DCDEN_MASK (0x1 << CDETCTRL1_DCDEN_SHIFT) | ||
70 | #define CDETCTRL1_DCD2SCT_MASK (0x1 << CDETCTRL1_DCD2SCT_SHIFT) | ||
71 | #define CDETCTRL1_CDDELAY_MASK (0x1 << CDETCTRL1_CDDELAY_SHIFT) | ||
72 | #define CDETCTRL1_DCDCPL_MASK (0x1 << CDETCTRL1_DCDCPL_SHIFT) | ||
73 | #define CDETCTRL1_CDPDET_MASK (0x1 << CDETCTRL1_CDPDET_SHIFT) | ||
74 | |||
75 | #define CDETCTRL2_VIDRMEN_SHIFT (1) | ||
76 | #define CDETCTRL2_DXOVPEN_SHIFT (3) | ||
77 | #define CDETCTRL2_VIDRMEN_MASK (0x1 << CDETCTRL2_VIDRMEN_SHIFT) | ||
78 | #define CDETCTRL2_DXOVPEN_MASK (0x1 << CDETCTRL2_DXOVPEN_SHIFT) | ||
79 | |||
80 | /* MAX77693 MUIC - CONTROL1~3 register */ | ||
81 | #define COMN1SW_SHIFT (0) | ||
82 | #define COMP2SW_SHIFT (3) | ||
83 | #define COMN1SW_MASK (0x7 << COMN1SW_SHIFT) | ||
84 | #define COMP2SW_MASK (0x7 << COMP2SW_SHIFT) | ||
85 | #define COMP_SW_MASK (COMP2SW_MASK | COMN1SW_MASK) | ||
86 | #define CONTROL1_SW_USB ((1 << COMP2SW_SHIFT) \ | ||
87 | | (1 << COMN1SW_SHIFT)) | ||
88 | #define CONTROL1_SW_AUDIO ((2 << COMP2SW_SHIFT) \ | ||
89 | | (2 << COMN1SW_SHIFT)) | ||
90 | #define CONTROL1_SW_UART ((3 << COMP2SW_SHIFT) \ | ||
91 | | (3 << COMN1SW_SHIFT)) | ||
92 | #define CONTROL1_SW_OPEN ((0 << COMP2SW_SHIFT) \ | ||
93 | | (0 << COMN1SW_SHIFT)) | ||
94 | |||
95 | #define CONTROL2_LOWPWR_SHIFT (0) | ||
96 | #define CONTROL2_ADCEN_SHIFT (1) | ||
97 | #define CONTROL2_CPEN_SHIFT (2) | ||
98 | #define CONTROL2_SFOUTASRT_SHIFT (3) | ||
99 | #define CONTROL2_SFOUTORD_SHIFT (4) | ||
100 | #define CONTROL2_ACCDET_SHIFT (5) | ||
101 | #define CONTROL2_USBCPINT_SHIFT (6) | ||
102 | #define CONTROL2_RCPS_SHIFT (7) | ||
103 | #define CONTROL2_LOWPWR_MASK (0x1 << CONTROL2_LOWPWR_SHIFT) | ||
104 | #define CONTROL2_ADCEN_MASK (0x1 << CONTROL2_ADCEN_SHIFT) | ||
105 | #define CONTROL2_CPEN_MASK (0x1 << CONTROL2_CPEN_SHIFT) | ||
106 | #define CONTROL2_SFOUTASRT_MASK (0x1 << CONTROL2_SFOUTASRT_SHIFT) | ||
107 | #define CONTROL2_SFOUTORD_MASK (0x1 << CONTROL2_SFOUTORD_SHIFT) | ||
108 | #define CONTROL2_ACCDET_MASK (0x1 << CONTROL2_ACCDET_SHIFT) | ||
109 | #define CONTROL2_USBCPINT_MASK (0x1 << CONTROL2_USBCPINT_SHIFT) | ||
110 | #define CONTROL2_RCPS_MASK (0x1 << CONTROL2_RCPS_SHIFT) | ||
111 | |||
112 | #define CONTROL3_JIGSET_SHIFT (0) | ||
113 | #define CONTROL3_BTLDSET_SHIFT (2) | ||
114 | #define CONTROL3_ADCDBSET_SHIFT (4) | ||
115 | #define CONTROL3_JIGSET_MASK (0x3 << CONTROL3_JIGSET_SHIFT) | ||
116 | #define CONTROL3_BTLDSET_MASK (0x3 << CONTROL3_BTLDSET_SHIFT) | ||
117 | #define CONTROL3_ADCDBSET_MASK (0x3 << CONTROL3_ADCDBSET_SHIFT) | ||
118 | |||
119 | enum max77693_muic_adc_debounce_time { | ||
120 | ADC_DEBOUNCE_TIME_5MS = 0, | ||
121 | ADC_DEBOUNCE_TIME_10MS, | ||
122 | ADC_DEBOUNCE_TIME_25MS, | ||
123 | ADC_DEBOUNCE_TIME_38_62MS, | ||
124 | }; | ||
125 | |||
126 | struct max77693_muic_info { | ||
127 | struct device *dev; | ||
128 | struct max77693_dev *max77693; | ||
129 | struct extcon_dev *edev; | ||
130 | int prev_adc; | ||
131 | int prev_adc_gnd; | ||
132 | int prev_chg_type; | ||
133 | u8 status[2]; | ||
134 | |||
135 | int irq; | ||
136 | struct work_struct irq_work; | ||
137 | struct mutex mutex; | ||
138 | }; | ||
139 | |||
140 | enum max77693_muic_charger_type { | ||
141 | MAX77693_CHARGER_TYPE_NONE = 0, | ||
142 | MAX77693_CHARGER_TYPE_USB, | ||
143 | MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT, | ||
144 | MAX77693_CHARGER_TYPE_DEDICATED_CHG, | ||
145 | MAX77693_CHARGER_TYPE_APPLE_500MA, | ||
146 | MAX77693_CHARGER_TYPE_APPLE_1A_2A, | ||
147 | MAX77693_CHARGER_TYPE_DEAD_BATTERY = 7, | ||
148 | }; | ||
149 | |||
150 | /** | ||
151 | * struct max77693_muic_irq | ||
152 | * @irq: the index of irq list of MUIC device. | ||
153 | * @name: the name of irq. | ||
154 | * @virq: the virtual irq to use irq domain | ||
155 | */ | ||
156 | struct max77693_muic_irq { | ||
157 | unsigned int irq; | ||
158 | const char *name; | ||
159 | unsigned int virq; | ||
160 | }; | ||
161 | |||
162 | static struct max77693_muic_irq muic_irqs[] = { | ||
163 | { MAX77693_MUIC_IRQ_INT1_ADC, "muic-ADC" }, | ||
164 | { MAX77693_MUIC_IRQ_INT1_ADC_LOW, "muic-ADCLOW" }, | ||
165 | { MAX77693_MUIC_IRQ_INT1_ADC_ERR, "muic-ADCError" }, | ||
166 | { MAX77693_MUIC_IRQ_INT1_ADC1K, "muic-ADC1K" }, | ||
167 | { MAX77693_MUIC_IRQ_INT2_CHGTYP, "muic-CHGTYP" }, | ||
168 | { MAX77693_MUIC_IRQ_INT2_CHGDETREUN, "muic-CHGDETREUN" }, | ||
169 | { MAX77693_MUIC_IRQ_INT2_DCDTMR, "muic-DCDTMR" }, | ||
170 | { MAX77693_MUIC_IRQ_INT2_DXOVP, "muic-DXOVP" }, | ||
171 | { MAX77693_MUIC_IRQ_INT2_VBVOLT, "muic-VBVOLT" }, | ||
172 | { MAX77693_MUIC_IRQ_INT2_VIDRM, "muic-VIDRM" }, | ||
173 | { MAX77693_MUIC_IRQ_INT3_EOC, "muic-EOC" }, | ||
174 | { MAX77693_MUIC_IRQ_INT3_CGMBC, "muic-CGMBC" }, | ||
175 | { MAX77693_MUIC_IRQ_INT3_OVP, "muic-OVP" }, | ||
176 | { MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR, "muic-MBCCHG_ERR" }, | ||
177 | { MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, "muic-CHG_ENABLED" }, | ||
178 | { MAX77693_MUIC_IRQ_INT3_BAT_DET, "muic-BAT_DET" }, | ||
179 | }; | ||
180 | |||
181 | /* Define supported accessory type */ | ||
182 | enum max77693_muic_acc_type { | ||
183 | MAX77693_MUIC_ADC_GROUND = 0x0, | ||
184 | MAX77693_MUIC_ADC_SEND_END_BUTTON, | ||
185 | MAX77693_MUIC_ADC_REMOTE_S1_BUTTON, | ||
186 | MAX77693_MUIC_ADC_REMOTE_S2_BUTTON, | ||
187 | MAX77693_MUIC_ADC_REMOTE_S3_BUTTON, | ||
188 | MAX77693_MUIC_ADC_REMOTE_S4_BUTTON, | ||
189 | MAX77693_MUIC_ADC_REMOTE_S5_BUTTON, | ||
190 | MAX77693_MUIC_ADC_REMOTE_S6_BUTTON, | ||
191 | MAX77693_MUIC_ADC_REMOTE_S7_BUTTON, | ||
192 | MAX77693_MUIC_ADC_REMOTE_S8_BUTTON, | ||
193 | MAX77693_MUIC_ADC_REMOTE_S9_BUTTON, | ||
194 | MAX77693_MUIC_ADC_REMOTE_S10_BUTTON, | ||
195 | MAX77693_MUIC_ADC_REMOTE_S11_BUTTON, | ||
196 | MAX77693_MUIC_ADC_REMOTE_S12_BUTTON, | ||
197 | MAX77693_MUIC_ADC_RESERVED_ACC_1, | ||
198 | MAX77693_MUIC_ADC_RESERVED_ACC_2, | ||
199 | MAX77693_MUIC_ADC_RESERVED_ACC_3, | ||
200 | MAX77693_MUIC_ADC_RESERVED_ACC_4, | ||
201 | MAX77693_MUIC_ADC_RESERVED_ACC_5, | ||
202 | MAX77693_MUIC_ADC_CEA936_AUDIO, | ||
203 | MAX77693_MUIC_ADC_PHONE_POWERED_DEV, | ||
204 | MAX77693_MUIC_ADC_TTY_CONVERTER, | ||
205 | MAX77693_MUIC_ADC_UART_CABLE, | ||
206 | MAX77693_MUIC_ADC_CEA936A_TYPE1_CHG, | ||
207 | MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF, | ||
208 | MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON, | ||
209 | MAX77693_MUIC_ADC_AV_CABLE_NOLOAD, | ||
210 | MAX77693_MUIC_ADC_CEA936A_TYPE2_CHG, | ||
211 | MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF, | ||
212 | MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON, | ||
213 | MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE, | ||
214 | MAX77693_MUIC_ADC_OPEN, | ||
215 | |||
216 | /* The below accessories have same ADC value so ADCLow and | ||
217 | ADC1K bit is used to separate specific accessory */ | ||
218 | MAX77693_MUIC_GND_USB_OTG = 0x100, /* ADC:0x0, ADCLow:0, ADC1K:0 */ | ||
219 | MAX77693_MUIC_GND_AV_CABLE_LOAD = 0x102,/* ADC:0x0, ADCLow:1, ADC1K:0 */ | ||
220 | MAX77693_MUIC_GND_MHL_CABLE = 0x103, /* ADC:0x0, ADCLow:1, ADC1K:1 */ | ||
221 | }; | ||
222 | |||
223 | /* MAX77693 MUIC device support below list of accessories(external connector) */ | ||
224 | const char *max77693_extcon_cable[] = { | ||
225 | [0] = "USB", | ||
226 | [1] = "USB-Host", | ||
227 | [2] = "TA", | ||
228 | [3] = "Fast-charger", | ||
229 | [4] = "Slow-charger", | ||
230 | [5] = "Charge-downstream", | ||
231 | [6] = "MHL", | ||
232 | [7] = "Audio-video-load", | ||
233 | [8] = "Audio-video-noload", | ||
234 | [9] = "JIG", | ||
235 | |||
236 | NULL, | ||
237 | }; | ||
238 | |||
239 | static int max77693_muic_set_debounce_time(struct max77693_muic_info *info, | ||
240 | enum max77693_muic_adc_debounce_time time) | ||
241 | { | ||
242 | int ret = 0; | ||
243 | u8 ctrl3; | ||
244 | |||
245 | switch (time) { | ||
246 | case ADC_DEBOUNCE_TIME_5MS: | ||
247 | case ADC_DEBOUNCE_TIME_10MS: | ||
248 | case ADC_DEBOUNCE_TIME_25MS: | ||
249 | case ADC_DEBOUNCE_TIME_38_62MS: | ||
250 | ret = max77693_read_reg(info->max77693->regmap_muic, | ||
251 | MAX77693_MUIC_REG_CTRL3, &ctrl3); | ||
252 | ctrl3 &= ~CONTROL3_ADCDBSET_MASK; | ||
253 | ctrl3 |= (time << CONTROL3_ADCDBSET_SHIFT); | ||
254 | |||
255 | ret = max77693_write_reg(info->max77693->regmap_muic, | ||
256 | MAX77693_MUIC_REG_CTRL3, ctrl3); | ||
257 | if (ret) { | ||
258 | dev_err(info->dev, "failed to set ADC debounce time\n"); | ||
259 | ret = -EINVAL; | ||
260 | } | ||
261 | break; | ||
262 | default: | ||
263 | dev_err(info->dev, "invalid ADC debounce time\n"); | ||
264 | ret = -EINVAL; | ||
265 | break; | ||
266 | } | ||
267 | |||
268 | return ret; | ||
269 | }; | ||
270 | |||
271 | static int max77693_muic_set_path(struct max77693_muic_info *info, | ||
272 | u8 val, bool attached) | ||
273 | { | ||
274 | int ret = 0; | ||
275 | u8 ctrl1, ctrl2 = 0; | ||
276 | |||
277 | if (attached) | ||
278 | ctrl1 = val; | ||
279 | else | ||
280 | ctrl1 = CONTROL1_SW_OPEN; | ||
281 | |||
282 | ret = max77693_update_reg(info->max77693->regmap_muic, | ||
283 | MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK); | ||
284 | if (ret < 0) { | ||
285 | dev_err(info->dev, "failed to update MUIC register\n"); | ||
286 | goto out; | ||
287 | } | ||
288 | |||
289 | if (attached) | ||
290 | ctrl2 |= CONTROL2_CPEN_MASK; /* LowPwr=0, CPEn=1 */ | ||
291 | else | ||
292 | ctrl2 |= CONTROL2_LOWPWR_MASK; /* LowPwr=1, CPEn=0 */ | ||
293 | |||
294 | ret = max77693_update_reg(info->max77693->regmap_muic, | ||
295 | MAX77693_MUIC_REG_CTRL2, ctrl2, | ||
296 | CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK); | ||
297 | if (ret < 0) { | ||
298 | dev_err(info->dev, "failed to update MUIC register\n"); | ||
299 | goto out; | ||
300 | } | ||
301 | |||
302 | dev_info(info->dev, | ||
303 | "CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n", | ||
304 | ctrl1, ctrl2, attached ? "attached" : "detached"); | ||
305 | out: | ||
306 | return ret; | ||
307 | } | ||
308 | |||
309 | static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info, | ||
310 | bool attached) | ||
311 | { | ||
312 | int ret = 0; | ||
313 | int type; | ||
314 | int adc, adc1k, adclow; | ||
315 | |||
316 | if (attached) { | ||
317 | adc = info->status[0] & STATUS1_ADC_MASK; | ||
318 | adclow = info->status[0] & STATUS1_ADCLOW_MASK; | ||
319 | adclow >>= STATUS1_ADCLOW_SHIFT; | ||
320 | adc1k = info->status[0] & STATUS1_ADC1K_MASK; | ||
321 | adc1k >>= STATUS1_ADC1K_SHIFT; | ||
322 | |||
323 | /** | ||
324 | * [0x1][ADCLow][ADC1K] | ||
325 | * [0x1 0 0 ] : USB_OTG | ||
326 | * [0x1 1 0 ] : Audio Video Cable with load | ||
327 | * [0x1 1 1 ] : MHL | ||
328 | */ | ||
329 | type = ((0x1 << 8) | (adclow << 1) | adc1k); | ||
330 | |||
331 | /* Store previous ADC value to handle accessory | ||
332 | when accessory will be detached */ | ||
333 | info->prev_adc = adc; | ||
334 | info->prev_adc_gnd = type; | ||
335 | } else | ||
336 | type = info->prev_adc_gnd; | ||
337 | |||
338 | switch (type) { | ||
339 | case MAX77693_MUIC_GND_USB_OTG: | ||
340 | /* USB_OTG */ | ||
341 | ret = max77693_muic_set_path(info, CONTROL1_SW_USB, attached); | ||
342 | if (ret < 0) | ||
343 | goto out; | ||
344 | extcon_set_cable_state(info->edev, "USB-Host", attached); | ||
345 | break; | ||
346 | case MAX77693_MUIC_GND_AV_CABLE_LOAD: | ||
347 | /* Audio Video Cable with load */ | ||
348 | ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached); | ||
349 | if (ret < 0) | ||
350 | goto out; | ||
351 | extcon_set_cable_state(info->edev, | ||
352 | "Audio-video-load", attached); | ||
353 | break; | ||
354 | case MAX77693_MUIC_GND_MHL_CABLE: | ||
355 | /* MHL */ | ||
356 | extcon_set_cable_state(info->edev, "MHL", attached); | ||
357 | break; | ||
358 | default: | ||
359 | dev_err(info->dev, "faild to detect %s accessory\n", | ||
360 | attached ? "attached" : "detached"); | ||
361 | dev_err(info->dev, "- adc:0x%x, adclow:0x%x, adc1k:0x%x\n", | ||
362 | adc, adclow, adc1k); | ||
363 | ret = -EINVAL; | ||
364 | break; | ||
365 | } | ||
366 | |||
367 | out: | ||
368 | return ret; | ||
369 | } | ||
370 | |||
371 | static int max77693_muic_adc_handler(struct max77693_muic_info *info, | ||
372 | int curr_adc, bool attached) | ||
373 | { | ||
374 | int ret = 0; | ||
375 | int adc; | ||
376 | |||
377 | if (attached) { | ||
378 | /* Store ADC value to handle accessory | ||
379 | when accessory will be detached */ | ||
380 | info->prev_adc = curr_adc; | ||
381 | adc = curr_adc; | ||
382 | } else | ||
383 | adc = info->prev_adc; | ||
384 | |||
385 | dev_info(info->dev, | ||
386 | "external connector is %s (adc:0x%02x, prev_adc:0x%x)\n", | ||
387 | attached ? "attached" : "detached", curr_adc, info->prev_adc); | ||
388 | |||
389 | switch (adc) { | ||
390 | case MAX77693_MUIC_ADC_GROUND: | ||
391 | /* USB_OTG/MHL/Audio */ | ||
392 | max77693_muic_adc_ground_handler(info, attached); | ||
393 | break; | ||
394 | case MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF: | ||
395 | case MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON: | ||
396 | /* USB */ | ||
397 | ret = max77693_muic_set_path(info, CONTROL1_SW_USB, attached); | ||
398 | if (ret < 0) | ||
399 | goto out; | ||
400 | extcon_set_cable_state(info->edev, "USB", attached); | ||
401 | break; | ||
402 | case MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF: | ||
403 | case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON: | ||
404 | /* JIG */ | ||
405 | ret = max77693_muic_set_path(info, CONTROL1_SW_UART, attached); | ||
406 | if (ret < 0) | ||
407 | goto out; | ||
408 | extcon_set_cable_state(info->edev, "JIG", attached); | ||
409 | break; | ||
410 | case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE: | ||
411 | /* Audio Video cable with no-load */ | ||
412 | ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached); | ||
413 | if (ret < 0) | ||
414 | goto out; | ||
415 | extcon_set_cable_state(info->edev, | ||
416 | "Audio-video-noload", attached); | ||
417 | break; | ||
418 | case MAX77693_MUIC_ADC_SEND_END_BUTTON: | ||
419 | case MAX77693_MUIC_ADC_REMOTE_S1_BUTTON: | ||
420 | case MAX77693_MUIC_ADC_REMOTE_S2_BUTTON: | ||
421 | case MAX77693_MUIC_ADC_REMOTE_S3_BUTTON: | ||
422 | case MAX77693_MUIC_ADC_REMOTE_S4_BUTTON: | ||
423 | case MAX77693_MUIC_ADC_REMOTE_S5_BUTTON: | ||
424 | case MAX77693_MUIC_ADC_REMOTE_S6_BUTTON: | ||
425 | case MAX77693_MUIC_ADC_REMOTE_S7_BUTTON: | ||
426 | case MAX77693_MUIC_ADC_REMOTE_S8_BUTTON: | ||
427 | case MAX77693_MUIC_ADC_REMOTE_S9_BUTTON: | ||
428 | case MAX77693_MUIC_ADC_REMOTE_S10_BUTTON: | ||
429 | case MAX77693_MUIC_ADC_REMOTE_S11_BUTTON: | ||
430 | case MAX77693_MUIC_ADC_REMOTE_S12_BUTTON: | ||
431 | case MAX77693_MUIC_ADC_RESERVED_ACC_1: | ||
432 | case MAX77693_MUIC_ADC_RESERVED_ACC_2: | ||
433 | case MAX77693_MUIC_ADC_RESERVED_ACC_3: | ||
434 | case MAX77693_MUIC_ADC_RESERVED_ACC_4: | ||
435 | case MAX77693_MUIC_ADC_RESERVED_ACC_5: | ||
436 | case MAX77693_MUIC_ADC_CEA936_AUDIO: | ||
437 | case MAX77693_MUIC_ADC_PHONE_POWERED_DEV: | ||
438 | case MAX77693_MUIC_ADC_TTY_CONVERTER: | ||
439 | case MAX77693_MUIC_ADC_UART_CABLE: | ||
440 | case MAX77693_MUIC_ADC_CEA936A_TYPE1_CHG: | ||
441 | case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD: | ||
442 | case MAX77693_MUIC_ADC_CEA936A_TYPE2_CHG: | ||
443 | /* This accessory isn't used in general case if it is specially | ||
444 | needed to detect additional accessory, should implement | ||
445 | proper operation when this accessory is attached/detached. */ | ||
446 | dev_info(info->dev, | ||
447 | "accessory is %s but it isn't used (adc:0x%x)\n", | ||
448 | attached ? "attached" : "detached", adc); | ||
449 | goto out; | ||
450 | default: | ||
451 | dev_err(info->dev, | ||
452 | "failed to detect %s accessory (adc:0x%x)\n", | ||
453 | attached ? "attached" : "detached", adc); | ||
454 | ret = -EINVAL; | ||
455 | goto out; | ||
456 | } | ||
457 | |||
458 | out: | ||
459 | return ret; | ||
460 | } | ||
461 | |||
462 | static int max77693_muic_chg_handler(struct max77693_muic_info *info, | ||
463 | int curr_chg_type, bool attached) | ||
464 | { | ||
465 | int ret = 0; | ||
466 | int chg_type; | ||
467 | |||
468 | if (attached) { | ||
469 | /* Store previous charger type to control | ||
470 | when charger accessory will be detached */ | ||
471 | info->prev_chg_type = curr_chg_type; | ||
472 | chg_type = curr_chg_type; | ||
473 | } else | ||
474 | chg_type = info->prev_chg_type; | ||
475 | |||
476 | dev_info(info->dev, | ||
477 | "external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n", | ||
478 | attached ? "attached" : "detached", | ||
479 | curr_chg_type, info->prev_chg_type); | ||
480 | |||
481 | switch (chg_type) { | ||
482 | case MAX77693_CHARGER_TYPE_USB: | ||
483 | ret = max77693_muic_set_path(info, CONTROL1_SW_USB, attached); | ||
484 | if (ret < 0) | ||
485 | goto out; | ||
486 | extcon_set_cable_state(info->edev, "USB", attached); | ||
487 | break; | ||
488 | case MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT: | ||
489 | extcon_set_cable_state(info->edev, | ||
490 | "Charge-downstream", attached); | ||
491 | break; | ||
492 | case MAX77693_CHARGER_TYPE_DEDICATED_CHG: | ||
493 | extcon_set_cable_state(info->edev, "TA", attached); | ||
494 | break; | ||
495 | case MAX77693_CHARGER_TYPE_APPLE_500MA: | ||
496 | extcon_set_cable_state(info->edev, "Slow-charger", attached); | ||
497 | break; | ||
498 | case MAX77693_CHARGER_TYPE_APPLE_1A_2A: | ||
499 | extcon_set_cable_state(info->edev, "Fast-charger", attached); | ||
500 | break; | ||
501 | case MAX77693_CHARGER_TYPE_DEAD_BATTERY: | ||
502 | break; | ||
503 | default: | ||
504 | dev_err(info->dev, | ||
505 | "failed to detect %s accessory (chg_type:0x%x)\n", | ||
506 | attached ? "attached" : "detached", chg_type); | ||
507 | ret = -EINVAL; | ||
508 | goto out; | ||
509 | } | ||
510 | |||
511 | out: | ||
512 | return ret; | ||
513 | } | ||
514 | |||
515 | static void max77693_muic_irq_work(struct work_struct *work) | ||
516 | { | ||
517 | struct max77693_muic_info *info = container_of(work, | ||
518 | struct max77693_muic_info, irq_work); | ||
519 | int curr_adc, curr_chg_type; | ||
520 | int irq_type = -1; | ||
521 | int i, ret = 0; | ||
522 | bool attached = true; | ||
523 | |||
524 | if (!info->edev) | ||
525 | return; | ||
526 | |||
527 | mutex_lock(&info->mutex); | ||
528 | |||
529 | for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++) | ||
530 | if (info->irq == muic_irqs[i].virq) | ||
531 | irq_type = muic_irqs[i].irq; | ||
532 | |||
533 | ret = max77693_bulk_read(info->max77693->regmap_muic, | ||
534 | MAX77693_MUIC_REG_STATUS1, 2, info->status); | ||
535 | if (ret) { | ||
536 | dev_err(info->dev, "failed to read MUIC register\n"); | ||
537 | mutex_unlock(&info->mutex); | ||
538 | return; | ||
539 | } | ||
540 | |||
541 | switch (irq_type) { | ||
542 | case MAX77693_MUIC_IRQ_INT1_ADC: | ||
543 | case MAX77693_MUIC_IRQ_INT1_ADC_LOW: | ||
544 | case MAX77693_MUIC_IRQ_INT1_ADC_ERR: | ||
545 | case MAX77693_MUIC_IRQ_INT1_ADC1K: | ||
546 | /* Handle all of accessory except for | ||
547 | type of charger accessory */ | ||
548 | curr_adc = info->status[0] & STATUS1_ADC_MASK; | ||
549 | curr_adc >>= STATUS1_ADC_SHIFT; | ||
550 | |||
551 | /* Check accossory state which is either detached or attached */ | ||
552 | if (curr_adc == MAX77693_MUIC_ADC_OPEN) | ||
553 | attached = false; | ||
554 | |||
555 | ret = max77693_muic_adc_handler(info, curr_adc, attached); | ||
556 | break; | ||
557 | case MAX77693_MUIC_IRQ_INT2_CHGTYP: | ||
558 | case MAX77693_MUIC_IRQ_INT2_CHGDETREUN: | ||
559 | case MAX77693_MUIC_IRQ_INT2_DCDTMR: | ||
560 | case MAX77693_MUIC_IRQ_INT2_DXOVP: | ||
561 | case MAX77693_MUIC_IRQ_INT2_VBVOLT: | ||
562 | case MAX77693_MUIC_IRQ_INT2_VIDRM: | ||
563 | /* Handle charger accessory */ | ||
564 | curr_chg_type = info->status[1] & STATUS2_CHGTYP_MASK; | ||
565 | curr_chg_type >>= STATUS2_CHGTYP_SHIFT; | ||
566 | |||
567 | /* Check charger accossory state which | ||
568 | is either detached or attached */ | ||
569 | if (curr_chg_type == MAX77693_CHARGER_TYPE_NONE) | ||
570 | attached = false; | ||
571 | |||
572 | ret = max77693_muic_chg_handler(info, curr_chg_type, attached); | ||
573 | break; | ||
574 | case MAX77693_MUIC_IRQ_INT3_EOC: | ||
575 | case MAX77693_MUIC_IRQ_INT3_CGMBC: | ||
576 | case MAX77693_MUIC_IRQ_INT3_OVP: | ||
577 | case MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR: | ||
578 | case MAX77693_MUIC_IRQ_INT3_CHG_ENABLED: | ||
579 | case MAX77693_MUIC_IRQ_INT3_BAT_DET: | ||
580 | break; | ||
581 | default: | ||
582 | dev_err(info->dev, "muic interrupt: irq %d occurred\n", | ||
583 | irq_type); | ||
584 | break; | ||
585 | } | ||
586 | |||
587 | if (ret < 0) | ||
588 | dev_err(info->dev, "failed to handle MUIC interrupt\n"); | ||
589 | |||
590 | mutex_unlock(&info->mutex); | ||
591 | |||
592 | return; | ||
593 | } | ||
594 | |||
595 | static irqreturn_t max77693_muic_irq_handler(int irq, void *data) | ||
596 | { | ||
597 | struct max77693_muic_info *info = data; | ||
598 | |||
599 | info->irq = irq; | ||
600 | schedule_work(&info->irq_work); | ||
601 | |||
602 | return IRQ_HANDLED; | ||
603 | } | ||
604 | |||
605 | static struct regmap_config max77693_muic_regmap_config = { | ||
606 | .reg_bits = 8, | ||
607 | .val_bits = 8, | ||
608 | }; | ||
609 | |||
610 | static int max77693_muic_detect_accessory(struct max77693_muic_info *info) | ||
611 | { | ||
612 | int ret = 0; | ||
613 | int adc, chg_type; | ||
614 | |||
615 | mutex_lock(&info->mutex); | ||
616 | |||
617 | /* Read STATUSx register to detect accessory */ | ||
618 | ret = max77693_bulk_read(info->max77693->regmap_muic, | ||
619 | MAX77693_MUIC_REG_STATUS1, 2, info->status); | ||
620 | if (ret) { | ||
621 | dev_err(info->dev, "failed to read MUIC register\n"); | ||
622 | mutex_unlock(&info->mutex); | ||
623 | return -EINVAL; | ||
624 | } | ||
625 | |||
626 | adc = info->status[0] & STATUS1_ADC_MASK; | ||
627 | adc >>= STATUS1_ADC_SHIFT; | ||
628 | |||
629 | if (adc != MAX77693_MUIC_ADC_OPEN) { | ||
630 | dev_info(info->dev, | ||
631 | "external connector is attached (adc:0x%02x)\n", adc); | ||
632 | |||
633 | ret = max77693_muic_adc_handler(info, adc, true); | ||
634 | if (ret < 0) | ||
635 | dev_err(info->dev, "failed to detect accessory\n"); | ||
636 | goto out; | ||
637 | } | ||
638 | |||
639 | chg_type = info->status[1] & STATUS2_CHGTYP_MASK; | ||
640 | chg_type >>= STATUS2_CHGTYP_SHIFT; | ||
641 | |||
642 | if (chg_type != MAX77693_CHARGER_TYPE_NONE) { | ||
643 | dev_info(info->dev, | ||
644 | "external connector is attached (chg_type:0x%x)\n", | ||
645 | chg_type); | ||
646 | |||
647 | max77693_muic_chg_handler(info, chg_type, true); | ||
648 | if (ret < 0) | ||
649 | dev_err(info->dev, "failed to detect charger accessory\n"); | ||
650 | } | ||
651 | |||
652 | out: | ||
653 | mutex_unlock(&info->mutex); | ||
654 | return ret; | ||
655 | } | ||
656 | |||
657 | static int __devinit max77693_muic_probe(struct platform_device *pdev) | ||
658 | { | ||
659 | struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent); | ||
660 | struct max77693_muic_info *info; | ||
661 | int ret, i; | ||
662 | u8 id; | ||
663 | |||
664 | info = kzalloc(sizeof(struct max77693_muic_info), GFP_KERNEL); | ||
665 | if (!info) { | ||
666 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
667 | ret = -ENOMEM; | ||
668 | goto err_kfree; | ||
669 | } | ||
670 | info->dev = &pdev->dev; | ||
671 | info->max77693 = max77693; | ||
672 | info->max77693->regmap_muic = regmap_init_i2c(info->max77693->muic, | ||
673 | &max77693_muic_regmap_config); | ||
674 | if (IS_ERR(info->max77693->regmap_muic)) { | ||
675 | ret = PTR_ERR(info->max77693->regmap_muic); | ||
676 | dev_err(max77693->dev, | ||
677 | "failed to allocate register map: %d\n", ret); | ||
678 | goto err_regmap; | ||
679 | } | ||
680 | platform_set_drvdata(pdev, info); | ||
681 | mutex_init(&info->mutex); | ||
682 | |||
683 | INIT_WORK(&info->irq_work, max77693_muic_irq_work); | ||
684 | |||
685 | /* Support irq domain for MAX77693 MUIC device */ | ||
686 | for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) { | ||
687 | struct max77693_muic_irq *muic_irq = &muic_irqs[i]; | ||
688 | int virq = 0; | ||
689 | |||
690 | virq = irq_create_mapping(max77693->irq_domain, muic_irq->irq); | ||
691 | if (!virq) | ||
692 | goto err_irq; | ||
693 | muic_irq->virq = virq; | ||
694 | |||
695 | ret = request_threaded_irq(virq, NULL, | ||
696 | max77693_muic_irq_handler, | ||
697 | 0, muic_irq->name, info); | ||
698 | if (ret) { | ||
699 | dev_err(&pdev->dev, | ||
700 | "failed: irq request (IRQ: %d," | ||
701 | " error :%d)\n", | ||
702 | muic_irq->irq, ret); | ||
703 | |||
704 | for (i = i - 1; i >= 0; i--) | ||
705 | free_irq(muic_irq->virq, info); | ||
706 | goto err_irq; | ||
707 | } | ||
708 | } | ||
709 | |||
710 | /* Initialize extcon device */ | ||
711 | info->edev = kzalloc(sizeof(struct extcon_dev), GFP_KERNEL); | ||
712 | if (!info->edev) { | ||
713 | dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); | ||
714 | ret = -ENOMEM; | ||
715 | goto err_irq; | ||
716 | } | ||
717 | info->edev->name = DEV_NAME; | ||
718 | info->edev->supported_cable = max77693_extcon_cable; | ||
719 | ret = extcon_dev_register(info->edev, NULL); | ||
720 | if (ret) { | ||
721 | dev_err(&pdev->dev, "failed to register extcon device\n"); | ||
722 | goto err_extcon; | ||
723 | } | ||
724 | |||
725 | /* Check revision number of MUIC device*/ | ||
726 | ret = max77693_read_reg(info->max77693->regmap_muic, | ||
727 | MAX77693_MUIC_REG_ID, &id); | ||
728 | if (ret < 0) { | ||
729 | dev_err(&pdev->dev, "failed to read revision number\n"); | ||
730 | goto err_extcon; | ||
731 | } | ||
732 | dev_info(info->dev, "device ID : 0x%x\n", id); | ||
733 | |||
734 | /* Set ADC debounce time */ | ||
735 | max77693_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS); | ||
736 | |||
737 | /* Detect accessory on boot */ | ||
738 | max77693_muic_detect_accessory(info); | ||
739 | |||
740 | return ret; | ||
741 | |||
742 | err_extcon: | ||
743 | kfree(info->edev); | ||
744 | err_irq: | ||
745 | err_regmap: | ||
746 | kfree(info); | ||
747 | err_kfree: | ||
748 | return ret; | ||
749 | } | ||
750 | |||
751 | static int __devexit max77693_muic_remove(struct platform_device *pdev) | ||
752 | { | ||
753 | struct max77693_muic_info *info = platform_get_drvdata(pdev); | ||
754 | int i; | ||
755 | |||
756 | for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) | ||
757 | free_irq(muic_irqs[i].virq, info); | ||
758 | cancel_work_sync(&info->irq_work); | ||
759 | extcon_dev_unregister(info->edev); | ||
760 | kfree(info); | ||
761 | |||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | static struct platform_driver max77693_muic_driver = { | ||
766 | .driver = { | ||
767 | .name = DEV_NAME, | ||
768 | .owner = THIS_MODULE, | ||
769 | }, | ||
770 | .probe = max77693_muic_probe, | ||
771 | .remove = __devexit_p(max77693_muic_remove), | ||
772 | }; | ||
773 | |||
774 | module_platform_driver(max77693_muic_driver); | ||
775 | |||
776 | MODULE_DESCRIPTION("Maxim MAX77693 Extcon driver"); | ||
777 | MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); | ||
778 | MODULE_LICENSE("GPL"); | ||
779 | MODULE_ALIAS("platform:extcon-max77693"); | ||
diff --git a/drivers/extcon/extcon_class.c b/drivers/extcon/extcon_class.c index 159aeb07b3b..f6419f9db76 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 8a0dcc11c7c..fe3db45fa83 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/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index b9426a6592e..0614ff3a7d7 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h | |||
@@ -411,7 +411,7 @@ enum { | |||
411 | #define HV_PRESENT_BIT 0x80000000 | 411 | #define HV_PRESENT_BIT 0x80000000 |
412 | 412 | ||
413 | #define HV_LINUX_GUEST_ID_LO 0x00000000 | 413 | #define HV_LINUX_GUEST_ID_LO 0x00000000 |
414 | #define HV_LINUX_GUEST_ID_HI 0xB16B00B5 | 414 | #define HV_LINUX_GUEST_ID_HI 2976579765 |
415 | #define HV_LINUX_GUEST_ID (((u64)HV_LINUX_GUEST_ID_HI << 32) | \ | 415 | #define HV_LINUX_GUEST_ID (((u64)HV_LINUX_GUEST_ID_HI << 32) | \ |
416 | HV_LINUX_GUEST_ID_LO) | 416 | HV_LINUX_GUEST_ID_LO) |
417 | 417 | ||
diff --git a/drivers/power/ds2780_battery.c b/drivers/power/ds2780_battery.c index de31cae1ba5..74fad941c56 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 975684a40f1..5f92a4bb33f 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 a0c8965c1a7..530a2d30906 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 291897c881b..4b0fcf3c2d0 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c | |||
@@ -178,6 +178,7 @@ static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status) | |||
178 | hdq_data->hdq_irqstatus, OMAP_HDQ_TIMEOUT); | 178 | hdq_data->hdq_irqstatus, OMAP_HDQ_TIMEOUT); |
179 | if (ret == 0) { | 179 | if (ret == 0) { |
180 | dev_dbg(hdq_data->dev, "TX wait elapsed\n"); | 180 | dev_dbg(hdq_data->dev, "TX wait elapsed\n"); |
181 | ret = -ETIMEDOUT; | ||
181 | goto out; | 182 | goto out; |
182 | } | 183 | } |
183 | 184 | ||
@@ -185,7 +186,7 @@ static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status) | |||
185 | /* check irqstatus */ | 186 | /* check irqstatus */ |
186 | if (!(*status & OMAP_HDQ_INT_STATUS_TXCOMPLETE)) { | 187 | if (!(*status & OMAP_HDQ_INT_STATUS_TXCOMPLETE)) { |
187 | dev_dbg(hdq_data->dev, "timeout waiting for" | 188 | dev_dbg(hdq_data->dev, "timeout waiting for" |
188 | "TXCOMPLETE/RXCOMPLETE, %x", *status); | 189 | " TXCOMPLETE/RXCOMPLETE, %x", *status); |
189 | ret = -ETIMEDOUT; | 190 | ret = -ETIMEDOUT; |
190 | goto out; | 191 | goto out; |
191 | } | 192 | } |
@@ -196,7 +197,7 @@ static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status) | |||
196 | OMAP_HDQ_FLAG_CLEAR, &tmp_status); | 197 | OMAP_HDQ_FLAG_CLEAR, &tmp_status); |
197 | if (ret) { | 198 | if (ret) { |
198 | dev_dbg(hdq_data->dev, "timeout waiting GO bit" | 199 | dev_dbg(hdq_data->dev, "timeout waiting GO bit" |
199 | "return to zero, %x", tmp_status); | 200 | " return to zero, %x", tmp_status); |
200 | } | 201 | } |
201 | 202 | ||
202 | out: | 203 | out: |
@@ -339,7 +340,7 @@ static int omap_hdq_break(struct hdq_data *hdq_data) | |||
339 | &tmp_status); | 340 | &tmp_status); |
340 | if (ret) | 341 | if (ret) |
341 | dev_dbg(hdq_data->dev, "timeout waiting INIT&GO bits" | 342 | dev_dbg(hdq_data->dev, "timeout waiting INIT&GO bits" |
342 | "return to zero, %x", tmp_status); | 343 | " return to zero, %x", tmp_status); |
343 | 344 | ||
344 | out: | 345 | out: |
345 | mutex_unlock(&hdq_data->hdq_mutex); | 346 | mutex_unlock(&hdq_data->hdq_mutex); |
@@ -351,7 +352,6 @@ static int hdq_read_byte(struct hdq_data *hdq_data, u8 *val) | |||
351 | { | 352 | { |
352 | int ret = 0; | 353 | int ret = 0; |
353 | u8 status; | 354 | u8 status; |
354 | unsigned long timeout = jiffies + OMAP_HDQ_TIMEOUT; | ||
355 | 355 | ||
356 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | 356 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); |
357 | if (ret < 0) { | 357 | if (ret < 0) { |
@@ -369,22 +369,20 @@ static int hdq_read_byte(struct hdq_data *hdq_data, u8 *val) | |||
369 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO, | 369 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO, |
370 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO); | 370 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO); |
371 | /* | 371 | /* |
372 | * The RX comes immediately after TX. It | 372 | * The RX comes immediately after TX. |
373 | * triggers another interrupt before we | ||
374 | * sleep. So we have to wait for RXCOMPLETE bit. | ||
375 | */ | 373 | */ |
376 | while (!(hdq_data->hdq_irqstatus | 374 | wait_event_timeout(hdq_wait_queue, |
377 | & OMAP_HDQ_INT_STATUS_RXCOMPLETE) | 375 | (hdq_data->hdq_irqstatus |
378 | && time_before(jiffies, timeout)) { | 376 | & OMAP_HDQ_INT_STATUS_RXCOMPLETE), |
379 | schedule_timeout_uninterruptible(1); | 377 | OMAP_HDQ_TIMEOUT); |
380 | } | 378 | |
381 | hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, 0, | 379 | hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, 0, |
382 | OMAP_HDQ_CTRL_STATUS_DIR); | 380 | OMAP_HDQ_CTRL_STATUS_DIR); |
383 | status = hdq_data->hdq_irqstatus; | 381 | status = hdq_data->hdq_irqstatus; |
384 | /* check irqstatus */ | 382 | /* check irqstatus */ |
385 | if (!(status & OMAP_HDQ_INT_STATUS_RXCOMPLETE)) { | 383 | if (!(status & OMAP_HDQ_INT_STATUS_RXCOMPLETE)) { |
386 | dev_dbg(hdq_data->dev, "timeout waiting for" | 384 | dev_dbg(hdq_data->dev, "timeout waiting for" |
387 | "RXCOMPLETE, %x", status); | 385 | " RXCOMPLETE, %x", status); |
388 | ret = -ETIMEDOUT; | 386 | ret = -ETIMEDOUT; |
389 | goto out; | 387 | goto out; |
390 | } | 388 | } |
@@ -394,7 +392,7 @@ static int hdq_read_byte(struct hdq_data *hdq_data, u8 *val) | |||
394 | out: | 392 | out: |
395 | mutex_unlock(&hdq_data->hdq_mutex); | 393 | mutex_unlock(&hdq_data->hdq_mutex); |
396 | rtn: | 394 | rtn: |
397 | return 0; | 395 | return ret; |
398 | 396 | ||
399 | } | 397 | } |
400 | 398 | ||
@@ -456,7 +454,7 @@ static int omap_hdq_put(struct hdq_data *hdq_data) | |||
456 | 454 | ||
457 | if (0 == hdq_data->hdq_usecount) { | 455 | if (0 == hdq_data->hdq_usecount) { |
458 | dev_dbg(hdq_data->dev, "attempt to decrement use count" | 456 | dev_dbg(hdq_data->dev, "attempt to decrement use count" |
459 | "when it is zero"); | 457 | " when it is zero"); |
460 | ret = -EINVAL; | 458 | ret = -EINVAL; |
461 | } else { | 459 | } else { |
462 | hdq_data->hdq_usecount--; | 460 | hdq_data->hdq_usecount--; |
@@ -524,7 +522,7 @@ static void omap_w1_write_byte(void *_hdq, u8 byte) | |||
524 | mutex_unlock(&hdq_data->hdq_mutex); | 522 | mutex_unlock(&hdq_data->hdq_mutex); |
525 | 523 | ||
526 | ret = hdq_write_byte(hdq_data, byte, &status); | 524 | ret = hdq_write_byte(hdq_data, byte, &status); |
527 | if (ret == 0) { | 525 | if (ret < 0) { |
528 | dev_dbg(hdq_data->dev, "TX failure:Ctrl status %x\n", status); | 526 | dev_dbg(hdq_data->dev, "TX failure:Ctrl status %x\n", status); |
529 | return; | 527 | return; |
530 | } | 528 | } |
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index eb9e376d624..67526690acb 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 c4f1859fb52..05188f6aab5 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 52ad812fa1e..773dca5beaf 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 8e813eed0f0..441ad3a3b58 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 7a7dbe5026f..40a10b5ed12 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 84e2410aec1..984b30331a4 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 0f7b8f9c509..85f2cdb27fa 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 5754c9a4f58..aa7bd5fa2fa 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 39f78c0b143..7b09307de0e 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 73737936502..a1fba79eb1b 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 0d0c7985293..877daf74159 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 82bc66497b4..557dfb0b4f6 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 00000000000..98117db595b --- /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 ff29ae747ee..d90062b211f 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 2f2e894ea0c..1a574370d2c 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 4d012ca3f32..45908e56c2f 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 874aeb05011..b00ada44a89 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 68288355727..5a98649f6ab 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 d17c20fd74e..4733eab34a2 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -495,7 +495,7 @@ void debugfs_remove(struct dentry *dentry) | |||
495 | struct dentry *parent; | 495 | struct dentry *parent; |
496 | int ret; | 496 | int ret; |
497 | 497 | ||
498 | if (!dentry) | 498 | if (IS_ERR_OR_NULL(dentry)) |
499 | return; | 499 | return; |
500 | 500 | ||
501 | parent = dentry->d_parent; | 501 | parent = dentry->d_parent; |
@@ -527,7 +527,7 @@ void debugfs_remove_recursive(struct dentry *dentry) | |||
527 | struct dentry *child; | 527 | struct dentry *child; |
528 | struct dentry *parent; | 528 | struct dentry *parent; |
529 | 529 | ||
530 | if (!dentry) | 530 | if (IS_ERR_OR_NULL(dentry)) |
531 | return; | 531 | return; |
532 | 532 | ||
533 | parent = dentry->d_parent; | 533 | parent = dentry->d_parent; |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index a5cf784f9cc..6b0bb00d4d2 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -307,6 +307,7 @@ static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) | |||
307 | { | 307 | { |
308 | struct sysfs_dirent *sd; | 308 | struct sysfs_dirent *sd; |
309 | int is_dir; | 309 | int is_dir; |
310 | int type; | ||
310 | 311 | ||
311 | if (flags & LOOKUP_RCU) | 312 | if (flags & LOOKUP_RCU) |
312 | return -ECHILD; | 313 | return -ECHILD; |
@@ -326,6 +327,15 @@ static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) | |||
326 | if (strcmp(dentry->d_name.name, sd->s_name) != 0) | 327 | if (strcmp(dentry->d_name.name, sd->s_name) != 0) |
327 | goto out_bad; | 328 | goto out_bad; |
328 | 329 | ||
330 | /* The sysfs dirent has been moved to a different namespace */ | ||
331 | type = KOBJ_NS_TYPE_NONE; | ||
332 | if (sd->s_parent) { | ||
333 | type = sysfs_ns_type(sd->s_parent); | ||
334 | if (type != KOBJ_NS_TYPE_NONE && | ||
335 | sysfs_info(dentry->d_sb)->ns[type] != sd->s_ns) | ||
336 | goto out_bad; | ||
337 | } | ||
338 | |||
329 | mutex_unlock(&sysfs_mutex); | 339 | mutex_unlock(&sysfs_mutex); |
330 | out_valid: | 340 | out_valid: |
331 | return 1; | 341 | return 1; |
diff --git a/include/linux/device.h b/include/linux/device.h index 5083bccae96..52a5f15a222 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -691,6 +691,11 @@ struct device { | |||
691 | struct iommu_group *iommu_group; | 691 | struct iommu_group *iommu_group; |
692 | }; | 692 | }; |
693 | 693 | ||
694 | static inline struct device *kobj_to_dev(struct kobject *kobj) | ||
695 | { | ||
696 | return container_of(kobj, struct device, kobj); | ||
697 | } | ||
698 | |||
694 | /* Get the wakeup routines, which depend on struct device */ | 699 | /* Get the wakeup routines, which depend on struct device */ |
695 | #include <linux/pm_wakeup.h> | 700 | #include <linux/pm_wakeup.h> |
696 | 701 | ||
diff --git a/include/linux/extcon/extcon_gpio.h b/include/linux/extcon/extcon_gpio.h index a2129b73dcb..2d8307f7d67 100644 --- a/include/linux/extcon/extcon_gpio.h +++ b/include/linux/extcon/extcon_gpio.h | |||
@@ -31,7 +31,7 @@ | |||
31 | * @irq_flags IRQ Flags (e.g., IRQF_TRIGGER_LOW). | 31 | * @irq_flags IRQ Flags (e.g., IRQF_TRIGGER_LOW). |
32 | * @state_on print_state is overriden with state_on if attached. If Null, | 32 | * @state_on print_state is overriden with state_on if attached. If Null, |
33 | * default method of extcon class is used. | 33 | * default method of extcon class is used. |
34 | * @state_off print_state is overriden with state_on if dettached. If Null, | 34 | * @state_off print_state is overriden with state_on if detached. If Null, |
35 | * default method of extcon class is used. | 35 | * default method of extcon class is used. |
36 | * | 36 | * |
37 | * Note that in order for state_on or state_off to be valid, both state_on | 37 | * Note that in order for state_on or state_off to be valid, both state_on |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 017a7fb5a1f..ae0aaa9d42f 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) |
diff --git a/kernel/printk.c b/kernel/printk.c index ac4bc9e7946..50c96b5651b 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -216,6 +216,7 @@ struct log { | |||
216 | */ | 216 | */ |
217 | static DEFINE_RAW_SPINLOCK(logbuf_lock); | 217 | static DEFINE_RAW_SPINLOCK(logbuf_lock); |
218 | 218 | ||
219 | #ifdef CONFIG_PRINTK | ||
219 | /* the next printk record to read by syslog(READ) or /proc/kmsg */ | 220 | /* the next printk record to read by syslog(READ) or /proc/kmsg */ |
220 | static u64 syslog_seq; | 221 | static u64 syslog_seq; |
221 | static u32 syslog_idx; | 222 | static u32 syslog_idx; |
@@ -228,14 +229,19 @@ static u32 log_first_idx; | |||
228 | 229 | ||
229 | /* index and sequence number of the next record to store in the buffer */ | 230 | /* index and sequence number of the next record to store in the buffer */ |
230 | static u64 log_next_seq; | 231 | static u64 log_next_seq; |
231 | #ifdef CONFIG_PRINTK | ||
232 | static u32 log_next_idx; | 232 | static u32 log_next_idx; |
233 | 233 | ||
234 | /* the next printk record to write to the console */ | ||
235 | static u64 console_seq; | ||
236 | static u32 console_idx; | ||
237 | static enum log_flags console_prev; | ||
238 | |||
234 | /* the next printk record to read after the last 'clear' command */ | 239 | /* the next printk record to read after the last 'clear' command */ |
235 | static u64 clear_seq; | 240 | static u64 clear_seq; |
236 | static u32 clear_idx; | 241 | static u32 clear_idx; |
237 | 242 | ||
238 | #define LOG_LINE_MAX 1024 | 243 | #define PREFIX_MAX 32 |
244 | #define LOG_LINE_MAX 1024 - PREFIX_MAX | ||
239 | 245 | ||
240 | /* record buffer */ | 246 | /* record buffer */ |
241 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) | 247 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) |
@@ -360,6 +366,7 @@ static void log_store(int facility, int level, | |||
360 | struct devkmsg_user { | 366 | struct devkmsg_user { |
361 | u64 seq; | 367 | u64 seq; |
362 | u32 idx; | 368 | u32 idx; |
369 | enum log_flags prev; | ||
363 | struct mutex lock; | 370 | struct mutex lock; |
364 | char buf[8192]; | 371 | char buf[8192]; |
365 | }; | 372 | }; |
@@ -425,6 +432,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, | |||
425 | struct log *msg; | 432 | struct log *msg; |
426 | u64 ts_usec; | 433 | u64 ts_usec; |
427 | size_t i; | 434 | size_t i; |
435 | char cont = '-'; | ||
428 | size_t len; | 436 | size_t len; |
429 | ssize_t ret; | 437 | ssize_t ret; |
430 | 438 | ||
@@ -462,8 +470,25 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, | |||
462 | msg = log_from_idx(user->idx); | 470 | msg = log_from_idx(user->idx); |
463 | ts_usec = msg->ts_nsec; | 471 | ts_usec = msg->ts_nsec; |
464 | do_div(ts_usec, 1000); | 472 | do_div(ts_usec, 1000); |
465 | len = sprintf(user->buf, "%u,%llu,%llu;", | 473 | |
466 | (msg->facility << 3) | msg->level, user->seq, ts_usec); | 474 | /* |
475 | * If we couldn't merge continuation line fragments during the print, | ||
476 | * export the stored flags to allow an optional external merge of the | ||
477 | * records. Merging the records isn't always neccessarily correct, like | ||
478 | * when we hit a race during printing. In most cases though, it produces | ||
479 | * better readable output. 'c' in the record flags mark the first | ||
480 | * fragment of a line, '+' the following. | ||
481 | */ | ||
482 | if (msg->flags & LOG_CONT && !(user->prev & LOG_CONT)) | ||
483 | cont = 'c'; | ||
484 | else if ((msg->flags & LOG_CONT) || | ||
485 | ((user->prev & LOG_CONT) && !(msg->flags & LOG_PREFIX))) | ||
486 | cont = '+'; | ||
487 | |||
488 | len = sprintf(user->buf, "%u,%llu,%llu,%c;", | ||
489 | (msg->facility << 3) | msg->level, | ||
490 | user->seq, ts_usec, cont); | ||
491 | user->prev = msg->flags; | ||
467 | 492 | ||
468 | /* escape non-printable characters */ | 493 | /* escape non-printable characters */ |
469 | for (i = 0; i < msg->text_len; i++) { | 494 | for (i = 0; i < msg->text_len; i++) { |
@@ -646,6 +671,15 @@ void log_buf_kexec_setup(void) | |||
646 | VMCOREINFO_SYMBOL(log_buf_len); | 671 | VMCOREINFO_SYMBOL(log_buf_len); |
647 | VMCOREINFO_SYMBOL(log_first_idx); | 672 | VMCOREINFO_SYMBOL(log_first_idx); |
648 | VMCOREINFO_SYMBOL(log_next_idx); | 673 | VMCOREINFO_SYMBOL(log_next_idx); |
674 | /* | ||
675 | * Export struct log size and field offsets. User space tools can | ||
676 | * parse it and detect any changes to structure down the line. | ||
677 | */ | ||
678 | VMCOREINFO_STRUCT_SIZE(log); | ||
679 | VMCOREINFO_OFFSET(log, ts_nsec); | ||
680 | VMCOREINFO_OFFSET(log, len); | ||
681 | VMCOREINFO_OFFSET(log, text_len); | ||
682 | VMCOREINFO_OFFSET(log, dict_len); | ||
649 | } | 683 | } |
650 | #endif | 684 | #endif |
651 | 685 | ||
@@ -876,7 +910,7 @@ static size_t msg_print_text(const struct log *msg, enum log_flags prev, | |||
876 | 910 | ||
877 | if (buf) { | 911 | if (buf) { |
878 | if (print_prefix(msg, syslog, NULL) + | 912 | if (print_prefix(msg, syslog, NULL) + |
879 | text_len + 1>= size - len) | 913 | text_len + 1 >= size - len) |
880 | break; | 914 | break; |
881 | 915 | ||
882 | if (prefix) | 916 | if (prefix) |
@@ -907,7 +941,7 @@ static int syslog_print(char __user *buf, int size) | |||
907 | struct log *msg; | 941 | struct log *msg; |
908 | int len = 0; | 942 | int len = 0; |
909 | 943 | ||
910 | text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); | 944 | text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); |
911 | if (!text) | 945 | if (!text) |
912 | return -ENOMEM; | 946 | return -ENOMEM; |
913 | 947 | ||
@@ -930,7 +964,8 @@ static int syslog_print(char __user *buf, int size) | |||
930 | 964 | ||
931 | skip = syslog_partial; | 965 | skip = syslog_partial; |
932 | msg = log_from_idx(syslog_idx); | 966 | msg = log_from_idx(syslog_idx); |
933 | n = msg_print_text(msg, syslog_prev, true, text, LOG_LINE_MAX); | 967 | n = msg_print_text(msg, syslog_prev, true, text, |
968 | LOG_LINE_MAX + PREFIX_MAX); | ||
934 | if (n - syslog_partial <= size) { | 969 | if (n - syslog_partial <= size) { |
935 | /* message fits into buffer, move forward */ | 970 | /* message fits into buffer, move forward */ |
936 | syslog_idx = log_next(syslog_idx); | 971 | syslog_idx = log_next(syslog_idx); |
@@ -969,7 +1004,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) | |||
969 | char *text; | 1004 | char *text; |
970 | int len = 0; | 1005 | int len = 0; |
971 | 1006 | ||
972 | text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); | 1007 | text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); |
973 | if (!text) | 1008 | if (!text) |
974 | return -ENOMEM; | 1009 | return -ENOMEM; |
975 | 1010 | ||
@@ -1022,7 +1057,8 @@ static int syslog_print_all(char __user *buf, int size, bool clear) | |||
1022 | struct log *msg = log_from_idx(idx); | 1057 | struct log *msg = log_from_idx(idx); |
1023 | int textlen; | 1058 | int textlen; |
1024 | 1059 | ||
1025 | textlen = msg_print_text(msg, prev, true, text, LOG_LINE_MAX); | 1060 | textlen = msg_print_text(msg, prev, true, text, |
1061 | LOG_LINE_MAX + PREFIX_MAX); | ||
1026 | if (textlen < 0) { | 1062 | if (textlen < 0) { |
1027 | len = textlen; | 1063 | len = textlen; |
1028 | break; | 1064 | break; |
@@ -1349,20 +1385,36 @@ static struct cont { | |||
1349 | u64 ts_nsec; /* time of first print */ | 1385 | u64 ts_nsec; /* time of first print */ |
1350 | u8 level; /* log level of first message */ | 1386 | u8 level; /* log level of first message */ |
1351 | u8 facility; /* log level of first message */ | 1387 | u8 facility; /* log level of first message */ |
1388 | enum log_flags flags; /* prefix, newline flags */ | ||
1352 | bool flushed:1; /* buffer sealed and committed */ | 1389 | bool flushed:1; /* buffer sealed and committed */ |
1353 | } cont; | 1390 | } cont; |
1354 | 1391 | ||
1355 | static void cont_flush(void) | 1392 | static void cont_flush(enum log_flags flags) |
1356 | { | 1393 | { |
1357 | if (cont.flushed) | 1394 | if (cont.flushed) |
1358 | return; | 1395 | return; |
1359 | if (cont.len == 0) | 1396 | if (cont.len == 0) |
1360 | return; | 1397 | return; |
1361 | 1398 | ||
1362 | log_store(cont.facility, cont.level, LOG_NOCONS, cont.ts_nsec, | 1399 | if (cont.cons) { |
1363 | NULL, 0, cont.buf, cont.len); | 1400 | /* |
1364 | 1401 | * If a fragment of this line was directly flushed to the | |
1365 | cont.flushed = true; | 1402 | * console; wait for the console to pick up the rest of the |
1403 | * line. LOG_NOCONS suppresses a duplicated output. | ||
1404 | */ | ||
1405 | log_store(cont.facility, cont.level, flags | LOG_NOCONS, | ||
1406 | cont.ts_nsec, NULL, 0, cont.buf, cont.len); | ||
1407 | cont.flags = flags; | ||
1408 | cont.flushed = true; | ||
1409 | } else { | ||
1410 | /* | ||
1411 | * If no fragment of this line ever reached the console, | ||
1412 | * just submit it to the store and free the buffer. | ||
1413 | */ | ||
1414 | log_store(cont.facility, cont.level, flags, 0, | ||
1415 | NULL, 0, cont.buf, cont.len); | ||
1416 | cont.len = 0; | ||
1417 | } | ||
1366 | } | 1418 | } |
1367 | 1419 | ||
1368 | static bool cont_add(int facility, int level, const char *text, size_t len) | 1420 | static bool cont_add(int facility, int level, const char *text, size_t len) |
@@ -1371,7 +1423,8 @@ static bool cont_add(int facility, int level, const char *text, size_t len) | |||
1371 | return false; | 1423 | return false; |
1372 | 1424 | ||
1373 | if (cont.len + len > sizeof(cont.buf)) { | 1425 | if (cont.len + len > sizeof(cont.buf)) { |
1374 | cont_flush(); | 1426 | /* the line gets too long, split it up in separate records */ |
1427 | cont_flush(LOG_CONT); | ||
1375 | return false; | 1428 | return false; |
1376 | } | 1429 | } |
1377 | 1430 | ||
@@ -1380,12 +1433,17 @@ static bool cont_add(int facility, int level, const char *text, size_t len) | |||
1380 | cont.level = level; | 1433 | cont.level = level; |
1381 | cont.owner = current; | 1434 | cont.owner = current; |
1382 | cont.ts_nsec = local_clock(); | 1435 | cont.ts_nsec = local_clock(); |
1436 | cont.flags = 0; | ||
1383 | cont.cons = 0; | 1437 | cont.cons = 0; |
1384 | cont.flushed = false; | 1438 | cont.flushed = false; |
1385 | } | 1439 | } |
1386 | 1440 | ||
1387 | memcpy(cont.buf + cont.len, text, len); | 1441 | memcpy(cont.buf + cont.len, text, len); |
1388 | cont.len += len; | 1442 | cont.len += len; |
1443 | |||
1444 | if (cont.len > (sizeof(cont.buf) * 80) / 100) | ||
1445 | cont_flush(LOG_CONT); | ||
1446 | |||
1389 | return true; | 1447 | return true; |
1390 | } | 1448 | } |
1391 | 1449 | ||
@@ -1394,7 +1452,7 @@ static size_t cont_print_text(char *text, size_t size) | |||
1394 | size_t textlen = 0; | 1452 | size_t textlen = 0; |
1395 | size_t len; | 1453 | size_t len; |
1396 | 1454 | ||
1397 | if (cont.cons == 0) { | 1455 | if (cont.cons == 0 && (console_prev & LOG_NEWLINE)) { |
1398 | textlen += print_time(cont.ts_nsec, text); | 1456 | textlen += print_time(cont.ts_nsec, text); |
1399 | size -= textlen; | 1457 | size -= textlen; |
1400 | } | 1458 | } |
@@ -1409,7 +1467,8 @@ static size_t cont_print_text(char *text, size_t size) | |||
1409 | } | 1467 | } |
1410 | 1468 | ||
1411 | if (cont.flushed) { | 1469 | if (cont.flushed) { |
1412 | text[textlen++] = '\n'; | 1470 | if (cont.flags & LOG_NEWLINE) |
1471 | text[textlen++] = '\n'; | ||
1413 | /* got everything, release buffer */ | 1472 | /* got everything, release buffer */ |
1414 | cont.len = 0; | 1473 | cont.len = 0; |
1415 | } | 1474 | } |
@@ -1507,7 +1566,7 @@ asmlinkage int vprintk_emit(int facility, int level, | |||
1507 | * or another task also prints continuation lines. | 1566 | * or another task also prints continuation lines. |
1508 | */ | 1567 | */ |
1509 | if (cont.len && (lflags & LOG_PREFIX || cont.owner != current)) | 1568 | if (cont.len && (lflags & LOG_PREFIX || cont.owner != current)) |
1510 | cont_flush(); | 1569 | cont_flush(LOG_NEWLINE); |
1511 | 1570 | ||
1512 | /* buffer line if possible, otherwise store it right away */ | 1571 | /* buffer line if possible, otherwise store it right away */ |
1513 | if (!cont_add(facility, level, text, text_len)) | 1572 | if (!cont_add(facility, level, text, text_len)) |
@@ -1525,7 +1584,7 @@ asmlinkage int vprintk_emit(int facility, int level, | |||
1525 | if (cont.len && cont.owner == current) { | 1584 | if (cont.len && cont.owner == current) { |
1526 | if (!(lflags & LOG_PREFIX)) | 1585 | if (!(lflags & LOG_PREFIX)) |
1527 | stored = cont_add(facility, level, text, text_len); | 1586 | stored = cont_add(facility, level, text, text_len); |
1528 | cont_flush(); | 1587 | cont_flush(LOG_NEWLINE); |
1529 | } | 1588 | } |
1530 | 1589 | ||
1531 | if (!stored) | 1590 | if (!stored) |
@@ -1616,9 +1675,20 @@ asmlinkage int printk(const char *fmt, ...) | |||
1616 | } | 1675 | } |
1617 | EXPORT_SYMBOL(printk); | 1676 | EXPORT_SYMBOL(printk); |
1618 | 1677 | ||
1619 | #else | 1678 | #else /* CONFIG_PRINTK */ |
1620 | 1679 | ||
1680 | #define LOG_LINE_MAX 0 | ||
1681 | #define PREFIX_MAX 0 | ||
1621 | #define LOG_LINE_MAX 0 | 1682 | #define LOG_LINE_MAX 0 |
1683 | static u64 syslog_seq; | ||
1684 | static u32 syslog_idx; | ||
1685 | static u64 console_seq; | ||
1686 | static u32 console_idx; | ||
1687 | static enum log_flags syslog_prev; | ||
1688 | static u64 log_first_seq; | ||
1689 | static u32 log_first_idx; | ||
1690 | static u64 log_next_seq; | ||
1691 | static enum log_flags console_prev; | ||
1622 | static struct cont { | 1692 | static struct cont { |
1623 | size_t len; | 1693 | size_t len; |
1624 | size_t cons; | 1694 | size_t cons; |
@@ -1902,10 +1972,34 @@ void wake_up_klogd(void) | |||
1902 | this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); | 1972 | this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); |
1903 | } | 1973 | } |
1904 | 1974 | ||
1905 | /* the next printk record to write to the console */ | 1975 | static void console_cont_flush(char *text, size_t size) |
1906 | static u64 console_seq; | 1976 | { |
1907 | static u32 console_idx; | 1977 | unsigned long flags; |
1908 | static enum log_flags console_prev; | 1978 | size_t len; |
1979 | |||
1980 | raw_spin_lock_irqsave(&logbuf_lock, flags); | ||
1981 | |||
1982 | if (!cont.len) | ||
1983 | goto out; | ||
1984 | |||
1985 | /* | ||
1986 | * We still queue earlier records, likely because the console was | ||
1987 | * busy. The earlier ones need to be printed before this one, we | ||
1988 | * did not flush any fragment so far, so just let it queue up. | ||
1989 | */ | ||
1990 | if (console_seq < log_next_seq && !cont.cons) | ||
1991 | goto out; | ||
1992 | |||
1993 | len = cont_print_text(text, size); | ||
1994 | raw_spin_unlock(&logbuf_lock); | ||
1995 | stop_critical_timings(); | ||
1996 | call_console_drivers(cont.level, text, len); | ||
1997 | start_critical_timings(); | ||
1998 | local_irq_restore(flags); | ||
1999 | return; | ||
2000 | out: | ||
2001 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | ||
2002 | } | ||
1909 | 2003 | ||
1910 | /** | 2004 | /** |
1911 | * console_unlock - unlock the console system | 2005 | * console_unlock - unlock the console system |
@@ -1923,7 +2017,7 @@ static enum log_flags console_prev; | |||
1923 | */ | 2017 | */ |
1924 | void console_unlock(void) | 2018 | void console_unlock(void) |
1925 | { | 2019 | { |
1926 | static char text[LOG_LINE_MAX]; | 2020 | static char text[LOG_LINE_MAX + PREFIX_MAX]; |
1927 | static u64 seen_seq; | 2021 | static u64 seen_seq; |
1928 | unsigned long flags; | 2022 | unsigned long flags; |
1929 | bool wake_klogd = false; | 2023 | bool wake_klogd = false; |
@@ -1937,19 +2031,7 @@ void console_unlock(void) | |||
1937 | console_may_schedule = 0; | 2031 | console_may_schedule = 0; |
1938 | 2032 | ||
1939 | /* flush buffered message fragment immediately to console */ | 2033 | /* flush buffered message fragment immediately to console */ |
1940 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 2034 | console_cont_flush(text, sizeof(text)); |
1941 | if (cont.len && (cont.cons < cont.len || cont.flushed)) { | ||
1942 | size_t len; | ||
1943 | |||
1944 | len = cont_print_text(text, sizeof(text)); | ||
1945 | raw_spin_unlock(&logbuf_lock); | ||
1946 | stop_critical_timings(); | ||
1947 | call_console_drivers(cont.level, text, len); | ||
1948 | start_critical_timings(); | ||
1949 | local_irq_restore(flags); | ||
1950 | } else | ||
1951 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | ||
1952 | |||
1953 | again: | 2035 | again: |
1954 | for (;;) { | 2036 | for (;;) { |
1955 | struct log *msg; | 2037 | struct log *msg; |
@@ -1986,6 +2068,7 @@ skip: | |||
1986 | * will properly dump everything later. | 2068 | * will properly dump everything later. |
1987 | */ | 2069 | */ |
1988 | msg->flags &= ~LOG_NOCONS; | 2070 | msg->flags &= ~LOG_NOCONS; |
2071 | console_prev = msg->flags; | ||
1989 | goto skip; | 2072 | goto skip; |
1990 | } | 2073 | } |
1991 | 2074 | ||