All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Add parameters for sysfs added I2C devices
@ 2016-05-10 16:11 minyard
  2016-05-10 16:11 ` [PATCH v2 1/3] i2c: Add parameters to sysfs-added i2c devices minyard
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: minyard @ 2016-05-10 16:11 UTC (permalink / raw)
  To: Wolfram Sang, linux-i2c, Jean Delvare; +Cc: minyard

This is a set of patches I posted earlier, it allows you to pass in
parameters when adding I2C devices through sysfs.

I really need this for the IPMI over I2C driver (The SSIF driver)
for a couple of reasons.

The SSIF driver itself needs to take a parameter to tell it's
address on the IPMI bus in case it's not the default.  It's also
nice to be able to pass in debug parameters this way.

Second, the IPMI driver can use SMBus alerts, but if the SMBus
alert device is added via sysfs, there is no way to specify the
interrupt information, thus it's fairly useless.

The first patch adds the ability to have parameters for sysfs added
I2C devices.  The second patch adds interrupt parameters for the
SMBus alert device.  The last is the IPMI SSIF changes, just for
example, I can add those in the IPMI tree.

-corey

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/3] i2c: Add parameters to sysfs-added i2c devices
  2016-05-10 16:11 [PATCH v2 0/3] Add parameters for sysfs added I2C devices minyard
@ 2016-05-10 16:11 ` minyard
  2016-05-11 17:23   ` Naveen Kaje
  2021-06-25 14:14   ` Wolfram Sang
  2016-05-10 16:11 ` [PATCH v2 2/3] i2c-smbus: Allow parms to be passed in from sysfs new_device minyard
  2016-05-10 16:11 ` [PATCH v2 3/3] ipmi: Handle I2C parms in the SSIF driver minyard
  2 siblings, 2 replies; 8+ messages in thread
From: minyard @ 2016-05-10 16:11 UTC (permalink / raw)
  To: Wolfram Sang, linux-i2c, Jean Delvare; +Cc: minyard, Corey Minyard

From: Corey Minyard <cminyard@mvista.com>

Some devices might need parameters to control their operation,
add the ability to pass these parameters to the client.

This also makes the parsing of sysfs-added I2C devices a little
more flexible, allowing tabs and arbitrary numbers of spaces.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
 drivers/i2c/i2c-core.c | 43 +++++++++++++++++++++++++++++++------------
 include/linux/i2c.h    |  3 +++
 2 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index e584d88..069c385 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -51,6 +51,7 @@
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_wakeirq.h>
+#include <linux/ctype.h>
 #include <linux/property.h>
 #include <linux/rwsem.h>
 #include <linux/slab.h>
@@ -780,7 +781,10 @@ static void i2c_device_shutdown(struct device *dev)
 
 static void i2c_client_dev_release(struct device *dev)
 {
-	kfree(to_i2c_client(dev));
+	struct i2c_client *client = to_i2c_client(dev);
+
+	kfree(client->parms);
+	kfree(client);
 }
 
 static ssize_t
@@ -1047,6 +1051,13 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
 	client->flags = info->flags;
 	client->addr = info->addr;
 	client->irq = info->irq;
+	if (info->parms) {
+		client->parms = kstrdup(info->parms, GFP_KERNEL);
+		if (!client->parms) {
+			dev_err(&adap->dev, "Out of memory allocating parms\n");
+			goto out_err_silent;
+		}
+	}
 
 	strlcpy(client->name, info->type, sizeof(client->name));
 
@@ -1196,31 +1207,39 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
 	struct i2c_adapter *adap = to_i2c_adapter(dev);
 	struct i2c_board_info info;
 	struct i2c_client *client;
-	char *blank, end;
+	char *pos, end;
 	int res;
 
 	memset(&info, 0, sizeof(struct i2c_board_info));
 
-	blank = strchr(buf, ' ');
-	if (!blank) {
+	pos = strpbrk(buf, " \t");
+	if (!pos) {
 		dev_err(dev, "%s: Missing parameters\n", "new_device");
 		return -EINVAL;
 	}
-	if (blank - buf > I2C_NAME_SIZE - 1) {
+	if (pos - buf > I2C_NAME_SIZE - 1) {
 		dev_err(dev, "%s: Invalid device name\n", "new_device");
 		return -EINVAL;
 	}
-	memcpy(info.type, buf, blank - buf);
+	memcpy(info.type, buf, pos - buf);
 
-	/* Parse remaining parameters, reject extra parameters */
-	res = sscanf(++blank, "%hi%c", &info.addr, &end);
-	if (res < 1) {
+	while (isspace(*pos))
+		pos++;
+
+	/* Parse address, saving remaining parameters. */
+	res = sscanf(pos, "%hi%c", &info.addr, &end);
+	if (res < 1 || (res > 1 && !isspace(end))) {
 		dev_err(dev, "%s: Can't parse I2C address\n", "new_device");
 		return -EINVAL;
 	}
-	if (res > 1  && end != '\n') {
-		dev_err(dev, "%s: Extra parameters\n", "new_device");
-		return -EINVAL;
+	if (res > 1) {
+		/* Extra parms, skip the address and space. */
+		while (!isspace(*pos))
+			pos++;
+		while (isspace(*pos))
+			pos++;
+		if (*pos)
+			info.parms = pos;
 	}
 
 	if ((info.addr & I2C_ADDR_OFFSET_TEN_BIT) == I2C_ADDR_OFFSET_TEN_BIT) {
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 200cf13b..35db0dd 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -225,6 +225,7 @@ struct i2c_client {
 	char name[I2C_NAME_SIZE];
 	struct i2c_adapter *adapter;	/* the adapter we sit on	*/
 	struct device dev;		/* the device structure		*/
+	char *parms;			/* sysfs extra parms		*/
 	int irq;			/* irq issued by device		*/
 	struct list_head detected;
 #if IS_ENABLED(CONFIG_I2C_SLAVE)
@@ -282,6 +283,7 @@ static inline int i2c_slave_event(struct i2c_client *client,
  * @archdata: copied into i2c_client.dev.archdata
  * @of_node: pointer to OpenFirmware device node
  * @fwnode: device node supplied by the platform firmware
+ * @parms: Parameters supplied on the sysfs command line
  * @irq: stored in i2c_client.irq
  *
  * I2C doesn't actually support hardware probing, although controllers and
@@ -303,6 +305,7 @@ struct i2c_board_info {
 	struct dev_archdata	*archdata;
 	struct device_node *of_node;
 	struct fwnode_handle *fwnode;
+	char            *parms;
 	int		irq;
 };
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/3] i2c-smbus: Allow parms to be passed in from sysfs new_device
  2016-05-10 16:11 [PATCH v2 0/3] Add parameters for sysfs added I2C devices minyard
  2016-05-10 16:11 ` [PATCH v2 1/3] i2c: Add parameters to sysfs-added i2c devices minyard
@ 2016-05-10 16:11 ` minyard
  2016-05-11 17:26   ` Naveen Kaje
  2016-05-10 16:11 ` [PATCH v2 3/3] ipmi: Handle I2C parms in the SSIF driver minyard
  2 siblings, 1 reply; 8+ messages in thread
From: minyard @ 2016-05-10 16:11 UTC (permalink / raw)
  To: Wolfram Sang, linux-i2c, Jean Delvare; +Cc: minyard, Corey Minyard

From: Corey Minyard <cminyard@mvista.com>

This allows "irq=<num>" and "edge" to be passed in to the i2c new_device
after the name and i2c address.  This way the alert can be configured
without having to have platform data.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
 drivers/i2c/i2c-smbus.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
index 7748fd6..4f099ad 100644
--- a/drivers/i2c/i2c-smbus.c
+++ b/drivers/i2c/i2c-smbus.c
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
+#include <linux/ctype.h>
 
 struct i2c_smbus_alert {
 	unsigned int		alert_edge_triggered:1;
@@ -123,15 +124,86 @@ static irqreturn_t smbalert_irq(int irq, void *d)
 	return IRQ_HANDLED;
 }
 
+static struct i2c_smbus_alert_setup *smbalert_parse_parms(struct device *dev,
+		const char *parms,
+		struct i2c_smbus_alert_setup *data)
+{
+	int rv;
+	char end;
+
+	if (!parms)
+		return NULL;
+
+	data->alert_edge_triggered = false;
+	while (*parms) {
+		const char *next = parms;
+		const char *val;
+		int parmlen;
+
+		while (*next && !isspace(*next) && *next != '=')
+			next++;
+
+		parmlen = next - parms;
+
+		if (*next == '=') {
+			next++;
+			val = next;
+			while (*next && !isspace(*next))
+				next++;
+		} else {
+			val = NULL;
+		}
+
+		if (strncmp(parms, "irq", parmlen) == 0) {
+			if (!val) {
+				dev_err(dev, "no irq parm value given\n");
+				return NULL;
+			}
+			rv = sscanf(val, "%d%c", &data->irq, &end);
+			if ((rv < 1) || ((rv > 1) && !isspace(end))) {
+				dev_err(dev, "Invalid irq parm: %s\n", val);
+				return NULL;
+			}
+		} else if (strncmp(parms, "edge", parmlen) == 0) {
+			if (val) {
+				dev_err(dev, "Value given with edge parm: %s\n",
+					val);
+				return NULL;
+			}
+			data->alert_edge_triggered = true;
+		} else {
+			dev_err(dev, "Invalid parameter: %s\n", parms);
+			return NULL;
+		}
+
+		while (*next && isspace(*next))
+			next++;
+		parms = next;
+	}
+
+	return data;
+}
+
 /* Setup SMBALERT# infrastructure */
 static int smbalert_probe(struct i2c_client *ara,
 			  const struct i2c_device_id *id)
 {
 	struct i2c_smbus_alert_setup *setup = dev_get_platdata(&ara->dev);
+	struct i2c_smbus_alert_setup dummy_setup;
 	struct i2c_smbus_alert *alert;
 	struct i2c_adapter *adapter = ara->adapter;
 	int res;
 
+	if (ara->parms)
+		/* Came in through sysfs. */
+		setup = smbalert_parse_parms(&ara->dev, ara->parms,
+					     &dummy_setup);
+
+	if (!setup) {
+		dev_err(&ara->dev, "SMBus alert without setup\n");
+		return -ENODEV;
+	}
+
 	alert = devm_kzalloc(&ara->dev, sizeof(struct i2c_smbus_alert),
 			     GFP_KERNEL);
 	if (!alert)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/3] ipmi: Handle I2C parms in the SSIF driver.
  2016-05-10 16:11 [PATCH v2 0/3] Add parameters for sysfs added I2C devices minyard
  2016-05-10 16:11 ` [PATCH v2 1/3] i2c: Add parameters to sysfs-added i2c devices minyard
  2016-05-10 16:11 ` [PATCH v2 2/3] i2c-smbus: Allow parms to be passed in from sysfs new_device minyard
@ 2016-05-10 16:11 ` minyard
  2016-05-11 17:26   ` Naveen Kaje
  2 siblings, 1 reply; 8+ messages in thread
From: minyard @ 2016-05-10 16:11 UTC (permalink / raw)
  To: Wolfram Sang, linux-i2c, Jean Delvare; +Cc: minyard, Corey Minyard

From: Corey Minyard <cminyard@mvista.com>

Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
 drivers/char/ipmi/ipmi_ssif.c | 62 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 61 insertions(+), 1 deletion(-)

diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
index 097c868..bbd9744 100644
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -200,7 +200,7 @@ struct ssif_info {
 	struct ipmi_smi_msg *waiting_msg;
 	struct ipmi_smi_msg *curr_msg;
 	enum ssif_intf_state ssif_state;
-	unsigned long       ssif_debug;
+	unsigned int        ssif_debug;
 
 	struct ipmi_smi_handlers handlers;
 
@@ -1386,6 +1386,60 @@ restart:
 	return found;
 }
 
+static int ssif_parse_parms(struct ssif_info *ssif_info,
+			    const char *parms, u8 *slave_addr)
+{
+	int rv;
+	char end;
+
+	if (!parms)
+		return 0;
+
+	while (*parms) {
+		const char *next = parms;
+		const char *val;
+		int parmlen;
+
+		while (*next && !isspace(*next) && *next != '=')
+			next++;
+
+		if (*next != '=') {
+			pr_err("IPMI SSIF invalid parm starting at %s\n",
+			       parms);
+			return -EINVAL;
+		}
+
+		parmlen = next - parms;
+		next++;
+		val = next;
+		while (*next && !isspace(*next))
+			next++;
+
+		if (strncmp(parms, "ipmb", parmlen) == 0) {
+			rv = sscanf(val, "%hhx%c", slave_addr, &end);
+			if ((rv < 1) || ((rv > 1) && !isspace(end))) {
+				pr_err("Invalid ipmb address: %s\n", val);
+				return -EINVAL;
+			}
+		} else if (strncmp(parms, "debug", parmlen) == 0) {
+			rv = sscanf(val, "%i%c", &ssif_info->ssif_debug, &end);
+			if ((rv < 1) || ((rv > 1) && !isspace(end))) {
+				pr_err("Invalid debug value: %s\n", val);
+				return -EINVAL;
+			}
+		} else {
+			pr_err("Invalid IPMI SSIF parameter: %s\n", parms);
+			return -EINVAL;
+		}
+
+		while (*next && isspace(*next))
+			next++;
+		parms = next;
+	}
+
+	return 0;
+}
+
 static bool check_acpi(struct ssif_info *ssif_info, struct device *dev)
 {
 #ifdef CONFIG_ACPI
@@ -1435,6 +1489,12 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		if (!addr_info) {
 			/* Must have come in through sysfs. */
 			ssif_info->addr_source = SI_HOTMOD;
+			rv = ssif_parse_parms(ssif_info, client->parms,
+					      &slave_addr);
+			if (rv) {
+				pr_err(PFX "Unable to parse parms from i2c\n");
+				goto out;
+			}
 		} else {
 			ssif_info->addr_source = addr_info->addr_src;
 			ssif_info->ssif_debug = addr_info->debug;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/3] i2c: Add parameters to sysfs-added i2c devices
  2016-05-10 16:11 ` [PATCH v2 1/3] i2c: Add parameters to sysfs-added i2c devices minyard
@ 2016-05-11 17:23   ` Naveen Kaje
  2021-06-25 14:14   ` Wolfram Sang
  1 sibling, 0 replies; 8+ messages in thread
From: Naveen Kaje @ 2016-05-11 17:23 UTC (permalink / raw)
  To: minyard, Wolfram Sang, linux-i2c, Jean Delvare; +Cc: Corey Minyard



On 5/10/2016 10:11 AM, minyard@acm.org wrote:
> From: Corey Minyard <cminyard@mvista.com>
>
> Some devices might need parameters to control their operation,
> add the ability to pass these parameters to the client.
>
> This also makes the parsing of sysfs-added I2C devices a little
> more flexible, allowing tabs and arbitrary numbers of spaces.
>
> Signed-off-by: Corey Minyard <cminyard@mvista.com>
Tested on QDF2432 with I2C IPMI client to ensure no regressions are 
introduced.
Tested-by: Naveen Kaje <nkaje@codeaurora.org>

> ---
>   drivers/i2c/i2c-core.c | 43 +++++++++++++++++++++++++++++++------------
>   include/linux/i2c.h    |  3 +++
>   2 files changed, 34 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> index e584d88..069c385 100644
> --- a/drivers/i2c/i2c-core.c
> +++ b/drivers/i2c/i2c-core.c
> @@ -51,6 +51,7 @@
>   #include <linux/pm_domain.h>
>   #include <linux/pm_runtime.h>
>   #include <linux/pm_wakeirq.h>
> +#include <linux/ctype.h>
>   #include <linux/property.h>
>   #include <linux/rwsem.h>
>   #include <linux/slab.h>
> @@ -780,7 +781,10 @@ static void i2c_device_shutdown(struct device *dev)
>   
>   static void i2c_client_dev_release(struct device *dev)
>   {
> -	kfree(to_i2c_client(dev));
> +	struct i2c_client *client = to_i2c_client(dev);
> +
> +	kfree(client->parms);
> +	kfree(client);
>   }
>   
>   static ssize_t
> @@ -1047,6 +1051,13 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
>   	client->flags = info->flags;
>   	client->addr = info->addr;
>   	client->irq = info->irq;
> +	if (info->parms) {
> +		client->parms = kstrdup(info->parms, GFP_KERNEL);
> +		if (!client->parms) {
> +			dev_err(&adap->dev, "Out of memory allocating parms\n");
> +			goto out_err_silent;
> +		}
> +	}
>   
>   	strlcpy(client->name, info->type, sizeof(client->name));
>   
> @@ -1196,31 +1207,39 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
>   	struct i2c_adapter *adap = to_i2c_adapter(dev);
>   	struct i2c_board_info info;
>   	struct i2c_client *client;
> -	char *blank, end;
> +	char *pos, end;
>   	int res;
>   
>   	memset(&info, 0, sizeof(struct i2c_board_info));
>   
> -	blank = strchr(buf, ' ');
> -	if (!blank) {
> +	pos = strpbrk(buf, " \t");
> +	if (!pos) {
>   		dev_err(dev, "%s: Missing parameters\n", "new_device");
>   		return -EINVAL;
>   	}
> -	if (blank - buf > I2C_NAME_SIZE - 1) {
> +	if (pos - buf > I2C_NAME_SIZE - 1) {
>   		dev_err(dev, "%s: Invalid device name\n", "new_device");
>   		return -EINVAL;
>   	}
> -	memcpy(info.type, buf, blank - buf);
> +	memcpy(info.type, buf, pos - buf);
>   
> -	/* Parse remaining parameters, reject extra parameters */
> -	res = sscanf(++blank, "%hi%c", &info.addr, &end);
> -	if (res < 1) {
> +	while (isspace(*pos))
> +		pos++;
> +
> +	/* Parse address, saving remaining parameters. */
> +	res = sscanf(pos, "%hi%c", &info.addr, &end);
> +	if (res < 1 || (res > 1 && !isspace(end))) {
>   		dev_err(dev, "%s: Can't parse I2C address\n", "new_device");
>   		return -EINVAL;
>   	}
> -	if (res > 1  && end != '\n') {
> -		dev_err(dev, "%s: Extra parameters\n", "new_device");
> -		return -EINVAL;
> +	if (res > 1) {
> +		/* Extra parms, skip the address and space. */
> +		while (!isspace(*pos))
> +			pos++;
> +		while (isspace(*pos))
> +			pos++;
> +		if (*pos)
> +			info.parms = pos;
>   	}
>   
>   	if ((info.addr & I2C_ADDR_OFFSET_TEN_BIT) == I2C_ADDR_OFFSET_TEN_BIT) {
> diff --git a/include/linux/i2c.h b/include/linux/i2c.h
> index 200cf13b..35db0dd 100644
> --- a/include/linux/i2c.h
> +++ b/include/linux/i2c.h
> @@ -225,6 +225,7 @@ struct i2c_client {
>   	char name[I2C_NAME_SIZE];
>   	struct i2c_adapter *adapter;	/* the adapter we sit on	*/
>   	struct device dev;		/* the device structure		*/
> +	char *parms;			/* sysfs extra parms		*/
>   	int irq;			/* irq issued by device		*/
>   	struct list_head detected;
>   #if IS_ENABLED(CONFIG_I2C_SLAVE)
> @@ -282,6 +283,7 @@ static inline int i2c_slave_event(struct i2c_client *client,
>    * @archdata: copied into i2c_client.dev.archdata
>    * @of_node: pointer to OpenFirmware device node
>    * @fwnode: device node supplied by the platform firmware
> + * @parms: Parameters supplied on the sysfs command line
>    * @irq: stored in i2c_client.irq
>    *
>    * I2C doesn't actually support hardware probing, although controllers and
> @@ -303,6 +305,7 @@ struct i2c_board_info {
>   	struct dev_archdata	*archdata;
>   	struct device_node *of_node;
>   	struct fwnode_handle *fwnode;
> +	char            *parms;
>   	int		irq;
>   };
>   

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/3] i2c-smbus: Allow parms to be passed in from sysfs new_device
  2016-05-10 16:11 ` [PATCH v2 2/3] i2c-smbus: Allow parms to be passed in from sysfs new_device minyard
@ 2016-05-11 17:26   ` Naveen Kaje
  0 siblings, 0 replies; 8+ messages in thread
From: Naveen Kaje @ 2016-05-11 17:26 UTC (permalink / raw)
  To: minyard, Wolfram Sang, linux-i2c, Jean Delvare; +Cc: Corey Minyard



On 5/10/2016 10:11 AM, minyard@acm.org wrote:
> From: Corey Minyard <cminyard@mvista.com>
>
> This allows "irq=<num>" and "edge" to be passed in to the i2c new_device
> after the name and i2c address.  This way the alert can be configured
> without having to have platform data.
>
> Signed-off-by: Corey Minyard <cminyard@mvista.com>
Tested on QDF2432 with I2C IPMI client to ensure no regressions are 
introduced.
Tested-by: Naveen Kaje <nkaje@codeaurora.org>
> ---
>   drivers/i2c/i2c-smbus.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 72 insertions(+)
>
> diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
> index 7748fd6..4f099ad 100644
> --- a/drivers/i2c/i2c-smbus.c
> +++ b/drivers/i2c/i2c-smbus.c
> @@ -23,6 +23,7 @@
>   #include <linux/module.h>
>   #include <linux/slab.h>
>   #include <linux/workqueue.h>
> +#include <linux/ctype.h>
>   
>   struct i2c_smbus_alert {
>   	unsigned int		alert_edge_triggered:1;
> @@ -123,15 +124,86 @@ static irqreturn_t smbalert_irq(int irq, void *d)
>   	return IRQ_HANDLED;
>   }
>   
> +static struct i2c_smbus_alert_setup *smbalert_parse_parms(struct device *dev,
> +		const char *parms,
> +		struct i2c_smbus_alert_setup *data)
> +{
> +	int rv;
> +	char end;
> +
> +	if (!parms)
> +		return NULL;
> +
> +	data->alert_edge_triggered = false;
> +	while (*parms) {
> +		const char *next = parms;
> +		const char *val;
> +		int parmlen;
> +
> +		while (*next && !isspace(*next) && *next != '=')
> +			next++;
> +
> +		parmlen = next - parms;
> +
> +		if (*next == '=') {
> +			next++;
> +			val = next;
> +			while (*next && !isspace(*next))
> +				next++;
> +		} else {
> +			val = NULL;
> +		}
> +
> +		if (strncmp(parms, "irq", parmlen) == 0) {
> +			if (!val) {
> +				dev_err(dev, "no irq parm value given\n");
> +				return NULL;
> +			}
> +			rv = sscanf(val, "%d%c", &data->irq, &end);
> +			if ((rv < 1) || ((rv > 1) && !isspace(end))) {
> +				dev_err(dev, "Invalid irq parm: %s\n", val);
> +				return NULL;
> +			}
> +		} else if (strncmp(parms, "edge", parmlen) == 0) {
> +			if (val) {
> +				dev_err(dev, "Value given with edge parm: %s\n",
> +					val);
> +				return NULL;
> +			}
> +			data->alert_edge_triggered = true;
> +		} else {
> +			dev_err(dev, "Invalid parameter: %s\n", parms);
> +			return NULL;
> +		}
> +
> +		while (*next && isspace(*next))
> +			next++;
> +		parms = next;
> +	}
> +
> +	return data;
> +}
> +
>   /* Setup SMBALERT# infrastructure */
>   static int smbalert_probe(struct i2c_client *ara,
>   			  const struct i2c_device_id *id)
>   {
>   	struct i2c_smbus_alert_setup *setup = dev_get_platdata(&ara->dev);
> +	struct i2c_smbus_alert_setup dummy_setup;
>   	struct i2c_smbus_alert *alert;
>   	struct i2c_adapter *adapter = ara->adapter;
>   	int res;
>   
> +	if (ara->parms)
> +		/* Came in through sysfs. */
> +		setup = smbalert_parse_parms(&ara->dev, ara->parms,
> +					     &dummy_setup);
> +
> +	if (!setup) {
> +		dev_err(&ara->dev, "SMBus alert without setup\n");
> +		return -ENODEV;
> +	}
> +
>   	alert = devm_kzalloc(&ara->dev, sizeof(struct i2c_smbus_alert),
>   			     GFP_KERNEL);
>   	if (!alert)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 3/3] ipmi: Handle I2C parms in the SSIF driver.
  2016-05-10 16:11 ` [PATCH v2 3/3] ipmi: Handle I2C parms in the SSIF driver minyard
@ 2016-05-11 17:26   ` Naveen Kaje
  0 siblings, 0 replies; 8+ messages in thread
From: Naveen Kaje @ 2016-05-11 17:26 UTC (permalink / raw)
  To: minyard, Wolfram Sang, linux-i2c, Jean Delvare; +Cc: Corey Minyard



On 5/10/2016 10:11 AM, minyard@acm.org wrote:
> From: Corey Minyard <cminyard@mvista.com>
>
> Signed-off-by: Corey Minyard <cminyard@mvista.com>
Tested on QDF2432 with I2C IPMI client to ensure no regressions are 
introduced.
Tested-by: Naveen Kaje <nkaje@codeaurora.org>
> ---
>   drivers/char/ipmi/ipmi_ssif.c | 62 ++++++++++++++++++++++++++++++++++++++++++-
>   1 file changed, 61 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
> index 097c868..bbd9744 100644
> --- a/drivers/char/ipmi/ipmi_ssif.c
> +++ b/drivers/char/ipmi/ipmi_ssif.c
> @@ -200,7 +200,7 @@ struct ssif_info {
>   	struct ipmi_smi_msg *waiting_msg;
>   	struct ipmi_smi_msg *curr_msg;
>   	enum ssif_intf_state ssif_state;
> -	unsigned long       ssif_debug;
> +	unsigned int        ssif_debug;
>   
>   	struct ipmi_smi_handlers handlers;
>   
> @@ -1386,6 +1386,60 @@ restart:
>   	return found;
>   }
>   
> +static int ssif_parse_parms(struct ssif_info *ssif_info,
> +			    const char *parms, u8 *slave_addr)
> +{
> +	int rv;
> +	char end;
> +
> +	if (!parms)
> +		return 0;
> +
> +	while (*parms) {
> +		const char *next = parms;
> +		const char *val;
> +		int parmlen;
> +
> +		while (*next && !isspace(*next) && *next != '=')
> +			next++;
> +
> +		if (*next != '=') {
> +			pr_err("IPMI SSIF invalid parm starting at %s\n",
> +			       parms);
> +			return -EINVAL;
> +		}
> +
> +		parmlen = next - parms;
> +		next++;
> +		val = next;
> +		while (*next && !isspace(*next))
> +			next++;
> +
> +		if (strncmp(parms, "ipmb", parmlen) == 0) {
> +			rv = sscanf(val, "%hhx%c", slave_addr, &end);
> +			if ((rv < 1) || ((rv > 1) && !isspace(end))) {
> +				pr_err("Invalid ipmb address: %s\n", val);
> +				return -EINVAL;
> +			}
> +		} else if (strncmp(parms, "debug", parmlen) == 0) {
> +			rv = sscanf(val, "%i%c", &ssif_info->ssif_debug, &end);
> +			if ((rv < 1) || ((rv > 1) && !isspace(end))) {
> +				pr_err("Invalid debug value: %s\n", val);
> +				return -EINVAL;
> +			}
> +		} else {
> +			pr_err("Invalid IPMI SSIF parameter: %s\n", parms);
> +			return -EINVAL;
> +		}
> +
> +		while (*next && isspace(*next))
> +			next++;
> +		parms = next;
> +	}
> +
> +	return 0;
> +}
> +
>   static bool check_acpi(struct ssif_info *ssif_info, struct device *dev)
>   {
>   #ifdef CONFIG_ACPI
> @@ -1435,6 +1489,12 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
>   		if (!addr_info) {
>   			/* Must have come in through sysfs. */
>   			ssif_info->addr_source = SI_HOTMOD;
> +			rv = ssif_parse_parms(ssif_info, client->parms,
> +					      &slave_addr);
> +			if (rv) {
> +				pr_err(PFX "Unable to parse parms from i2c\n");
> +				goto out;
> +			}
>   		} else {
>   			ssif_info->addr_source = addr_info->addr_src;
>   			ssif_info->ssif_debug = addr_info->debug;

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/3] i2c: Add parameters to sysfs-added i2c devices
  2016-05-10 16:11 ` [PATCH v2 1/3] i2c: Add parameters to sysfs-added i2c devices minyard
  2016-05-11 17:23   ` Naveen Kaje
@ 2021-06-25 14:14   ` Wolfram Sang
  1 sibling, 0 replies; 8+ messages in thread
From: Wolfram Sang @ 2021-06-25 14:14 UTC (permalink / raw)
  To: minyard; +Cc: linux-i2c, Jean Delvare, Corey Minyard

[-- Attachment #1: Type: text/plain, Size: 504 bytes --]


> From: Corey Minyard <cminyard@mvista.com>
> 
> Some devices might need parameters to control their operation,
> add the ability to pass these parameters to the client.

Cleaning up old patches from patchwork once in a while...

I don't think it is a good way to add parsers to each and every I2C
client driver which wants to read extra parameters. Maybe there is a
more generic way to configure at runtime these days. I never needed
something like this, so sadly I can't give a pointer.


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-06-25 14:14 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-10 16:11 [PATCH v2 0/3] Add parameters for sysfs added I2C devices minyard
2016-05-10 16:11 ` [PATCH v2 1/3] i2c: Add parameters to sysfs-added i2c devices minyard
2016-05-11 17:23   ` Naveen Kaje
2021-06-25 14:14   ` Wolfram Sang
2016-05-10 16:11 ` [PATCH v2 2/3] i2c-smbus: Allow parms to be passed in from sysfs new_device minyard
2016-05-11 17:26   ` Naveen Kaje
2016-05-10 16:11 ` [PATCH v2 3/3] ipmi: Handle I2C parms in the SSIF driver minyard
2016-05-11 17:26   ` Naveen Kaje

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.