diff options
| -rw-r--r-- | drivers/platform/x86/intel_mid_powerbtn.c | 72 |
1 files changed, 30 insertions, 42 deletions
diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c index 213e79ba68d5..f1ae5078b7ec 100644 --- a/drivers/platform/x86/intel_mid_powerbtn.c +++ b/drivers/platform/x86/intel_mid_powerbtn.c | |||
| @@ -23,58 +23,48 @@ | |||
| 23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
| 25 | #include <linux/input.h> | 25 | #include <linux/input.h> |
| 26 | |||
| 26 | #include <asm/intel_scu_ipc.h> | 27 | #include <asm/intel_scu_ipc.h> |
| 27 | 28 | ||
| 28 | #define DRIVER_NAME "msic_power_btn" | 29 | #define DRIVER_NAME "msic_power_btn" |
| 29 | 30 | ||
| 30 | #define MSIC_IRQ_STAT 0x02 | ||
| 31 | #define MSIC_IRQ_PB (1 << 0) | ||
| 32 | #define MSIC_PB_CONFIG 0x3e | ||
| 33 | #define MSIC_PB_STATUS 0x3f | 31 | #define MSIC_PB_STATUS 0x3f |
| 34 | #define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */ | 32 | #define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */ |
| 35 | |||
| 36 | struct mfld_pb_priv { | ||
| 37 | struct input_dev *input; | ||
| 38 | unsigned int irq; | ||
| 39 | }; | ||
| 40 | 33 | ||
| 41 | static irqreturn_t mfld_pb_isr(int irq, void *dev_id) | 34 | static irqreturn_t mfld_pb_isr(int irq, void *dev_id) |
| 42 | { | 35 | { |
| 43 | struct mfld_pb_priv *priv = dev_id; | 36 | struct input_dev *input = dev_id; |
| 44 | int ret; | 37 | int ret; |
| 45 | u8 pbstat; | 38 | u8 pbstat; |
| 46 | 39 | ||
| 47 | ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat); | 40 | ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat); |
| 48 | if (ret < 0) | 41 | if (ret < 0) { |
| 49 | return IRQ_HANDLED; | 42 | dev_err(input->dev.parent, "Read error %d while reading" |
| 50 | 43 | " MSIC_PB_STATUS\n", ret); | |
| 51 | input_event(priv->input, EV_KEY, KEY_POWER, !(pbstat & MSIC_PB_LEVEL)); | 44 | } else { |
| 52 | input_sync(priv->input); | 45 | input_event(input, EV_KEY, KEY_POWER, |
| 46 | !(pbstat & MSIC_PB_LEVEL)); | ||
| 47 | input_sync(input); | ||
| 48 | } | ||
| 53 | 49 | ||
| 54 | return IRQ_HANDLED; | 50 | return IRQ_HANDLED; |
| 55 | } | 51 | } |
| 56 | 52 | ||
| 57 | static int __devinit mfld_pb_probe(struct platform_device *pdev) | 53 | static int __devinit mfld_pb_probe(struct platform_device *pdev) |
| 58 | { | 54 | { |
| 59 | struct mfld_pb_priv *priv; | ||
| 60 | struct input_dev *input; | 55 | struct input_dev *input; |
| 61 | int irq; | 56 | int irq = platform_get_irq(pdev, 0); |
| 62 | int error; | 57 | int error; |
| 63 | 58 | ||
| 64 | irq = platform_get_irq(pdev, 0); | ||
| 65 | if (irq < 0) | 59 | if (irq < 0) |
| 66 | return -EINVAL; | 60 | return -EINVAL; |
| 67 | 61 | ||
| 68 | priv = kzalloc(sizeof(struct mfld_pb_priv), GFP_KERNEL); | ||
| 69 | input = input_allocate_device(); | 62 | input = input_allocate_device(); |
| 70 | if (!priv || !input) { | 63 | if (!input) { |
| 71 | error = -ENOMEM; | 64 | dev_err(&pdev->dev, "Input device allocation error\n"); |
| 72 | goto err_free_mem; | 65 | return -ENOMEM; |
| 73 | } | 66 | } |
| 74 | 67 | ||
| 75 | priv->input = input; | ||
| 76 | priv->irq = irq; | ||
| 77 | |||
| 78 | input->name = pdev->name; | 68 | input->name = pdev->name; |
| 79 | input->phys = "power-button/input0"; | 69 | input->phys = "power-button/input0"; |
| 80 | input->id.bustype = BUS_HOST; | 70 | input->id.bustype = BUS_HOST; |
| @@ -82,42 +72,40 @@ static int __devinit mfld_pb_probe(struct platform_device *pdev) | |||
| 82 | 72 | ||
| 83 | input_set_capability(input, EV_KEY, KEY_POWER); | 73 | input_set_capability(input, EV_KEY, KEY_POWER); |
| 84 | 74 | ||
| 85 | error = request_threaded_irq(priv->irq, NULL, mfld_pb_isr, | 75 | error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0, |
| 86 | 0, DRIVER_NAME, priv); | 76 | DRIVER_NAME, input); |
| 87 | if (error) { | 77 | if (error) { |
| 88 | dev_err(&pdev->dev, | 78 | dev_err(&pdev->dev, "Unable to request irq %d for mfld power" |
| 89 | "unable to request irq %d for mfld power button\n", | 79 | "button\n", irq); |
| 90 | irq); | 80 | goto err_free_input; |
| 91 | goto err_free_mem; | ||
| 92 | } | 81 | } |
| 93 | 82 | ||
| 94 | error = input_register_device(input); | 83 | error = input_register_device(input); |
| 95 | if (error) { | 84 | if (error) { |
| 96 | dev_err(&pdev->dev, | 85 | dev_err(&pdev->dev, "Unable to register input dev, error " |
| 97 | "unable to register input dev, error %d\n", error); | 86 | "%d\n", error); |
| 98 | goto err_free_irq; | 87 | goto err_free_irq; |
| 99 | } | 88 | } |
| 100 | 89 | ||
| 101 | platform_set_drvdata(pdev, priv); | 90 | platform_set_drvdata(pdev, input); |
| 102 | return 0; | 91 | return 0; |
| 103 | 92 | ||
| 104 | err_free_irq: | 93 | err_free_irq: |
| 105 | free_irq(priv->irq, priv); | 94 | free_irq(irq, input); |
| 106 | err_free_mem: | 95 | err_free_input: |
| 107 | input_free_device(input); | 96 | input_free_device(input); |
| 108 | kfree(priv); | ||
| 109 | return error; | 97 | return error; |
| 110 | } | 98 | } |
| 111 | 99 | ||
| 112 | static int __devexit mfld_pb_remove(struct platform_device *pdev) | 100 | static int __devexit mfld_pb_remove(struct platform_device *pdev) |
| 113 | { | 101 | { |
| 114 | struct mfld_pb_priv *priv = platform_get_drvdata(pdev); | 102 | struct input_dev *input = platform_get_drvdata(pdev); |
| 115 | 103 | int irq = platform_get_irq(pdev, 0); | |
| 116 | free_irq(priv->irq, priv); | ||
| 117 | input_unregister_device(priv->input); | ||
| 118 | kfree(priv); | ||
| 119 | 104 | ||
| 105 | free_irq(irq, input); | ||
| 106 | input_unregister_device(input); | ||
| 120 | platform_set_drvdata(pdev, NULL); | 107 | platform_set_drvdata(pdev, NULL); |
| 108 | |||
| 121 | return 0; | 109 | return 0; |
| 122 | } | 110 | } |
| 123 | 111 | ||
