linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sebastian Reichel <sre@kernel.org>
To: "Sebastian Reichel" <sre@kernel.org>,
	"Tony Lindgren" <tony@atomide.com>,
	"Benoît Cousson" <bcousson@baylibre.com>,
	"Aaro Koskinen" <aaro.koskinen@iki.fi>
Cc: "Pali Rohár" <pali.rohar@gmail.com>,
	"Pavel Machek" <pavel@ucw.cz>,
	linux-omap@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 1/5] HSI: nokia-modem: simplify kernel access to gpios
Date: Sun, 31 Jan 2016 02:19:43 +0100	[thread overview]
Message-ID: <1454203187-688-2-git-send-email-sre@kernel.org> (raw)
In-Reply-To: <1454203187-688-1-git-send-email-sre@kernel.org>

For implementing kernel based modem power management, the
gpios should be accessible via name from the kernel. The
old code would require walking through the gpio array
comparing the name of each gpio. This is no longer needed
by the new code, which does the comparing once at probe
time. As a side effect the code now checks, that all
required gpios are provided.

Signed-off-by: Sebastian Reichel <sre@kernel.org>
---
 drivers/hsi/clients/nokia-modem.c | 115 ++++++++++++++++++++++++++++----------
 1 file changed, 85 insertions(+), 30 deletions(-)

diff --git a/drivers/hsi/clients/nokia-modem.c b/drivers/hsi/clients/nokia-modem.c
index c000780d931f..f20ede611593 100644
--- a/drivers/hsi/clients/nokia-modem.c
+++ b/drivers/hsi/clients/nokia-modem.c
@@ -34,19 +34,23 @@ module_param(pm, int, 0400);
 MODULE_PARM_DESC(pm,
 	"Enable power management (0=disabled, 1=userland based [default])");
 
-struct nokia_modem_gpio {
-	struct gpio_desc	*gpio;
-	const char		*name;
+enum nokia_modem_type {
+	RAPUYAMA_V1,
+	RAPUYAMA_V2,
 };
 
 struct nokia_modem_device {
 	struct tasklet_struct	nokia_modem_rst_ind_tasklet;
 	int			nokia_modem_rst_ind_irq;
 	struct device		*device;
-	struct nokia_modem_gpio	*gpios;
-	int			gpio_amount;
 	struct hsi_client	*ssi_protocol;
 	struct hsi_client	*cmt_speech;
+	enum nokia_modem_type	type;
+	struct gpio_desc        *gpio_cmt_en;
+	struct gpio_desc	*gpio_cmt_apeslpx;
+	struct gpio_desc	*gpio_cmt_rst_rq;
+	struct gpio_desc	*gpio_cmt_rst;
+	struct gpio_desc	*gpio_cmt_bsi;
 };
 
 static void do_nokia_modem_rst_ind_tasklet(unsigned long data)
@@ -74,11 +78,33 @@ static irqreturn_t nokia_modem_rst_ind_isr(int irq, void *data)
 static void nokia_modem_gpio_unexport(struct device *dev)
 {
 	struct nokia_modem_device *modem = dev_get_drvdata(dev);
-	int i;
 
-	for (i = 0; i < modem->gpio_amount; i++) {
-		sysfs_remove_link(&dev->kobj, modem->gpios[i].name);
-		gpiod_unexport(modem->gpios[i].gpio);
+	if (pm != 1)
+		return;
+
+	if (modem->gpio_cmt_en) {
+		sysfs_remove_link(&dev->kobj, "cmt_en");
+		gpiod_unexport(modem->gpio_cmt_en);
+	}
+
+	if (modem->gpio_cmt_apeslpx) {
+		sysfs_remove_link(&dev->kobj, "cmt_apeslpx");
+		gpiod_unexport(modem->gpio_cmt_apeslpx);
+	}
+
+	if (modem->gpio_cmt_rst_rq) {
+		sysfs_remove_link(&dev->kobj, "cmt_rst_rq");
+		gpiod_unexport(modem->gpio_cmt_rst_rq);
+	}
+
+	if (modem->gpio_cmt_rst) {
+		sysfs_remove_link(&dev->kobj, "cmt_rst");
+		gpiod_unexport(modem->gpio_cmt_rst);
+	}
+
+	if (modem->gpio_cmt_bsi) {
+		sysfs_remove_link(&dev->kobj, "cmt_bsi");
+		gpiod_unexport(modem->gpio_cmt_bsi);
 	}
 }
 
@@ -102,38 +128,61 @@ static int nokia_modem_gpio_probe(struct device *dev)
 		return -EINVAL;
 	}
 
-	modem->gpios = devm_kzalloc(dev, gpio_count *
-				sizeof(struct nokia_modem_gpio), GFP_KERNEL);
-	if (!modem->gpios) {
-		dev_err(dev, "Could not allocate memory for gpios\n");
-		return -ENOMEM;
-	}
-
-	modem->gpio_amount = gpio_count;
-
 	for (i = 0; i < gpio_count; i++) {
-		modem->gpios[i].gpio = devm_gpiod_get_index(dev, NULL, i,
-							    GPIOD_OUT_LOW);
-		if (IS_ERR(modem->gpios[i].gpio)) {
+		const char *gpio_name;
+		struct gpio_desc *gpio_val;
+
+		gpio_val = devm_gpiod_get_index(dev, NULL, i, GPIOD_OUT_LOW);
+		if (IS_ERR(gpio_val)) {
 			dev_err(dev, "Could not get gpio %d\n", i);
-			return PTR_ERR(modem->gpios[i].gpio);
+			return PTR_ERR(gpio_val);
 		}
 
 		err = of_property_read_string_index(np, "gpio-names", i,
-						&(modem->gpios[i].name));
+						    &gpio_name);
 		if (err) {
 			dev_err(dev, "Could not get gpio name %d\n", i);
 			return err;
 		}
 
-		err = gpiod_export(modem->gpios[i].gpio, 0);
-		if (err)
-			return err;
+		if (strcmp(gpio_name, "cmt_en") == 0) {
+			modem->gpio_cmt_en = gpio_val;
+		} else if(strcmp(gpio_name, "cmt_apeslpx") == 0) {
+			modem->gpio_cmt_apeslpx = gpio_val;
+		} else if(strcmp(gpio_name, "cmt_rst_rq") == 0) {
+			modem->gpio_cmt_rst_rq = gpio_val;
+		} else if(strcmp(gpio_name, "cmt_rst") == 0) {
+			modem->gpio_cmt_rst = gpio_val;
+		} else if(strcmp(gpio_name, "cmt_bsi") == 0) {
+			modem->gpio_cmt_bsi = gpio_val;
+		} else {
+			dev_err(dev, "Unknown gpio '%s'\n", gpio_name);
+			return -EINVAL;
+		}
 
-		err = gpiod_export_link(dev, modem->gpios[i].name,
-							modem->gpios[i].gpio);
-		if (err)
-			return err;
+		if (pm == 1) {
+			err = gpiod_export(gpio_val, 0);
+			if (err)
+				return err;
+
+			err = gpiod_export_link(dev, gpio_name, gpio_val);
+			if (err)
+				return err;
+		}
+	}
+
+	/* gpios required by both generations */
+	if (!modem->gpio_cmt_en || !modem->gpio_cmt_apeslpx ||
+	    !modem->gpio_cmt_rst_rq) {
+		dev_err(dev, "missing gpio!");
+		return -ENXIO;
+	}
+
+	/* gpios required by first generations */
+	if (modem->type == RAPUYAMA_V1 &&
+	   (!modem->gpio_cmt_rst || !modem->gpio_cmt_bsi)) {
+		dev_err(dev, "missing gpio!");
+		return -ENXIO;
 	}
 
 	return 0;
@@ -163,6 +212,12 @@ static int nokia_modem_probe(struct device *dev)
 	dev_set_drvdata(dev, modem);
 	modem->device = dev;
 
+	if (of_device_is_compatible(np, "nokia,n900-modem")) {
+		modem->type = RAPUYAMA_V1;
+	} else {
+		modem->type = RAPUYAMA_V2;
+	}
+
 	irq = irq_of_parse_and_map(np, 0);
 	if (!irq) {
 		dev_err(dev, "Invalid rst_ind interrupt (%d)\n", irq);
-- 
2.7.0.rc3

  reply	other threads:[~2016-01-31  1:20 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-31  1:19 [PATCH 0/5] nokia-modem: kernel based PM Sebastian Reichel
2016-01-31  1:19 ` Sebastian Reichel [this message]
2016-01-31  1:19 ` [PATCH 2/5] HSI: " Sebastian Reichel
2016-01-31 17:29   ` Pavel Machek
2016-01-31 18:00     ` Sebastian Reichel
2016-02-07 21:39       ` Pavel Machek
2016-01-31  1:19 ` [PATCH 3/5] HSI: ssi-protocol: export modem info via sysfs Sebastian Reichel
2016-01-31 17:36   ` Pavel Machek
2016-01-31 18:34     ` Sebastian Reichel
2016-01-31  1:19 ` [PATCH 4/5] HSI: nokia-modem: drop support for disabled pm Sebastian Reichel
2016-01-31 11:24   ` Pali Rohár
2016-01-31 16:10     ` Sebastian Reichel
2016-02-08  8:50       ` Pali Rohár
2016-01-31  1:19 ` [PATCH 5/5] HSI: ssi-protocol: clear carrier flag on open Sebastian Reichel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1454203187-688-2-git-send-email-sre@kernel.org \
    --to=sre@kernel.org \
    --cc=aaro.koskinen@iki.fi \
    --cc=bcousson@baylibre.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=pali.rohar@gmail.com \
    --cc=pavel@ucw.cz \
    --cc=tony@atomide.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).