[RFC PATCH] Rework gpio cansleep (was Re: gpiolib and sleeping gpios)

Ryan Mallon ryan at bluewatersys.com
Tue Jun 22 21:59:21 EDT 2010


On 06/21/2010 05:09 PM, Uwe Kleine-König wrote:
> Hi,
>
> On Sun, Jun 20, 2010 at 07:40:46PM -0700, David Brownell wrote:
>   
>>>> And they will trigger runtime warnings, and
>>>> thus eventually get fixed.
>>>>         
>>> \
>>>   }
>>>
>>>   err = gpio_request(some_gpio, "some_gpio",
>>>           GPIOF_NO_SLEEP);
>>>       
>>
>> NAK ... keep it simple.  Such flags are
>> clearly not necessary...
>>
>> I understand that some folk are bothered
>> by concepts/frameworks that seem "too simple"
>> and thus want to complexify them.  In this
>> case I am in a position to help avoid that.
>> Complexity is not a virtue.
>>     
> I'm against such an additional flag, too.  But I still think merging
> gpio_get_value and gpio_get_value_cansleep is nice.
>
> Best regards
> Uwe
>
>   

Okay, here is a rough patch to demonstrate how I think the gpiolib
framework could be simplified for cansleep gpios.

'Can sleep' for a gpio has two different meanings depending on context:
1) When talking about a gpio chip, 'can sleep' refers to whether or not
the set/get functions for the gpio may sleep. For example, io expanders
on the i2c or spi bus may sleep.
2) When talking about a drivers use of a gpio, 'can sleep' refers to
whether or not the the driver ever calls gpio_(set/get)_value for a
particular gpio in a context where it is not possible to sleep. For
example, if a driver calls gpio_get_value(gpio) from an interupt handler
then the gpio must not be a sleeping gpio.

This patch introduces a new flag, FLAG_CANSLEEP, internal to gpiolib
which denotes that a requested gpio may be used in a sleeping context. A
new request function, gpio_request_cansleep, requests a gpio which may
only be used from sleep possible contexts (ie cannot be used from
interrupt handlers, inside spinlocks, etc). The existing gpio_request
function requests a gpio, but does not allow it to be used from a
context where sleep is not possible. If a sleeping gpio is passed to
gpio_request then -EINVAL is returned.

The gpio_(set/get)_value_cansleep functions are removed, and all callers
now use gpio_(set/get)_value. might_sleep_if is used to warn about
incorrect uses of sleeping gpios.

The benefits I see to this approach are:
 - Using gpio_request/gpio_request_cansleep means that passing a
sleeping gpio to a driver that calls gpio_(set/get)_value from non-sleep
safe context is caught at request time and handled as an error.
 - The API is simplified by combining gpio_(set/get)_value and
gpio_(set/get)_value_cansleep

~Ryan

---

 arch/arm/mach-davinci/board-dm355-evm.c     |   12 ++--
 arch/arm/mach-davinci/board-dm355-leopard.c |   12 ++--
 arch/arm/mach-davinci/board-dm644x-evm.c    |    4 +-
 drivers/gpio/gpiolib.c                      |   67 ++++++++++++++-------------
 drivers/input/keyboard/matrix_keypad.c      |   10 ++--
 drivers/leds/leds-gpio.c                    |    7 ++-
 drivers/leds/leds-lt3593.c                  |   14 +++---
 drivers/mmc/host/omap_hsmmc.c               |   11 ++--
 drivers/regulator/fixed.c                   |    6 +-
 drivers/usb/musb/davinci.c                  |    4 +-
 drivers/watchdog/wm831x_wdt.c               |    4 +-
 include/asm-generic/gpio.h                  |   16 ------
 include/linux/gpio.h                        |   18 ++-----
 sound/soc/s3c24xx/s3c24xx_simtec.c          |    8 ++--
 14 files changed, 88 insertions(+), 105 deletions(-)

diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index a319101..853fd12 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -118,10 +118,10 @@ static int dm355evm_mmc_gpios = -EINVAL;
 
 static void dm355evm_mmcsd_gpios(unsigned gpio)
 {
-	gpio_request(gpio + 0, "mmc0_ro");
-	gpio_request(gpio + 1, "mmc0_cd");
-	gpio_request(gpio + 2, "mmc1_ro");
-	gpio_request(gpio + 3, "mmc1_cd");
+	gpio_request_cansleep(gpio + 0, "mmc0_ro");
+	gpio_request_cansleep(gpio + 1, "mmc0_cd");
+	gpio_request_cansleep(gpio + 2, "mmc1_ro");
+	gpio_request_cansleep(gpio + 3, "mmc1_cd");
 
 	/* we "know" these are input-only so we don't
 	 * need to call gpio_direction_input()
@@ -262,7 +262,7 @@ static int dm355evm_mmc_get_cd(int module)
 	if (!gpio_is_valid(dm355evm_mmc_gpios))
 		return -ENXIO;
 	/* low == card present */
-	return !gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 1);
+	return !gpio_get_value(dm355evm_mmc_gpios + 2 * module + 1);
 }
 
 static int dm355evm_mmc_get_ro(int module)
@@ -270,7 +270,7 @@ static int dm355evm_mmc_get_ro(int module)
 	if (!gpio_is_valid(dm355evm_mmc_gpios))
 		return -ENXIO;
 	/* high == card's write protect switch active */
-	return gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 0);
+	return gpio_get_value(dm355evm_mmc_gpios + 2 * module + 0);
 }
 
 static struct davinci_mmc_config dm355evm_mmc_config = {
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index f1d8132..99a9a9c 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -110,10 +110,10 @@ static int leopard_mmc_gpio = -EINVAL;
 
 static void dm355leopard_mmcsd_gpios(unsigned gpio)
 {
-	gpio_request(gpio + 0, "mmc0_ro");
-	gpio_request(gpio + 1, "mmc0_cd");
-	gpio_request(gpio + 2, "mmc1_ro");
-	gpio_request(gpio + 3, "mmc1_cd");
+	gpio_request_cansleep(gpio + 0, "mmc0_ro");
+	gpio_request_cansleep(gpio + 1, "mmc0_cd");
+	gpio_request_cansleep(gpio + 2, "mmc1_ro");
+	gpio_request_cansleep(gpio + 3, "mmc1_cd");
 
 	/* we "know" these are input-only so we don't
 	 * need to call gpio_direction_input()
@@ -185,7 +185,7 @@ static int dm355leopard_mmc_get_cd(int module)
 	if (!gpio_is_valid(leopard_mmc_gpio))
 		return -ENXIO;
 	/* low == card present */
-	return !gpio_get_value_cansleep(leopard_mmc_gpio + 2 * module + 1);
+	return !gpio_get_value(leopard_mmc_gpio + 2 * module + 1);
 }
 
 static int dm355leopard_mmc_get_ro(int module)
@@ -193,7 +193,7 @@ static int dm355leopard_mmc_get_ro(int module)
 	if (!gpio_is_valid(leopard_mmc_gpio))
 		return -ENXIO;
 	/* high == card's write protect switch active */
-	return gpio_get_value_cansleep(leopard_mmc_gpio + 2 * module + 0);
+	return gpio_get_value(leopard_mmc_gpio + 2 * module + 0);
 }
 
 static struct davinci_mmc_config dm355leopard_mmc_config = {
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 34c8b41..5cf037c 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -335,7 +335,7 @@ static int sw_gpio;
 static ssize_t
 sw_show(struct device *d, struct device_attribute *a, char *buf)
 {
-	char *s = gpio_get_value_cansleep(sw_gpio) ? "on\n" : "off\n";
+	char *s = gpio_get_value(sw_gpio) ? "on\n" : "off\n";
 
 	strcpy(buf, s);
 	return strlen(s);
@@ -350,7 +350,7 @@ evm_u18_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
 
 	/* export dip switch option */
 	sw_gpio = gpio + 7;
-	status = gpio_request(sw_gpio, "user_sw");
+	status = gpio_request_cansleep(sw_gpio, "user_sw");
 	if (status == 0)
 		status = gpio_direction_input(sw_gpio);
 	if (status == 0)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 3ca3654..6090ddc 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -55,6 +55,7 @@ struct gpio_desc {
 #define FLAG_TRIG_FALL	5	/* trigger on falling edge */
 #define FLAG_TRIG_RISE	6	/* trigger on rising edge */
 #define FLAG_ACTIVE_LOW	7	/* sysfs value has active low */
+#define FLAG_CANSLEEP	8	/* gpio may sleep during get/set */	
 
 #define PDESC_ID_SHIFT	16	/* add new flags before this one */
 
@@ -279,7 +280,7 @@ static ssize_t gpio_value_show(struct device *dev,
 	} else {
 		int value;
 
-		value = !!gpio_get_value_cansleep(gpio);
+		value = !!__gpio_get_value(gpio);
 		if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
 			value = !value;
 
@@ -310,7 +311,7 @@ static ssize_t gpio_value_store(struct device *dev,
 		if (status == 0) {
 			if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
 				value = !value;
-			gpio_set_value_cansleep(gpio, value != 0);
+			__gpio_set_value(gpio, value != 0);
 			status = size;
 		}
 	}
@@ -773,8 +774,10 @@ int gpio_export(unsigned gpio, bool direction_may_change)
 				device_unregister(dev);
 		} else
 			status = PTR_ERR(dev);
-		if (status == 0)
+		if (status == 0) {
 			set_bit(FLAG_EXPORT, &desc->flags);
+			set_bit(FLAG_CANSLEEP, &desc->flags);
+		}
 	}
 
 	mutex_unlock(&sysfs_lock);
@@ -1152,7 +1155,7 @@ EXPORT_SYMBOL_GPL(gpiochip_remove);
  * on each other, and help provide better diagnostics in debugfs.
  * They're called even less than the "set direction" calls.
  */
-int gpio_request(unsigned gpio, const char *label)
+static int __gpio_request(unsigned gpio, const char *label, int cansleep)
 {
 	struct gpio_desc	*desc;
 	struct gpio_chip	*chip;
@@ -1171,6 +1174,9 @@ int gpio_request(unsigned gpio, const char *label)
 	if (!try_module_get(chip->owner))
 		goto done;
 
+	if (!cansleep && chip->cansleep)
+		goto done;
+
 	/* NOTE:  gpio_request() can be called in early boot,
 	 * before IRQs are enabled, for non-sleeping (SOC) GPIOs.
 	 */
@@ -1184,6 +1190,9 @@ int gpio_request(unsigned gpio, const char *label)
 		goto done;
 	}
 
+	if (cansleep)
+		set_bit(FLAG_CANSLEEP, &desc->flags);
+
 	if (chip->request) {
 		/* chip->request may sleep */
 		spin_unlock_irqrestore(&gpio_lock, flags);
@@ -1204,8 +1213,19 @@ done:
 	spin_unlock_irqrestore(&gpio_lock, flags);
 	return status;
 }
+
+int gpio_request(unsigned gpio, const char *label)
+{
+	return __gpio_request(gpio, label, 0);
+}
 EXPORT_SYMBOL_GPL(gpio_request);
 
+int gpio_request_cansleep(unsigned gpio, const char *label)
+{
+	return __gpio_request(gpio, label, 1);
+}
+EXPORT_SYMBOL_GPL(gpio_request_cansleep);
+
 void gpio_free(unsigned gpio)
 {
 	unsigned long		flags;
@@ -1525,9 +1545,13 @@ EXPORT_SYMBOL_GPL(gpio_set_debounce);
 int __gpio_get_value(unsigned gpio)
 {
 	struct gpio_chip	*chip;
+	struct gpio_desc	*desc;
 
 	chip = gpio_to_chip(gpio);
-	WARN_ON(extra_checks && chip->can_sleep);
+	desc = &gpio_desc[gpio];
+
+	might_sleep_if(extra_checks && (chip->cansleep || 
+					test_bit(FLAG_CANSLEEP, &desc->flags));
 	return chip->get ? chip->get(chip, gpio - chip->base) : 0;
 }
 EXPORT_SYMBOL_GPL(__gpio_get_value);
@@ -1544,9 +1568,13 @@ EXPORT_SYMBOL_GPL(__gpio_get_value);
 void __gpio_set_value(unsigned gpio, int value)
 {
 	struct gpio_chip	*chip;
+	struct gpio_desc	*desc;
 
 	chip = gpio_to_chip(gpio);
-	WARN_ON(extra_checks && chip->can_sleep);
+	desc = &gpio_desc[gpio];
+
+	might_sleep_if(extra_checks && (chip->cansleep ||
+					test_bit(FLAG_CANSLEEP, &desc->flags));
 	chip->set(chip, gpio - chip->base, value);
 }
 EXPORT_SYMBOL_GPL(__gpio_set_value);
@@ -1588,33 +1616,6 @@ int __gpio_to_irq(unsigned gpio)
 }
 EXPORT_SYMBOL_GPL(__gpio_to_irq);
 
-
-
-/* There's no value in making it easy to inline GPIO calls that may sleep.
- * Common examples include ones connected to I2C or SPI chips.
- */
-
-int gpio_get_value_cansleep(unsigned gpio)
-{
-	struct gpio_chip	*chip;
-
-	might_sleep_if(extra_checks);
-	chip = gpio_to_chip(gpio);
-	return chip->get ? chip->get(chip, gpio - chip->base) : 0;
-}
-EXPORT_SYMBOL_GPL(gpio_get_value_cansleep);
-
-void gpio_set_value_cansleep(unsigned gpio, int value)
-{
-	struct gpio_chip	*chip;
-
-	might_sleep_if(extra_checks);
-	chip = gpio_to_chip(gpio);
-	chip->set(chip, gpio - chip->base, value);
-}
-EXPORT_SYMBOL_GPL(gpio_set_value_cansleep);
-
-
 #ifdef CONFIG_DEBUG_FS
 
 static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index b443e08..e0b3884 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -52,7 +52,7 @@ static void __activate_col(const struct matrix_keypad_platform_data *pdata,
 	if (on) {
 		gpio_direction_output(pdata->col_gpios[col], level_on);
 	} else {
-		gpio_set_value_cansleep(pdata->col_gpios[col], !level_on);
+		gpio_set_value(pdata->col_gpios[col], !level_on);
 		gpio_direction_input(pdata->col_gpios[col]);
 	}
 }
@@ -78,7 +78,7 @@ static void activate_all_cols(const struct matrix_keypad_platform_data *pdata,
 static bool row_asserted(const struct matrix_keypad_platform_data *pdata,
 			 int row)
 {
-	return gpio_get_value_cansleep(pdata->row_gpios[row]) ?
+	return gpio_get_value(pdata->row_gpios[row]) ?
 			!pdata->active_low : pdata->active_low;
 }
 
@@ -273,7 +273,8 @@ static int __devinit init_matrix_gpio(struct platform_device *pdev,
 
 	/* initialized strobe lines as outputs, activated */
 	for (i = 0; i < pdata->num_col_gpios; i++) {
-		err = gpio_request(pdata->col_gpios[i], "matrix_kbd_col");
+		err = gpio_request_cansleep(pdata->col_gpios[i],
+					    "matrix_kbd_col");
 		if (err) {
 			dev_err(&pdev->dev,
 				"failed to request GPIO%d for COL%d\n",
@@ -285,7 +286,8 @@ static int __devinit init_matrix_gpio(struct platform_device *pdev,
 	}
 
 	for (i = 0; i < pdata->num_row_gpios; i++) {
-		err = gpio_request(pdata->row_gpios[i], "matrix_kbd_row");
+		err = gpio_request_cansleep(pdata->row_gpios[i],
+					    "matrix_kbd_row");
 		if (err) {
 			dev_err(&pdev->dev,
 				"failed to request GPIO%d for ROW%d\n",
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index cc22eee..89a8278 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -42,7 +42,7 @@ static void gpio_led_work(struct work_struct *work)
 						 NULL, NULL);
 		led_dat->blinking = 0;
 	} else
-		gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level);
+		gpio_set_value(led_dat->gpio, led_dat->new_level);
 }
 
 static void gpio_led_set(struct led_classdev *led_cdev,
@@ -103,7 +103,10 @@ static int __devinit create_gpio_led(const struct gpio_led *template,
 		return 0;
 	}
 
-	ret = gpio_request(template->gpio, template->name);
+	if (gpio_cansleep(template->gpio))
+		ret = gpio_request_cansleep(template->gpio, template->name);
+	else
+		ret = gpio_request(template->gpio);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c
index 2579678..605c6ca 100644
--- a/drivers/leds/leds-lt3593.c
+++ b/drivers/leds/leds-lt3593.c
@@ -48,25 +48,25 @@ static void lt3593_led_work(struct work_struct *work)
 	 */
 
 	if (led_dat->new_level == 0) {
-		gpio_set_value_cansleep(led_dat->gpio, 0);
+		gpio_set_value(led_dat->gpio, 0);
 		return;
 	}
 
 	pulses = 32 - (led_dat->new_level * 32) / 255;
 
 	if (pulses == 0) {
-		gpio_set_value_cansleep(led_dat->gpio, 0);
+		gpio_set_value(led_dat->gpio, 0);
 		mdelay(1);
-		gpio_set_value_cansleep(led_dat->gpio, 1);
+		gpio_set_value(led_dat->gpio, 1);
 		return;
 	}
 
-	gpio_set_value_cansleep(led_dat->gpio, 1);
+	gpio_set_value(led_dat->gpio, 1);
 
 	while (pulses--) {
-		gpio_set_value_cansleep(led_dat->gpio, 0);
+		gpio_set_value(led_dat->gpio, 0);
 		udelay(1);
-		gpio_set_value_cansleep(led_dat->gpio, 1);
+		gpio_set_value(led_dat->gpio, 1);
 		udelay(1);
 	}
 }
@@ -93,7 +93,7 @@ static int __devinit create_lt3593_led(const struct gpio_led *template,
 		return 0;
 	}
 
-	ret = gpio_request(template->gpio, template->name);
+	ret = gpio_request_cansleep(template->gpio, template->name);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index b032828..0b362a6 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -191,7 +191,7 @@ static int omap_hsmmc_card_detect(struct device *dev, int slot)
 	struct omap_mmc_platform_data *mmc = dev->platform_data;
 
 	/* NOTE: assumes card detect signal is active-low */
-	return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
+	return !gpio_get_value(mmc->slots[0].switch_pin);
 }
 
 static int omap_hsmmc_get_wp(struct device *dev, int slot)
@@ -199,7 +199,7 @@ static int omap_hsmmc_get_wp(struct device *dev, int slot)
 	struct omap_mmc_platform_data *mmc = dev->platform_data;
 
 	/* NOTE: assumes write protect signal is active-high */
-	return gpio_get_value_cansleep(mmc->slots[0].gpio_wp);
+	return gpio_get_value(mmc->slots[0].gpio_wp);
 }
 
 static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
@@ -207,7 +207,7 @@ static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
 	struct omap_mmc_platform_data *mmc = dev->platform_data;
 
 	/* NOTE: assumes card detect signal is active-low */
-	return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
+	return !gpio_get_value(mmc->slots[0].switch_pin);
 }
 
 #ifdef CONFIG_PM
@@ -473,7 +473,8 @@ static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata)
 			pdata->slots[0].card_detect = omap_hsmmc_card_detect;
 		pdata->slots[0].card_detect_irq =
 				gpio_to_irq(pdata->slots[0].switch_pin);
-		ret = gpio_request(pdata->slots[0].switch_pin, "mmc_cd");
+		ret = gpio_request_cansleep(pdata->slots[0].switch_pin,
+					    "mmc_cd");
 		if (ret)
 			return ret;
 		ret = gpio_direction_input(pdata->slots[0].switch_pin);
@@ -484,7 +485,7 @@ static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata)
 
 	if (gpio_is_valid(pdata->slots[0].gpio_wp)) {
 		pdata->slots[0].get_ro = omap_hsmmc_get_wp;
-		ret = gpio_request(pdata->slots[0].gpio_wp, "mmc_wp");
+		ret = gpio_request_cansleep(pdata->slots[0].gpio_wp, "mmc_wp");
 		if (ret)
 			goto err_free_cd;
 		ret = gpio_direction_input(pdata->slots[0].gpio_wp);
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index 2fe9d99..1e9392d 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -49,7 +49,7 @@ static int fixed_voltage_enable(struct regulator_dev *dev)
 	struct fixed_voltage_data *data = rdev_get_drvdata(dev);
 
 	if (gpio_is_valid(data->gpio)) {
-		gpio_set_value_cansleep(data->gpio, data->enable_high);
+		gpio_set_value(data->gpio, data->enable_high);
 		data->is_enabled = true;
 	}
 
@@ -61,7 +61,7 @@ static int fixed_voltage_disable(struct regulator_dev *dev)
 	struct fixed_voltage_data *data = rdev_get_drvdata(dev);
 
 	if (gpio_is_valid(data->gpio)) {
-		gpio_set_value_cansleep(data->gpio, !data->enable_high);
+		gpio_set_value(data->gpio, !data->enable_high);
 		data->is_enabled = false;
 	}
 
@@ -148,7 +148,7 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
 			dev_warn(&pdev->dev,
 				"using GPIO 0 for regulator enable control\n");
 
-		ret = gpio_request(config->gpio, config->supply_name);
+		ret = gpio_request_cansleep(config->gpio, config->supply_name);
 		if (ret) {
 			dev_err(&pdev->dev,
 			   "Could not obtain regulator enable GPIO %d: %d\n",
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 5762436..48d72d4 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -161,7 +161,7 @@ static int vbus_state = -1;
  */
 static void evm_deferred_drvvbus(struct work_struct *ignored)
 {
-	gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
+	gpio_set_value(GPIO_nVBUS_DRV, vbus_state);
 	vbus_state = !vbus_state;
 }
 
@@ -181,7 +181,7 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate)
 		static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
 
 		if (immediate)
-			gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
+			gpio_set_value(GPIO_nVBUS_DRV, vbus_state);
 		else
 			schedule_work(&evm_vbus_work);
 	}
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 8c4b2d5..1f37574 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -123,7 +123,7 @@ static int wm831x_wdt_kick(struct wm831x *wm831x)
 	mutex_lock(&wdt_mutex);
 
 	if (update_gpio) {
-		gpio_set_value_cansleep(update_gpio, update_state);
+		gpio_set_value(update_gpio, update_state);
 		update_state = !update_state;
 		ret = 0;
 		goto out;
@@ -350,7 +350,7 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
 		reg |= pdata->software << WM831X_WDOG_RST_SRC_SHIFT;
 
 		if (pdata->update_gpio) {
-			ret = gpio_request(pdata->update_gpio,
+			ret = gpio_request_cansleep(pdata->update_gpio,
 					   "Watchdog update");
 			if (ret < 0) {
 				dev_err(wm831x->dev,
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 4f3d75e..8ae678b 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -128,10 +128,6 @@ extern int gpio_direction_output(unsigned gpio, int value);
 
 extern int gpio_set_debounce(unsigned gpio, unsigned debounce);
 
-extern int gpio_get_value_cansleep(unsigned gpio);
-extern void gpio_set_value_cansleep(unsigned gpio, int value);
-
-
 /* A platform's <asm/gpio.h> code may want to inline the I/O calls when
  * the GPIO is constant and refers to some always-present controller,
  * giving direct access to chip registers and tight bitbanging loops.
@@ -200,18 +196,6 @@ static inline int gpio_cansleep(unsigned gpio)
 	return 0;
 }
 
-static inline int gpio_get_value_cansleep(unsigned gpio)
-{
-	might_sleep();
-	return gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value_cansleep(unsigned gpio, int value)
-{
-	might_sleep();
-	gpio_set_value(gpio, value);
-}
-
 #endif /* !CONFIG_HAVE_GPIO_LIB */
 
 #ifndef CONFIG_GPIO_SYSFS
diff --git a/include/linux/gpio.h b/include/linux/gpio.h
index 03f616b..d02e4cd 100644
--- a/include/linux/gpio.h
+++ b/include/linux/gpio.h
@@ -33,6 +33,11 @@ static inline int gpio_request(unsigned gpio, const char *label)
 	return -ENOSYS;
 }
 
+static inline int gpio_request_cansleep(unsigned gpio, const char *label)
+{
+	return -ENOSYS;
+}
+
 static inline void gpio_free(unsigned gpio)
 {
 	might_sleep();
@@ -76,19 +81,6 @@ static inline int gpio_cansleep(unsigned gpio)
 	return 0;
 }
 
-static inline int gpio_get_value_cansleep(unsigned gpio)
-{
-	/* GPIO can never have been requested or set as {in,out}put */
-	WARN_ON(1);
-	return 0;
-}
-
-static inline void gpio_set_value_cansleep(unsigned gpio, int value)
-{
-	/* GPIO can never have been requested or set as output */
-	WARN_ON(1);
-}
-
 static inline int gpio_export(unsigned gpio, bool direction_may_change)
 {
 	/* GPIO can never have been requested or set as {in,out}put */
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c
index 4984754..b22b0d4 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec.c
+++ b/sound/soc/s3c24xx/s3c24xx_simtec.c
@@ -51,8 +51,8 @@ static int speaker_gain_get(struct snd_kcontrol *kcontrol,
  */
 static void speaker_gain_set(int value)
 {
-	gpio_set_value_cansleep(pdata->amp_gain[0], value & 1);
-	gpio_set_value_cansleep(pdata->amp_gain[1], value >> 1);
+	gpio_set_value(pdata->amp_gain[0], value & 1);
+	gpio_set_value(pdata->amp_gain[1], value >> 1);
 }
 
 /**
@@ -253,13 +253,13 @@ static int attach_gpio_amp(struct device *dev,
 
 	/* attach gpio amp gain (if any) */
 	if (pdata->amp_gain[0] > 0) {
-		ret = gpio_request(pd->amp_gain[0], "gpio-amp-gain0");
+		ret = gpio_request_cansleep(pd->amp_gain[0], "gpio-amp-gain0");
 		if (ret) {
 			dev_err(dev, "cannot get amp gpio gain0\n");
 			return ret;
 		}
 
-		ret = gpio_request(pd->amp_gain[1], "gpio-amp-gain1");
+		ret = gpio_request_cansleep(pd->amp_gain[1], "gpio-amp-gain1");
 		if (ret) {
 			dev_err(dev, "cannot get amp gpio gain1\n");
 			gpio_free(pdata->amp_gain[0]);




More information about the linux-arm-kernel mailing list