* Re: Fwd: [RFC] [PATCH] Input: ADP5588 - Support gpio function on unused pin [not found] <4c459b70.0aee8c0a.1c29.3e9e@mx.google.com> @ 2010-07-20 18:40 ` Dmitry Torokhov 2010-07-26 15:45 ` Xiaolong Chen 1 sibling, 0 replies; 7+ messages in thread From: Dmitry Torokhov @ 2010-07-20 18:40 UTC (permalink / raw) To: Xiaolong Chen Cc: Michael, david-b, Michael Hennerich, linux-input, TAO HU, Yuan.Bo YE, Xiaolong CHEN Hi Xiaolong, On Tue, Jul 20, 2010 at 08:49:36PM +0800, Xiaolong Chen wrote: > Hi Dmitry, > > There is still some issue on my company mail system, so change to this mail to submit the patch. > > Looks like this time haven't the line wrapped issue, any further comments and suggestion, please let me know. > I think we need to protect the code you are adding with #ifdef CONFIG_GPIOLIBi and provide the stubs in case gpiolib is not available. This will also force splitting the gpio hanlding code into separate functions so that it is easier to read. Please see how it is done in ad7879 driver. Also if would be great if you generated the patch against the version of the driver that is ither in linux-next or in the 'next' branch of my tree as there a few changes clashing with yours. Thanks. -- Dmitry ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Fwd: [RFC] [PATCH] Input: ADP5588 - Support gpio function on unused pin [not found] <4c459b70.0aee8c0a.1c29.3e9e@mx.google.com> 2010-07-20 18:40 ` Fwd: [RFC] [PATCH] Input: ADP5588 - Support gpio function on unused pin Dmitry Torokhov @ 2010-07-26 15:45 ` Xiaolong Chen 2010-07-26 17:38 ` Dmitry Torokhov 1 sibling, 1 reply; 7+ messages in thread From: Xiaolong Chen @ 2010-07-26 15:45 UTC (permalink / raw) To: Dmitry Torokhov Cc: Michael, david-b, Michael Hennerich, linux-input, TAO HU, Yuan.Bo YE, Xiaolong CHEN Hi, Dmitry Following your comments, add the CONFIG_GPIOLIB and update the patch based on the linux-next. If there is any comments and suggestion, please feel free let me know. I think we need to protect the code you are adding with #ifdef CONFIG_GPIOLIBi and provide the stubs in case gpiolib is not available. This will also force splitting the gpio hanlding code into separate functions so that it is easier to read. Please see how it is done in ad7879 driver. Done. Also if would be great if you generated the patch against the version of the driver that is ither in linux-next or in the 'next' branch of my tree as there a few changes clashing with yours. Done. From ac2b85cbf0452015f3a19b08d50bcd8ff97db25e Mon Sep 17 00:00:00 2001 From: xiaolong <a21785@motorola.com> Date: Thu, 22 Jul 2010 05:47:46 -0400 Subject: [PATCH] Input: ADP5588 - Support gpio function on unused pin This implements an optional gpio function on unused pin by adp5588 kpad. adp5588_kpad_platform_data has been extended with gpio_data, support gpio function if gpio_data is not NULL. Signed-off-by: Xiaolong Chen <xiao-long.chen@motorola.com> Signed-off-by: Yuanbo Ye <yuan-bo.ye@motorola.com> Signed-off-by: Tao Hu <taohu@motorola.com> Acked-by: Michael Hennerich <michael.hennerich@analog.com> Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- drivers/input/keyboard/adp5588-keys.c | 218 +++++++++++++++++++++++++++++++++ include/linux/i2c/adp5588.h | 1 + 2 files changed, 219 insertions(+), 0 deletions(-) diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 9096db7..f19c7ce 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -19,6 +19,7 @@ #include <linux/platform_device.h> #include <linux/input.h> #include <linux/i2c.h> +#include <linux/gpio.h> #include <linux/slab.h> #include <linux/i2c/adp5588.h> @@ -54,6 +55,10 @@ #define KEYP_MAX_EVENT 10 +#define MAXGPIO 18 +#define ADP_BANK(offs) ((offs) >> 3) +#define ADP_BIT(offs) (1u << ((offs) & 0x7)) + /* * Early pre 4.0 Silicon required to delay readout by at least 25ms, * since the Event Counter Register updated 25ms after the interrupt @@ -69,6 +74,14 @@ struct adp5588_kpad { unsigned short keycode[ADP5588_KEYMAPSIZE]; const struct adp5588_gpi_map *gpimap; unsigned short gpimapsize; + unsigned char gpiomap[MAXGPIO]; + bool support_gpio; +#ifdef CONFIG_GPIOLIB + struct gpio_chip gc; +#endif + struct mutex gpio_lock; /* Protect cached dir, dat_out */ + uint8_t dat_out[3]; + uint8_t dir[3]; }; static int adp5588_read(struct i2c_client *client, u8 reg) @@ -86,6 +99,194 @@ static int adp5588_write(struct i2c_client *client, u8 reg, u8 val) return i2c_smbus_write_byte_data(client, reg, val); } +#ifdef CONFIG_GPIOLIB +static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) +{ + unsigned bank, bit; + struct adp5588_kpad *kpad = + container_of(chip, struct adp5588_kpad, gc); + + bank = ADP_BANK(kpad->gpiomap[off]); + bit = ADP_BIT(kpad->gpiomap[off]); + + return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit); +} + +static void adp5588_gpio_set_value(struct gpio_chip *chip, + unsigned off, int val) +{ + unsigned bank, bit; + struct adp5588_kpad *kpad = + container_of(chip, struct adp5588_kpad, gc); + + bank = ADP_BANK(kpad->gpiomap[off]); + bit = ADP_BIT(kpad->gpiomap[off]); + + mutex_lock(&kpad->gpio_lock); + if (val) + kpad->dat_out[bank] |= bit; + else + kpad->dat_out[bank] &= ~bit; + + adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank, + kpad->dat_out[bank]); + mutex_unlock(&kpad->gpio_lock); +} + +static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) +{ + int ret; + unsigned bank, bit; + struct adp5588_kpad *kpad = + container_of(chip, struct adp5588_kpad, gc); + + bank = ADP_BANK(kpad->gpiomap[off]); + bit = ADP_BIT(kpad->gpiomap[off]); + + mutex_lock(&kpad->gpio_lock); + kpad->dir[bank] &= ~bit; + ret = adp5588_write(kpad->client, GPIO_DIR1 + bank, kpad->dir[bank]); + mutex_unlock(&kpad->gpio_lock); + + return ret; +} + +static int adp5588_gpio_direction_output(struct gpio_chip *chip, + unsigned off, int val) +{ + int ret; + unsigned bank, bit; + struct adp5588_kpad *kpad = + container_of(chip, struct adp5588_kpad, gc); + + bank = ADP_BANK(kpad->gpiomap[off]); + bit = ADP_BIT(kpad->gpiomap[off]); + + mutex_lock(&kpad->gpio_lock); + kpad->dir[bank] |= bit; + + if (val) + kpad->dat_out[bank] |= bit; + else + kpad->dat_out[bank] &= ~bit; + + ret = adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank, + kpad->dat_out[bank]); + ret |= adp5588_write(kpad->client, GPIO_DIR1 + bank, + kpad->dir[bank]); + mutex_unlock(&kpad->gpio_lock); + + return ret; +} + +static int __devinit adp5588_gpio_add(struct device *dev) +{ + int i, ret = 0; + struct adp5588_kpad *kpad = dev_get_drvdata(dev); + struct adp5588_kpad_platform_data *pdata = dev->platform_data; + + if (pdata->gpio_data) { + int j = 0; + bool pin_used[MAXGPIO]; + + for (i = 0; i < pdata->rows; i++) + pin_used[i] = true; + + for (i = 0; i < pdata->cols; i++) + pin_used[i + GPI_PIN_COL_BASE - GPI_PIN_BASE] = true; + + for (i = 0; i < kpad->gpimapsize; i++) + pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true; + + for (i = 0; i < MAXGPIO; i++) { + if (!pin_used[i]) + kpad->gpiomap[j++] = i; + } + kpad->gc.ngpio = j; + + if (kpad->gc.ngpio) + kpad->support_gpio = true; + } + + if (!kpad->support_gpio) { + dev_info(dev, "Don't support gpio function\n"); + return 0; + } + + kpad->gc.direction_input = adp5588_gpio_direction_input; + kpad->gc.direction_output = adp5588_gpio_direction_output; + kpad->gc.get = adp5588_gpio_get_value; + kpad->gc.set = adp5588_gpio_set_value; + kpad->gc.can_sleep = 1; + + kpad->gc.base = pdata->gpio_data->gpio_start; + kpad->gc.label = kpad->client->name; + kpad->gc.owner = THIS_MODULE; + + mutex_init(&kpad->gpio_lock); + + ret = gpiochip_add(&kpad->gc); + if (ret) { + dev_err(dev, "gpiochip_add err: %d\n", ret); + return ret; + } + + for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { + kpad->dat_out[i] = adp5588_read(kpad->client, + GPIO_DAT_OUT1 + i); + kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i); + } + + if (pdata->gpio_data->setup) { + ret = pdata->gpio_data->setup(kpad->client, + kpad->gc.base, kpad->gc.ngpio, + pdata->gpio_data->context); + if (ret < 0) + dev_warn(dev, "setup failed, %d\n", ret); + } + + return 0; +} + +static inline int adp5588_gpio_remove(struct device *dev) +{ + int ret = 0; + struct adp5588_kpad *kpad = dev_get_drvdata(dev); + struct adp5588_kpad_platform_data *pdata = dev->platform_data; + + if (!kpad->support_gpio) + return 0; + + if (pdata->gpio_data->teardown) { + ret = pdata->gpio_data->teardown(kpad->client, + kpad->gc.base, kpad->gc.ngpio, + pdata->gpio_data->context); + if (ret < 0) { + dev_err(dev, "teardown failed %d\n", ret); + return ret; + } + } + + ret = gpiochip_remove(&kpad->gc); + if (ret) { + dev_err(dev, "gpiochip_remove failed %d\n", ret); + return ret; + } + + return 0; +} +#else +static inline int adp5588_gpio_add(struct device *dev) +{ + return 0; +} + +static inline int adp5588_gpio_remove(struct device *dev) +{ + return 0; +} +#endif + static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt) { int i, j; @@ -184,6 +385,15 @@ static int __devinit adp5588_setup(struct i2c_client *client) ret |= adp5588_write(client, GPI_EM3, evt_mode3); } + if (pdata->gpio_data) { + for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { + int pull_mask = pdata->gpio_data->pullup_dis_mask; + + ret |= adp5588_write(client, GPIO_PULL1 + i, + (pull_mask >> (8 * i)) & 0xFF); + } + } + ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT | OVR_FLOW_INT | K_LCK_INT | GPI_INT | KE_INT); /* Status is W1C */ @@ -384,6 +594,10 @@ static int __devinit adp5588_probe(struct i2c_client *client, device_init_wakeup(&client->dev, 1); i2c_set_clientdata(client, kpad); + error = adp5588_gpio_add(&client->dev); + if (error) + goto err_free_irq; + dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq); return 0; @@ -401,12 +615,16 @@ static int __devinit adp5588_probe(struct i2c_client *client, static int __devexit adp5588_remove(struct i2c_client *client) { + int ret; struct adp5588_kpad *kpad = i2c_get_clientdata(client); adp5588_write(client, CFG, 0); free_irq(client->irq, kpad); cancel_delayed_work_sync(&kpad->work); input_unregister_device(kpad->input); + ret = adp5588_gpio_remove(&client->dev); + if (ret) + return ret; kfree(kpad); return 0; diff --git a/include/linux/i2c/adp5588.h b/include/linux/i2c/adp5588.h index b5f57c4..2e7d465 100644 --- a/include/linux/i2c/adp5588.h +++ b/include/linux/i2c/adp5588.h @@ -123,6 +123,7 @@ struct adp5588_kpad_platform_data { unsigned short unlock_key2; /* Unlock Key 2 */ const struct adp5588_gpi_map *gpimap; unsigned short gpimapsize; + struct adp5588_gpio_platform_data *gpio_data; }; struct adp5588_gpio_platform_data { -- 1.5.4.3 Thanks, Xiaolong ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: Fwd: [RFC] [PATCH] Input: ADP5588 - Support gpio function on unused pin 2010-07-26 15:45 ` Xiaolong Chen @ 2010-07-26 17:38 ` Dmitry Torokhov 2010-07-27 5:31 ` Xiaolong Chen 0 siblings, 1 reply; 7+ messages in thread From: Dmitry Torokhov @ 2010-07-26 17:38 UTC (permalink / raw) To: Xiaolong Chen Cc: Michael, david-b, Michael Hennerich, linux-input, TAO HU, Yuan.Bo YE, Xiaolong CHEN Hi Xiaolong, On Mon, Jul 26, 2010 at 11:45:43PM +0800, Xiaolong Chen wrote: > Hi, Dmitry > > Following your comments, add the CONFIG_GPIOLIB and update the > patch based on the linux-next. If there is any comments and > suggestion, please feel free let me know. > > I think we need to protect the code you are adding with #ifdef > CONFIG_GPIOLIBi and provide the stubs in case gpiolib is not > available. This will also force splitting the gpio hanlding code > into separate functions so that it is easier to read. Please see > how it is done in ad7879 driver. > Done. > > Also if would be great if you generated the patch against the > version of the driver that is ither in linux-next or in the 'next' > branch of my tree as there a few changes clashing with yours. > Done. > I have applied the patch with minor changes to my 'next' branch on kernel.org. Would you mind taking a look there to make sure it is all in order? Thanks. -- Dmitry ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Fwd: [RFC] [PATCH] Input: ADP5588 - Support gpio function on unused pin 2010-07-26 17:38 ` Dmitry Torokhov @ 2010-07-27 5:31 ` Xiaolong Chen [not found] ` <AANLkTi=qHUknGZdoj75Nr9gCKe-TRPMf3cgtsHejSrOc-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 0 siblings, 1 reply; 7+ messages in thread From: Xiaolong Chen @ 2010-07-27 5:31 UTC (permalink / raw) To: Dmitry Torokhov Cc: Michael, david-b, Michael Hennerich, linux-input, TAO HU, Yuan.Bo YE, Xiaolong CHEN Hi, Dmitry Look through the update, it's fine. Thanks, Xiaolong On Tue, Jul 27, 2010 at 1:38 AM, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote: > Hi Xiaolong, > > On Mon, Jul 26, 2010 at 11:45:43PM +0800, Xiaolong Chen wrote: >> Hi, Dmitry >> >> Following your comments, add the CONFIG_GPIOLIB and update the >> patch based on the linux-next. If there is any comments and >> suggestion, please feel free let me know. >> >> I think we need to protect the code you are adding with #ifdef >> CONFIG_GPIOLIBi and provide the stubs in case gpiolib is not >> available. This will also force splitting the gpio hanlding code >> into separate functions so that it is easier to read. Please see >> how it is done in ad7879 driver. >> Done. >> >> Also if would be great if you generated the patch against the >> version of the driver that is ither in linux-next or in the 'next' >> branch of my tree as there a few changes clashing with yours. >> Done. >> > > I have applied the patch with minor changes to my 'next' branch on > kernel.org. Would you mind taking a look there to make sure it is all in > order? > > Thanks. > > -- > Dmitry > -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 7+ messages in thread
[parent not found: <AANLkTi=qHUknGZdoj75Nr9gCKe-TRPMf3cgtsHejSrOc-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: Fwd: [RFC] [PATCH] Input: ADP5588 - Support gpio function on unused pin [not found] ` <AANLkTi=qHUknGZdoj75Nr9gCKe-TRPMf3cgtsHejSrOc-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> @ 2010-07-30 8:29 ` Hennerich, Michael 2010-07-30 17:08 ` Dmitry Torokhov 0 siblings, 1 reply; 7+ messages in thread From: Hennerich, Michael @ 2010-07-30 8:29 UTC (permalink / raw) To: Xiaolong Chen, Dmitry Torokhov Cc: david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org, Xiaolong CHEN, linux-input-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, uclinux-dist-devel, TAO HU, Yuan.Bo YE Hi Dmitry, I took a look at the driver in your next tree. Two issues: -Avoid NULL pointer dereference in adp5588_gpio_add(), set clientdata before call to adp5588_gpio_add(). -Avoid NULL pointer dereference, exit if gpio_data doesn't exist Signed-off-by: Michael Hennerich <michael.hennerich-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org> drivers/input/keyboard/adp5588-keys.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index c39ec93..456bba7 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -201,6 +201,9 @@ static int __devinit adp5588_gpio_add(struct device *dev) if (kpad->gc.ngpio) kpad->export_gpio = true; + } else { + kpad->export_gpio = false; + return 0; } if (!kpad->export_gpio) { @@ -581,12 +584,13 @@ static int __devinit adp5588_probe(struct i2c_client *client, if (kpad->gpimapsize) adp5588_report_switch_state(kpad); + i2c_set_clientdata(client, kpad); + error = adp5588_gpio_add(&client->dev); if (error) goto err_free_irq; device_init_wakeup(&client->dev, 1); - i2c_set_clientdata(client, kpad); dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq); return 0; Greetings, Michael Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 4036 Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: Fwd: [RFC] [PATCH] Input: ADP5588 - Support gpio function on unused pin 2010-07-30 8:29 ` Hennerich, Michael @ 2010-07-30 17:08 ` Dmitry Torokhov [not found] ` <20100730170854.GA22450-WlK9ik9hQGAhIp7JRqBPierSzoNAToWh@public.gmane.org> 0 siblings, 1 reply; 7+ messages in thread From: Dmitry Torokhov @ 2010-07-30 17:08 UTC (permalink / raw) To: Hennerich, Michael Cc: Xiaolong Chen, david-b@pacbell.net, Michael Hennerich, linux-input@vger.kernel.org, TAO HU, Yuan.Bo YE, Xiaolong CHEN, uclinux-dist-devel Hi Michael, On Fri, Jul 30, 2010 at 09:29:36AM +0100, Hennerich, Michael wrote: > Hi Dmitry, > > I took a look at the driver in your next tree. > > Two issues: > -Avoid NULL pointer dereference in adp5588_gpio_add(), > set clientdata before call to adp5588_gpio_add(). Ah, I see. However, now that you pointed this out, I do not like that we pass 'struct dev ice *' and use dev_get_drvdata() when adding and removing gpios. I'd rather pass keypad structre there, as in the patch below. What do you think? -- Dmitry Input: adp5588-keypad - fix NULL dereference in adp5588_gpio_add() From: Dmitry Torokhov <dmitry.torokhov@gmail.com> The kpad structure is assigned to i2c client via i2s_set_clientdata() at the end of adp5588_probe(), but in adp5588_gpio_add() we tried to access it (via dev_get_drvdata! which is not nice at all) causing an oops. Let's pass pointer to kpad directly into adp5588_gpio_add() and adp5588_gpio_remove() to avoid accessing driver data before it is set up. Also split out building of gpiomap into a separate function to clear the logic. Reported-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru> --- drivers/input/keyboard/adp5588-keys.c | 64 ++++++++++++++++++--------------- 1 files changed, 35 insertions(+), 29 deletions(-) diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index c39ec93..4208ff5 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -173,41 +173,47 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, return ret; } -static int __devinit adp5588_gpio_add(struct device *dev) +static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad, + const struct adp5588_kpad_platform_data *pdata) { - struct adp5588_kpad *kpad = dev_get_drvdata(dev); - const struct adp5588_kpad_platform_data *pdata = dev->platform_data; - const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; - int i, error; + bool pin_used[MAXGPIO]; + int n_unused = 0; + int i; - if (gpio_data) { - int j = 0; - bool pin_used[MAXGPIO]; + for (i = 0; i < pdata->rows; i++) + pin_used[i] = true; - for (i = 0; i < pdata->rows; i++) - pin_used[i] = true; + for (i = 0; i < pdata->cols; i++) + pin_used[i + GPI_PIN_COL_BASE - GPI_PIN_BASE] = true; - for (i = 0; i < pdata->cols; i++) - pin_used[i + GPI_PIN_COL_BASE - GPI_PIN_BASE] = true; + for (i = 0; i < kpad->gpimapsize; i++) + pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true; - for (i = 0; i < kpad->gpimapsize; i++) - pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true; + for (i = 0; i < MAXGPIO; i++) + if (!pin_used[i]) + kpad->gpiomap[n_unused++] = i; - for (i = 0; i < MAXGPIO; i++) { - if (!pin_used[i]) - kpad->gpiomap[j++] = i; - } - kpad->gc.ngpio = j; + return n_unused; +} - if (kpad->gc.ngpio) - kpad->export_gpio = true; - } +static int __devinit adp5588_gpio_add(struct adp5588_kpad *kpad) +{ + struct device *dev = &kpad->client->dev; + const struct adp5588_kpad_platform_data *pdata = dev->platform_data; + const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; + int i, error; - if (!kpad->export_gpio) { + if (!gpio_data) + return 0; + + kpad->gc.ngpio = adp5588_build_gpiomap(kpad, pdata); + if (kpad->gc.ngpio == 0) { dev_info(dev, "No unused gpios left to export\n"); return 0; } + kpad->export_gpio = true; + kpad->gc.direction_input = adp5588_gpio_direction_input; kpad->gc.direction_output = adp5588_gpio_direction_output; kpad->gc.get = adp5588_gpio_get_value; @@ -243,9 +249,9 @@ static int __devinit adp5588_gpio_add(struct device *dev) return 0; } -static void __devexit adp5588_gpio_remove(struct device *dev) +static void __devexit adp5588_gpio_remove(struct adp5588_kpad *kpad) { - struct adp5588_kpad *kpad = dev_get_drvdata(dev); + struct device *dev = &kpad->client->dev; const struct adp5588_kpad_platform_data *pdata = dev->platform_data; const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; int error; @@ -266,12 +272,12 @@ static void __devexit adp5588_gpio_remove(struct device *dev) dev_warn(dev, "gpiochip_remove failed %d\n", error); } #else -static inline int adp5588_gpio_add(struct device *dev) +static inline int adp5588_gpio_add(struct adp5588_kpad *kpad) { return 0; } -static inline void adp5588_gpio_remove(struct device *dev) +static inline void adp5588_gpio_remove(struct adp5588_kpad *kpad) { } #endif @@ -581,7 +587,7 @@ static int __devinit adp5588_probe(struct i2c_client *client, if (kpad->gpimapsize) adp5588_report_switch_state(kpad); - error = adp5588_gpio_add(&client->dev); + error = adp5588_gpio_add(kpad); if (error) goto err_free_irq; @@ -611,7 +617,7 @@ static int __devexit adp5588_remove(struct i2c_client *client) free_irq(client->irq, kpad); cancel_delayed_work_sync(&kpad->work); input_unregister_device(kpad->input); - adp5588_gpio_remove(&client->dev); + adp5588_gpio_remove(kpad); kfree(kpad); return 0; ^ permalink raw reply related [flat|nested] 7+ messages in thread
[parent not found: <20100730170854.GA22450-WlK9ik9hQGAhIp7JRqBPierSzoNAToWh@public.gmane.org>]
* Re: Fwd: [RFC] [PATCH] Input: ADP5588 - Support gpio function on unused pin [not found] ` <20100730170854.GA22450-WlK9ik9hQGAhIp7JRqBPierSzoNAToWh@public.gmane.org> @ 2010-08-02 9:37 ` Hennerich, Michael 0 siblings, 0 replies; 7+ messages in thread From: Hennerich, Michael @ 2010-08-02 9:37 UTC (permalink / raw) To: Dmitry Torokhov Cc: Xiaolong Chen, david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org, Xiaolong CHEN, linux-input-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, uclinux-dist-devel, TAO HU, Yuan.Bo YE Dmitry Torokhov wrote on 2010-07-30: > Hi Michael, > > On Fri, Jul 30, 2010 at 09:29:36AM +0100, Hennerich, Michael wrote: >> Hi Dmitry, >> >> I took a look at the driver in your next tree. >> >> Two issues: >> -Avoid NULL pointer dereference in adp5588_gpio_add(), set >> clientdata before call to adp5588_gpio_add(). > > Ah, I see. However, now that you pointed this out, I do not like that > we pass 'struct dev ice *' and use dev_get_drvdata() when adding and > removing gpios. I'd rather pass keypad structre there, as in the patch > below. What do you think? > Hi Dmitry, Your patch looks good. However there is another problem. The pin_used array must be cleared before it is used. + memset(pin_used, false, sizeof(pin_used)); Greetings, Michael Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 4036 Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-08-02 9:37 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <4c459b70.0aee8c0a.1c29.3e9e@mx.google.com> 2010-07-20 18:40 ` Fwd: [RFC] [PATCH] Input: ADP5588 - Support gpio function on unused pin Dmitry Torokhov 2010-07-26 15:45 ` Xiaolong Chen 2010-07-26 17:38 ` Dmitry Torokhov 2010-07-27 5:31 ` Xiaolong Chen [not found] ` <AANLkTi=qHUknGZdoj75Nr9gCKe-TRPMf3cgtsHejSrOc-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2010-07-30 8:29 ` Hennerich, Michael 2010-07-30 17:08 ` Dmitry Torokhov [not found] ` <20100730170854.GA22450-WlK9ik9hQGAhIp7JRqBPierSzoNAToWh@public.gmane.org> 2010-08-02 9:37 ` Hennerich, Michael
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).