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
This commit is contained in:
Коммит
6a7c924314
|
@ -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'.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче