aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-04-10 20:04:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-04-10 20:04:42 -0400
commit6a7c924314dd1b4facfccc682011622c15e71ea3 (patch)
tree66f219e5cef0132f3d147971a1d59639db8fd3ac
parent9f2394c9be47a754bae9e4b6d382bdd4d77d0a11 (diff)
parentcaf280800aaf73f0796d1bb3fa0f6576c8222258 (diff)
Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "Some bugfixes from I2C: - fix a uevent triggered boot problem by removing a useless debug print - fix sysfs-attributes of the new i2c-demux-pinctrl driver to follow standard kernel behaviour - fix a potential division-by-zero error (needed two takes)" * 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: jz4780: really prevent potential division by zero Revert "i2c: jz4780: prevent potential division by zero" i2c: jz4780: prevent potential division by zero i2c: mux: demux-pinctrl: Update docs to new sysfs-attributes i2c: mux: demux-pinctrl: Clean up sysfs attributes i2c: prevent endless uevent loop with CONFIG_I2C_DEBUG_CORE
-rw-r--r--Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl29
-rw-r--r--drivers/i2c/busses/i2c-jz4780.c7
-rw-r--r--drivers/i2c/i2c-core.c10
-rw-r--r--drivers/i2c/muxes/i2c-demux-pinctrl.c39
4 files changed, 49 insertions, 36 deletions
diff --git a/Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl b/Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl
index 7ac7d7262bb7..3c3514815cd5 100644
--- a/Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl
+++ b/Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl
@@ -1,23 +1,18 @@
1What: /sys/devices/platform/<i2c-demux-name>/cur_master 1What: /sys/devices/platform/<i2c-demux-name>/available_masters
2Date: January 2016 2Date: January 2016
3KernelVersion: 4.6 3KernelVersion: 4.6
4Contact: Wolfram Sang <wsa@the-dreams.de> 4Contact: Wolfram Sang <wsa@the-dreams.de>
5Description: 5Description:
6 Reading the file will give you a list of masters which can be
7 selected for a demultiplexed bus. The format is
8 "<index>:<name>". Example from a Renesas Lager board:
6 9
7This file selects the active I2C master for a demultiplexed bus. 10 0:/i2c@e6500000 1:/i2c@e6508000
8 11
9Write 0 there for the first master, 1 for the second etc. Reading the file will 12What: /sys/devices/platform/<i2c-demux-name>/current_master
10give you a list with the active master marked. Example from a Renesas Lager 13Date: January 2016
11board: 14KernelVersion: 4.6
12 15Contact: Wolfram Sang <wsa@the-dreams.de>
13root@Lager:~# cat /sys/devices/platform/i2c@8/cur_master 16Description:
14* 0 - /i2c@9 17 This file selects/shows the active I2C master for a demultiplexed
15 1 - /i2c@e6520000 18 bus. It uses the <index> value from the file 'available_masters'.
16 2 - /i2c@e6530000
17
18root@Lager:~# echo 2 > /sys/devices/platform/i2c@8/cur_master
19
20root@Lager:~# cat /sys/devices/platform/i2c@8/cur_master
21 0 - /i2c@9
22 1 - /i2c@e6520000
23* 2 - /i2c@e6530000
diff --git a/drivers/i2c/busses/i2c-jz4780.c b/drivers/i2c/busses/i2c-jz4780.c
index f325663c27c5..ba14a863b451 100644
--- a/drivers/i2c/busses/i2c-jz4780.c
+++ b/drivers/i2c/busses/i2c-jz4780.c
@@ -771,11 +771,16 @@ static int jz4780_i2c_probe(struct platform_device *pdev)
771 ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", 771 ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
772 &clk_freq); 772 &clk_freq);
773 if (ret) { 773 if (ret) {
774 dev_err(&pdev->dev, "clock-frequency not specified in DT"); 774 dev_err(&pdev->dev, "clock-frequency not specified in DT\n");
775 goto err; 775 goto err;
776 } 776 }
777 777
778 i2c->speed = clk_freq / 1000; 778 i2c->speed = clk_freq / 1000;
779 if (i2c->speed == 0) {
780 ret = -EINVAL;
781 dev_err(&pdev->dev, "clock-frequency minimum is 1000\n");
782 goto err;
783 }
779 jz4780_i2c_set_speed(i2c); 784 jz4780_i2c_set_speed(i2c);
780 785
781 dev_info(&pdev->dev, "Bus frequency is %d KHz\n", i2c->speed); 786 dev_info(&pdev->dev, "Bus frequency is %d KHz\n", i2c->speed);
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 0f2f8484e8ec..e584d88ee337 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -525,22 +525,16 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
525 return 0; 525 return 0;
526} 526}
527 527
528
529/* uevent helps with hotplug: modprobe -q $(MODALIAS) */
530static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env) 528static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
531{ 529{
532 struct i2c_client *client = to_i2c_client(dev); 530 struct i2c_client *client = to_i2c_client(dev);
533 int rc; 531 int rc;
534 532
535 rc = acpi_device_uevent_modalias(dev, env); 533 rc = acpi_device_uevent_modalias(dev, env);
536 if (rc != -ENODEV) 534 if (rc != -ENODEV)
537 return rc; 535 return rc;
538 536
539 if (add_uevent_var(env, "MODALIAS=%s%s", 537 return add_uevent_var(env, "MODALIAS=%s%s", I2C_MODULE_PREFIX, client->name);
540 I2C_MODULE_PREFIX, client->name))
541 return -ENOMEM;
542 dev_dbg(dev, "uevent\n");
543 return 0;
544} 538}
545 539
546/* i2c bus recovery routines */ 540/* i2c bus recovery routines */
diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c
index 7748a0a5ddb9..8de073aed001 100644
--- a/drivers/i2c/muxes/i2c-demux-pinctrl.c
+++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c
@@ -140,22 +140,34 @@ static int i2c_demux_change_master(struct i2c_demux_pinctrl_priv *priv, u32 new_
140 return i2c_demux_activate_master(priv, new_chan); 140 return i2c_demux_activate_master(priv, new_chan);
141} 141}
142 142
143static ssize_t cur_master_show(struct device *dev, struct device_attribute *attr, 143static ssize_t available_masters_show(struct device *dev,
144 char *buf) 144 struct device_attribute *attr,
145 char *buf)
145{ 146{
146 struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev); 147 struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
147 int count = 0, i; 148 int count = 0, i;
148 149
149 for (i = 0; i < priv->num_chan && count < PAGE_SIZE; i++) 150 for (i = 0; i < priv->num_chan && count < PAGE_SIZE; i++)
150 count += scnprintf(buf + count, PAGE_SIZE - count, "%c %d - %s\n", 151 count += scnprintf(buf + count, PAGE_SIZE - count, "%d:%s%c",
151 i == priv->cur_chan ? '*' : ' ', i, 152 i, priv->chan[i].parent_np->full_name,
152 priv->chan[i].parent_np->full_name); 153 i == priv->num_chan - 1 ? '\n' : ' ');
153 154
154 return count; 155 return count;
155} 156}
157static DEVICE_ATTR_RO(available_masters);
156 158
157static ssize_t cur_master_store(struct device *dev, struct device_attribute *attr, 159static ssize_t current_master_show(struct device *dev,
158 const char *buf, size_t count) 160 struct device_attribute *attr,
161 char *buf)
162{
163 struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
164
165 return sprintf(buf, "%d\n", priv->cur_chan);
166}
167
168static ssize_t current_master_store(struct device *dev,
169 struct device_attribute *attr,
170 const char *buf, size_t count)
159{ 171{
160 struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev); 172 struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
161 unsigned int val; 173 unsigned int val;
@@ -172,7 +184,7 @@ static ssize_t cur_master_store(struct device *dev, struct device_attribute *att
172 184
173 return ret < 0 ? ret : count; 185 return ret < 0 ? ret : count;
174} 186}
175static DEVICE_ATTR_RW(cur_master); 187static DEVICE_ATTR_RW(current_master);
176 188
177static int i2c_demux_pinctrl_probe(struct platform_device *pdev) 189static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
178{ 190{
@@ -218,12 +230,18 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
218 /* switch to first parent as active master */ 230 /* switch to first parent as active master */
219 i2c_demux_activate_master(priv, 0); 231 i2c_demux_activate_master(priv, 0);
220 232
221 err = device_create_file(&pdev->dev, &dev_attr_cur_master); 233 err = device_create_file(&pdev->dev, &dev_attr_available_masters);
222 if (err) 234 if (err)
223 goto err_rollback; 235 goto err_rollback;
224 236
237 err = device_create_file(&pdev->dev, &dev_attr_current_master);
238 if (err)
239 goto err_rollback_available;
240
225 return 0; 241 return 0;
226 242
243err_rollback_available:
244 device_remove_file(&pdev->dev, &dev_attr_available_masters);
227err_rollback: 245err_rollback:
228 for (j = 0; j < i; j++) { 246 for (j = 0; j < i; j++) {
229 of_node_put(priv->chan[j].parent_np); 247 of_node_put(priv->chan[j].parent_np);
@@ -238,7 +256,8 @@ static int i2c_demux_pinctrl_remove(struct platform_device *pdev)
238 struct i2c_demux_pinctrl_priv *priv = platform_get_drvdata(pdev); 256 struct i2c_demux_pinctrl_priv *priv = platform_get_drvdata(pdev);
239 int i; 257 int i;
240 258
241 device_remove_file(&pdev->dev, &dev_attr_cur_master); 259 device_remove_file(&pdev->dev, &dev_attr_current_master);
260 device_remove_file(&pdev->dev, &dev_attr_available_masters);
242 261
243 i2c_demux_deactivate_master(priv); 262 i2c_demux_deactivate_master(priv);
244 263