aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuodong Xu <guodong.xu@linaro.org>2013-12-05 21:27:09 +0800
committerGuodong Xu <guodong.xu@linaro.org>2013-12-05 21:27:09 +0800
commit85e32c21a194794f6bf1bc1c0f8e89914e06cda1 (patch)
tree18f76675f99371963363e490cbaf7bce960056f8
parentd539adecc096b722f13fd7d998e68275500109ee (diff)
parent56f092a1bc6311932c42d02ed84f2c304e1e64cb (diff)
Merge branch 'tracking-hilt-regulator-1129' into integration-hilt-lsk-androidintegration-hilt-lsk-android-1205
* tracking-hilt-regulator-1129: mfd: hi6421: calling irq_create_mapping in irq handler can cause failure rtc: rtc-hi6421: rtc_device_register should be called before devm_request_irq input: hi6421: allocate input_dev before request_irq
-rw-r--r--drivers/input/misc/hi6421_pwrkey.c41
-rw-r--r--drivers/mfd/hi6421-pmic-core.c12
-rw-r--r--drivers/rtc/rtc-hi6421.c18
3 files changed, 40 insertions, 31 deletions
diff --git a/drivers/input/misc/hi6421_pwrkey.c b/drivers/input/misc/hi6421_pwrkey.c
index 7b2098d1fe2b..31d0145fc688 100644
--- a/drivers/input/misc/hi6421_pwrkey.c
+++ b/drivers/input/misc/hi6421_pwrkey.c
@@ -56,22 +56,36 @@ static int hi6421_onkey_probe(struct platform_device *pdev)
info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
+
+ info->idev = input_allocate_device();
+ if (!info->idev) {
+ dev_err(&pdev->dev, "Failed to allocate input device\n");
+ return -ENOMEM;
+ }
+ info->idev->name = "hi6421_on";
+ info->idev->phys = "hi6421_on/input0";
+ info->idev->dev.parent = &pdev->dev;
+ info->idev->evbit[0] = BIT_MASK(EV_KEY);
+ __set_bit(KEY_POWER, info->idev->keybit);
+
info->irq[0] = platform_get_irq_byname(pdev, "down");
- if (info->irq[0] < 0)
- return -ENOENT;
+ if (info->irq[0] < 0) {
+ ret = -ENOENT;
+ goto err_irq0;
+ }
ret = request_irq(info->irq[0], hi6421_onkey_handler,
IRQF_DISABLED, "down", info);
if (ret < 0)
- return ret;
+ goto err_irq0;
info->irq[1] = platform_get_irq_byname(pdev, "up");
if (info->irq[1] < 0) {
ret = -ENOENT;
- goto err;
+ goto err_irq1;
}
ret = request_irq(info->irq[1], hi6421_onkey_handler,
IRQF_DISABLED, "up", info);
if (ret < 0)
- goto err;
+ goto err_irq1;
info->irq[2] = platform_get_irq_byname(pdev, "hold 1s");
if (info->irq[2] < 0) {
ret = -ENOENT;
@@ -91,17 +105,6 @@ static int hi6421_onkey_probe(struct platform_device *pdev)
if (ret < 0)
goto err_irq3;
- info->idev = input_allocate_device();
- if (!info->idev) {
- dev_err(&pdev->dev, "Failed to allocate input device\n");
- goto err_alloc;
- }
- info->idev->name = "hi6421_on";
- info->idev->phys = "hi6421_on/input0";
- info->idev->dev.parent = &pdev->dev;
- info->idev->evbit[0] = BIT_MASK(EV_KEY);
- __set_bit(KEY_POWER, info->idev->keybit);
-
ret = input_register_device(info->idev);
if (ret) {
dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
@@ -111,15 +114,15 @@ static int hi6421_onkey_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, info);
return ret;
err_reg:
- input_free_device(info->idev);
-err_alloc:
free_irq(info->irq[3], info);
err_irq3:
free_irq(info->irq[2], info);
err_irq2:
free_irq(info->irq[1], info);
-err:
+err_irq1:
free_irq(info->irq[0], info);
+err_irq0:
+ input_free_device(info->idev);
return ret;
}
diff --git a/drivers/mfd/hi6421-pmic-core.c b/drivers/mfd/hi6421-pmic-core.c
index b2d7c4e82bd2..1ef6d4e16172 100644
--- a/drivers/mfd/hi6421-pmic-core.c
+++ b/drivers/mfd/hi6421-pmic-core.c
@@ -107,7 +107,7 @@ EXPORT_SYMBOL(hi6421_pmic_rmw);
static int hi6421_to_irq(struct hi6421_pmic *pmic, unsigned offset)
{
- return irq_create_mapping(pmic->domain, offset);
+ return irq_find_mapping(pmic->domain, offset);
}
static irqreturn_t hi6421_irq_handler(int irq, void *data)
@@ -196,7 +196,7 @@ static int hi6421_pmic_probe(struct platform_device *pdev)
struct device_node *np = dev->of_node;
struct hi6421_pmic *pmic = NULL;
enum of_gpio_flags flags;
- int ret;
+ int i, ret;
pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic) {
@@ -253,6 +253,14 @@ static int hi6421_pmic_probe(struct platform_device *pdev)
if (!pmic->domain)
return -ENODEV;
+ for (i = 0; i < HI6421_NR_IRQ; i++) {
+ ret = irq_create_mapping(pmic->domain, i);
+ if (ret == NO_IRQ) {
+ dev_err(dev, "failed mapping hwirq %d\n", i);
+ return -ENOMEM;
+ }
+ }
+
ret = request_threaded_irq(pmic->irq, hi6421_irq_handler, NULL,
IRQF_TRIGGER_LOW | IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND,
"pmic", pmic);
diff --git a/drivers/rtc/rtc-hi6421.c b/drivers/rtc/rtc-hi6421.c
index 14e27b96e0ef..50ec3911861b 100644
--- a/drivers/rtc/rtc-hi6421.c
+++ b/drivers/rtc/rtc-hi6421.c
@@ -214,29 +214,27 @@ static int hi6421_rtc_probe(struct platform_device *pdev)
if (info->irq < 0)
return -ENOENT;
- ret = devm_request_irq(&pdev->dev, info->irq, hi6421_rtc_handler,
- IRQF_DISABLED, "alarm", info);
- if (ret < 0)
- return ret;
info->pmic = dev_get_drvdata(pdev->dev.parent);
platform_set_drvdata(pdev, info);
/* enable RTC device */
hi6421_pmic_write(info->pmic, REG_RTCCTRL, 1);
- info->rtc = rtc_device_register(pdev->name, &pdev->dev,
- &hi6421_rtc_ops,
- THIS_MODULE);
+ info->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
+ &hi6421_rtc_ops, THIS_MODULE);
if (IS_ERR(info->rtc))
return PTR_ERR(info->rtc);
+
+ ret = devm_request_irq(&pdev->dev, info->irq, hi6421_rtc_handler,
+ IRQF_DISABLED, "alarm", info);
+ if (ret < 0)
+ return ret;
+
return 0;
}
static int hi6421_rtc_remove(struct platform_device *pdev)
{
- struct hi6421_rtc_info *info = platform_get_drvdata(pdev);
-
- rtc_device_unregister(info->rtc);
return 0;
}