Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 11 Apr 2016 00:04:42 +0000 (17:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 11 Apr 2016 00:04:42 +0000 (17:04 -0700)
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

Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl
drivers/i2c/busses/i2c-jz4780.c
drivers/i2c/i2c-core.c
drivers/i2c/muxes/i2c-demux-pinctrl.c

index 7ac7d7262bb718f7d9e1d5e60c14491a4d7e7db0..3c3514815cd53bada6852068370d7cd193be9293 100644 (file)
@@ -1,23 +1,18 @@
-What:          /sys/devices/platform/<i2c-demux-name>/cur_master
+What:          /sys/devices/platform/<i2c-demux-name>/available_masters
 Date:          January 2016
 KernelVersion: 4.6
 Contact:       Wolfram Sang <wsa@the-dreams.de>
 Description:
+               Reading the file will give you a list of masters which can be
+               selected for a demultiplexed bus. The format is
+               "<index>:<name>". Example from a Renesas Lager board:
 
-This file selects the active I2C master for a demultiplexed bus.
+               0:/i2c@e6500000 1:/i2c@e6508000
 
-Write 0 there for the first master, 1 for the second etc. Reading the file will
-give you a list with the active master marked. Example from a Renesas Lager
-board:
-
-root@Lager:~# cat /sys/devices/platform/i2c@8/cur_master
-* 0 - /i2c@9
-  1 - /i2c@e6520000
-  2 - /i2c@e6530000
-
-root@Lager:~# echo 2 > /sys/devices/platform/i2c@8/cur_master
-
-root@Lager:~# cat /sys/devices/platform/i2c@8/cur_master
-  0 - /i2c@9
-  1 - /i2c@e6520000
-* 2 - /i2c@e6530000
+What:          /sys/devices/platform/<i2c-demux-name>/current_master
+Date:          January 2016
+KernelVersion: 4.6
+Contact:       Wolfram Sang <wsa@the-dreams.de>
+Description:
+               This file selects/shows the active I2C master for a demultiplexed
+               bus. It uses the <index> value from the file 'available_masters'.
index f325663c27c532645a1901a385ac6d52543e5ba5..ba14a863b451f943ea862bb94d2f808554a397d0 100644 (file)
@@ -771,11 +771,16 @@ static int jz4780_i2c_probe(struct platform_device *pdev)
        ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
                                   &clk_freq);
        if (ret) {
-               dev_err(&pdev->dev, "clock-frequency not specified in DT");
+               dev_err(&pdev->dev, "clock-frequency not specified in DT\n");
                goto err;
        }
 
        i2c->speed = clk_freq / 1000;
+       if (i2c->speed == 0) {
+               ret = -EINVAL;
+               dev_err(&pdev->dev, "clock-frequency minimum is 1000\n");
+               goto err;
+       }
        jz4780_i2c_set_speed(i2c);
 
        dev_info(&pdev->dev, "Bus frequency is %d KHz\n", i2c->speed);
index 0f2f8484e8ec1f51ca8e265bd160d3cbee5c7885..e584d88ee337f66e158644076f7b9a2b0018177e 100644 (file)
@@ -525,22 +525,16 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
        return 0;
 }
 
-
-/* uevent helps with hotplug: modprobe -q $(MODALIAS) */
 static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
-       struct i2c_client       *client = to_i2c_client(dev);
+       struct i2c_client *client = to_i2c_client(dev);
        int rc;
 
        rc = acpi_device_uevent_modalias(dev, env);
        if (rc != -ENODEV)
                return rc;
 
-       if (add_uevent_var(env, "MODALIAS=%s%s",
-                          I2C_MODULE_PREFIX, client->name))
-               return -ENOMEM;
-       dev_dbg(dev, "uevent\n");
-       return 0;
+       return add_uevent_var(env, "MODALIAS=%s%s", I2C_MODULE_PREFIX, client->name);
 }
 
 /* i2c bus recovery routines */
index 7748a0a5ddb9f1cabba4f5318078afdddc614bc9..8de073aed001482461b3ad12398c00fa9417fc95 100644 (file)
@@ -140,22 +140,34 @@ static int i2c_demux_change_master(struct i2c_demux_pinctrl_priv *priv, u32 new_
        return i2c_demux_activate_master(priv, new_chan);
 }
 
-static ssize_t cur_master_show(struct device *dev, struct device_attribute *attr,
-                          char *buf)
+static ssize_t available_masters_show(struct device *dev,
+                                     struct device_attribute *attr,
+                                     char *buf)
 {
        struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
        int count = 0, i;
 
        for (i = 0; i < priv->num_chan && count < PAGE_SIZE; i++)
-               count += scnprintf(buf + count, PAGE_SIZE - count, "%c %d - %s\n",
-                                i == priv->cur_chan ? '*' : ' ', i,
-                                priv->chan[i].parent_np->full_name);
+               count += scnprintf(buf + count, PAGE_SIZE - count, "%d:%s%c",
+                                  i, priv->chan[i].parent_np->full_name,
+                                  i == priv->num_chan - 1 ? '\n' : ' ');
 
        return count;
 }
+static DEVICE_ATTR_RO(available_masters);
 
-static ssize_t cur_master_store(struct device *dev, struct device_attribute *attr,
-                           const char *buf, size_t count)
+static ssize_t current_master_show(struct device *dev,
+                                  struct device_attribute *attr,
+                                  char *buf)
+{
+       struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d\n", priv->cur_chan);
+}
+
+static ssize_t current_master_store(struct device *dev,
+                                   struct device_attribute *attr,
+                                   const char *buf, size_t count)
 {
        struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
        unsigned int val;
@@ -172,7 +184,7 @@ static ssize_t cur_master_store(struct device *dev, struct device_attribute *att
 
        return ret < 0 ? ret : count;
 }
-static DEVICE_ATTR_RW(cur_master);
+static DEVICE_ATTR_RW(current_master);
 
 static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
 {
@@ -218,12 +230,18 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
        /* switch to first parent as active master */
        i2c_demux_activate_master(priv, 0);
 
-       err = device_create_file(&pdev->dev, &dev_attr_cur_master);
+       err = device_create_file(&pdev->dev, &dev_attr_available_masters);
        if (err)
                goto err_rollback;
 
+       err = device_create_file(&pdev->dev, &dev_attr_current_master);
+       if (err)
+               goto err_rollback_available;
+
        return 0;
 
+err_rollback_available:
+       device_remove_file(&pdev->dev, &dev_attr_available_masters);
 err_rollback:
        for (j = 0; j < i; j++) {
                of_node_put(priv->chan[j].parent_np);
@@ -238,7 +256,8 @@ static int i2c_demux_pinctrl_remove(struct platform_device *pdev)
        struct i2c_demux_pinctrl_priv *priv = platform_get_drvdata(pdev);
        int i;
 
-       device_remove_file(&pdev->dev, &dev_attr_cur_master);
+       device_remove_file(&pdev->dev, &dev_attr_current_master);
+       device_remove_file(&pdev->dev, &dev_attr_available_masters);
 
        i2c_demux_deactivate_master(priv);