From patchwork Sun Jul 8 01:05:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 1169181 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 36FEF3FC36 for ; Sun, 8 Jul 2012 01:12:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751438Ab2GHBF0 (ORCPT ); Sat, 7 Jul 2012 21:05:26 -0400 Received: from mail-pb0-f46.google.com ([209.85.160.46]:33848 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751404Ab2GHBFZ (ORCPT ); Sat, 7 Jul 2012 21:05:25 -0400 Received: by pbbrp8 with SMTP id rp8so17011034pbb.19 for ; Sat, 07 Jul 2012 18:05:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=b19hApCjcbFN3SkwgzkUPkpCS3arp6lZkarNjrCi62k=; b=w9GxnfLfGtCQXIu5KZjxGFKJACn+bO4v0nVsqR6C4QKFMdIvTS2o9d37YiFAUOO1bm GKymDyko9tApM8IYQDSc7x/mZk7gC7YAIw/SrhXT/vE/D7NmEEOQkCe9TZfTuL8igh2H /x1cRRNCYaSvAkrJnYYS5XvBeBqdRH9zoNBQpsGa3OwGk154H8rIXUPRqAq6VSp2Q62V fbHoz3KKELhoFvYa2yqPbnm6e8j11uW6fnhJd/Bx4DNa7sLUmqnxSbVK7b+BeJlUD5SH yv204lS0E4vLSLUOJ4yC+wbyoyW/hgpwZq5g2HkNAiwW6+2fsvgRf9pw9/1s3QD8aKYI oR5A== Received: by 10.66.76.231 with SMTP id n7mr55631885paw.68.1341709525294; Sat, 07 Jul 2012 18:05:25 -0700 (PDT) Received: from mailhub.coreip.homeip.net (c-67-188-112-76.hsd1.ca.comcast.net. [67.188.112.76]) by mx.google.com with ESMTPS id rv9sm24744407pbc.43.2012.07.07.18.05.23 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 07 Jul 2012 18:05:24 -0700 (PDT) Date: Sat, 7 Jul 2012 18:05:20 -0700 From: Dmitry Torokhov To: Richard Weinberger Cc: daniel@caiaq.de, rusty@rustcorp.com.au, mchehab@redhat.com, axel.lin@gmail.com, linux-input@vger.kernel.org, "linux-kernel@vger.kernel.org" Subject: Re: input: eeti_ts.c build error Message-ID: <20120708010520.GC19007@core.coreip.homeip.net> References: <4FF83E48.6060303@nod.at> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <4FF83E48.6060303@nod.at> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Hi Richard, On Sat, Jul 07, 2012 at 03:48:56PM +0200, Richard Weinberger wrote: > Hi! > > While building a kernel for an ARM board the following build error came across: > > drivers/input/touchscreen/eeti_ts.c: In function 'eeti_ts_irq_active': > drivers/input/touchscreen/eeti_ts.c:65:2: error: implicit declaration of function 'irq_to_gpio' [-Werror=implicit-function-declaration] > > .config is attached. > Happens on 3.4.4 and Linus's tree as of today. Could you please try the patch below? I have had it for a long time but could not find anyone to test it. Thanks. diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 503c709..4d875e5 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c @@ -46,9 +46,6 @@ MODULE_PARM_DESC(flip_y, "flip y coordinate"); struct eeti_ts_priv { struct i2c_client *client; struct input_dev *input; - struct work_struct work; - struct mutex mutex; - int irq, irq_active_high; }; #define EETI_TS_BITDEPTH (11) @@ -60,26 +57,18 @@ struct eeti_ts_priv { #define REPORT_BIT_HAS_PRESSURE (1 << 6) #define REPORT_RES_BITS(v) (((v) >> 1) + EETI_TS_BITDEPTH) -static inline int eeti_ts_irq_active(struct eeti_ts_priv *priv) -{ - return gpio_get_value(irq_to_gpio(priv->irq)) == priv->irq_active_high; -} - -static void eeti_ts_read(struct work_struct *work) +static irqreturn_t eeti_ts_isr(int irq, void *dev_id) { + struct eeti_ts_priv *priv = dev_id; + struct i2c_client *client = priv->client; + struct input_dev *input = priv->input; + unsigned int x, y, res, pressed; + int rc; char buf[6]; - unsigned int x, y, res, pressed, to = 100; - struct eeti_ts_priv *priv = - container_of(work, struct eeti_ts_priv, work); - - mutex_lock(&priv->mutex); - - while (eeti_ts_irq_active(priv) && --to) - i2c_master_recv(priv->client, buf, sizeof(buf)); - if (!to) { - dev_err(&priv->client->dev, - "unable to clear IRQ - line stuck?\n"); + rc = i2c_master_recv(client, buf, sizeof(buf)); + if (rc < 0) { + dev_err(&client->dev, "i2c_master_recv failed, error: %d", rc); goto out; } @@ -103,46 +92,22 @@ static void eeti_ts_read(struct work_struct *work) y = EETI_MAXVAL - y; if (buf[0] & REPORT_BIT_HAS_PRESSURE) - input_report_abs(priv->input, ABS_PRESSURE, buf[5]); + input_report_abs(input, ABS_PRESSURE, buf[5]); - input_report_abs(priv->input, ABS_X, x); - input_report_abs(priv->input, ABS_Y, y); - input_report_key(priv->input, BTN_TOUCH, !!pressed); - input_sync(priv->input); + input_report_abs(input, ABS_X, x); + input_report_abs(input, ABS_Y, y); + input_report_key(input, BTN_TOUCH, pressed); + input_sync(input); out: - mutex_unlock(&priv->mutex); -} - -static irqreturn_t eeti_ts_isr(int irq, void *dev_id) -{ - struct eeti_ts_priv *priv = dev_id; - - /* postpone I2C transactions as we are atomic */ - schedule_work(&priv->work); - return IRQ_HANDLED; } -static void eeti_ts_start(struct eeti_ts_priv *priv) -{ - enable_irq(priv->irq); - - /* Read the events once to arm the IRQ */ - eeti_ts_read(&priv->work); -} - -static void eeti_ts_stop(struct eeti_ts_priv *priv) -{ - disable_irq(priv->irq); - cancel_work_sync(&priv->work); -} - static int eeti_ts_open(struct input_dev *dev) { struct eeti_ts_priv *priv = input_get_drvdata(dev); - eeti_ts_start(priv); + enable_irq(priv->client->irq); return 0; } @@ -151,17 +116,17 @@ static void eeti_ts_close(struct input_dev *dev) { struct eeti_ts_priv *priv = input_get_drvdata(dev); - eeti_ts_stop(priv); + disable_irq(priv->client->irq); } static int __devinit eeti_ts_probe(struct i2c_client *client, const struct i2c_device_id *idp) { - struct eeti_ts_platform_data *pdata; + const struct eeti_ts_platform_data *pdata = client->dev.platform_data; struct eeti_ts_priv *priv; struct input_dev *input; unsigned int irq_flags; - int err = -ENOMEM; + int err; /* * In contrast to what's described in the datasheet, there seems @@ -171,25 +136,15 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, */ priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&client->dev, "failed to allocate driver data\n"); - goto err0; - } - - mutex_init(&priv->mutex); input = input_allocate_device(); - - if (!input) { - dev_err(&client->dev, "Failed to allocate input device.\n"); - goto err1; + if (!priv || !input) { + dev_err(&client->dev, "failed to memory\n"); + err = -ENOMEM; + goto err_free_mem; } - input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); - - input_set_abs_params(input, ABS_X, 0, EETI_MAXVAL, 0, 0); - input_set_abs_params(input, ABS_Y, 0, EETI_MAXVAL, 0, 0); - input_set_abs_params(input, ABS_PRESSURE, 0, 0xff, 0, 0); + priv->client = client; + priv->input = input; input->name = client->name; input->id.bustype = BUS_I2C; @@ -197,49 +152,47 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, input->open = eeti_ts_open; input->close = eeti_ts_close; - priv->client = client; - priv->input = input; - priv->irq = client->irq; - - pdata = client->dev.platform_data; - - if (pdata) - priv->irq_active_high = pdata->irq_active_high; + input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); - irq_flags = priv->irq_active_high ? - IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING; + input_set_abs_params(input, ABS_X, 0, EETI_MAXVAL, 0, 0); + input_set_abs_params(input, ABS_Y, 0, EETI_MAXVAL, 0, 0); + input_set_abs_params(input, ABS_PRESSURE, 0, 0xff, 0, 0); - INIT_WORK(&priv->work, eeti_ts_read); - i2c_set_clientdata(client, priv); input_set_drvdata(input, priv); - err = input_register_device(input); - if (err) - goto err1; + irq_flags = pdata && pdata->irq_active_high ? + IRQF_TRIGGER_HIGH : IRQF_TRIGGER_LOW; + irq_flags |= IRQF_ONESHOT; - err = request_irq(priv->irq, eeti_ts_isr, irq_flags, - client->name, priv); - if (err) { + err = request_threaded_irq(client->irq, NULL, eeti_ts_isr, + irq_flags, client->name, priv); + if (err < 0) { dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); - goto err2; + goto err_free_mem; } /* - * Disable the device for now. It will be enabled once the + * Disable the IRQ for now. It will be enabled once the * input device is opened. */ - eeti_ts_stop(priv); + disable_irq(client->irq); + err = input_register_device(input); + if (err) + goto err_free_irq; + + i2c_set_clientdata(client, priv); device_init_wakeup(&client->dev, 0); + return 0; -err2: - input_unregister_device(input); - input = NULL; /* so we dont try to free it below */ -err1: +err_free_irq: + free_irq(client->irq, priv); +err_free_mem: input_free_device(input); kfree(priv); -err0: + return err; } @@ -247,20 +200,14 @@ static int __devexit eeti_ts_remove(struct i2c_client *client) { struct eeti_ts_priv *priv = i2c_get_clientdata(client); - free_irq(priv->irq, priv); - /* - * eeti_ts_stop() leaves IRQ disabled. We need to re-enable it - * so that device still works if we reload the driver. - */ - enable_irq(priv->irq); - + free_irq(client->irq, priv); input_unregister_device(priv->input); kfree(priv); return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int eeti_ts_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -270,12 +217,12 @@ static int eeti_ts_suspend(struct device *dev) mutex_lock(&input_dev->mutex); if (input_dev->users) - eeti_ts_stop(priv); + disable_irq(client->irq); mutex_unlock(&input_dev->mutex); if (device_may_wakeup(&client->dev)) - enable_irq_wake(priv->irq); + enable_irq_wake(client->irq); return 0; } @@ -287,20 +234,20 @@ static int eeti_ts_resume(struct device *dev) struct input_dev *input_dev = priv->input; if (device_may_wakeup(&client->dev)) - disable_irq_wake(priv->irq); + disable_irq_wake(client->irq); mutex_lock(&input_dev->mutex); if (input_dev->users) - eeti_ts_start(priv); + enable_irq(client->irq); mutex_unlock(&input_dev->mutex); return 0; } +#endif static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume); -#endif static const struct i2c_device_id eeti_ts_id[] = { { "eeti_ts", 0 }, @@ -311,9 +258,8 @@ MODULE_DEVICE_TABLE(i2c, eeti_ts_id); static struct i2c_driver eeti_ts_driver = { .driver = { .name = "eeti_ts", -#ifdef CONFIG_PM + .owner = THIS_MODULE, .pm = &eeti_ts_pm, -#endif }, .probe = eeti_ts_probe, .remove = __devexit_p(eeti_ts_remove),