Apply this patch:

>From 51b4d415971bb052a26938791337d1050bf94748 Mon Sep 17 00:00:00 2001
From: Robert Nelson <[email protected]>
Date: Mon, 26 Oct 2015 11:42:13 -0500
Subject: [PATCH 8/9] tps65217: Enable KEY_POWER press on AC loss / PWR_BUT

This is an adaption to v3.14.x of the original patch by Andrew Bradford 
<[email protected]>
Some minor devm_* changes and DT support done by Pantelis Antoniou 
<[email protected]> for 3.8.x

Signed-off-by: Robert Nelson <[email protected]>
---
 arch/arm/boot/dts/am335x-bone-common.dtsi |   3 +
 drivers/mfd/tps65217.c                    | 122 +++++++++++++++++++++++++++++-
 include/linux/mfd/tps65217.h              |   5 ++
 3 files changed, 128 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi 
b/arch/arm/boot/dts/am335x-bone-common.dtsi
index 29c0c7e..393af39 100644
--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
@@ -330,6 +330,9 @@
         */
        ti,pmic-shutdown-controller;
 
+       interrupt-parent = <&intc>;
+       interrupts = <7>;       /* NNMI */
+
        regulators {
                dcdc1_reg: regulator@0 {
                        regulator-name = "vdds_dpr";
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c
index 7d1cfc1..0730431 100644
--- a/drivers/mfd/tps65217.c
+++ b/drivers/mfd/tps65217.c
@@ -24,8 +24,12 @@
 #include <linux/slab.h>
 #include <linux/regmap.h>
 #include <linux/err.h>
+#include <linux/input.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#include <linux/interrupt.h>
 
 #include <linux/mfd/core.h>
 #include <linux/mfd/tps65217.h>
@@ -157,6 +161,82 @@ static const struct of_device_id tps65217_of_match[] = {
        { /* sentinel */ },
 };
 
+static irqreturn_t tps65217_irq(int irq, void *irq_data)
+{
+       struct tps65217 *tps = irq_data;
+       unsigned int int_reg = 0, status_reg = 0;
+
+       tps65217_reg_read(tps, TPS65217_REG_INT, &int_reg);
+       tps65217_reg_read(tps, TPS65217_REG_STATUS, &status_reg);
+       if (status_reg)
+               dev_dbg(tps->dev, "status now: 0x%X\n", status_reg);
+
+       if (!int_reg)
+               return IRQ_NONE;
+
+       if (int_reg & TPS65217_INT_PBI) {
+               /* Handle push button */
+               dev_dbg(tps->dev, "power button status change\n");
+               input_report_key(tps->pwr_but, KEY_POWER,
+                               status_reg & TPS65217_STATUS_PB);
+               input_sync(tps->pwr_but);
+       }
+       if (int_reg & TPS65217_INT_ACI) {
+               /* Handle AC power status change */
+               dev_dbg(tps->dev, "AC power status change\n");
+               /* Press KEY_POWER when AC not present */
+               input_report_key(tps->pwr_but, KEY_POWER,
+                               ~status_reg & TPS65217_STATUS_ACPWR);
+               input_sync(tps->pwr_but);
+       }
+       if (int_reg & TPS65217_INT_USBI) {
+               /* Handle USB power status change */
+               dev_dbg(tps->dev, "USB power status change\n");
+       }
+
+       return IRQ_HANDLED;
+}
+
+static int tps65217_probe_pwr_but(struct tps65217 *tps)
+{
+       int ret;
+       unsigned int int_reg;
+
+       tps->pwr_but = devm_input_allocate_device(tps->dev);
+       if (!tps->pwr_but) {
+               dev_err(tps->dev,
+                       "Failed to allocated pwr_but input device\n");
+               return -ENOMEM;
+       }
+
+       tps->pwr_but->evbit[0] = BIT_MASK(EV_KEY);
+       tps->pwr_but->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
+       tps->pwr_but->name = "tps65217_pwr_but";
+       ret = input_register_device(tps->pwr_but);
+       if (ret) {
+               /* NOTE: devm managed device */
+               dev_err(tps->dev, "Failed to register button device\n");
+               return ret;
+       }
+       ret = devm_request_threaded_irq(tps->dev,
+               tps->irq, NULL, tps65217_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+               "tps65217", tps);
+       if (ret != 0) {
+               dev_err(tps->dev, "Failed to request IRQ %d\n", tps->irq);
+               return ret;
+       }
+
+       /* enable the power button interrupt */
+       ret = tps65217_reg_read(tps, TPS65217_REG_INT, &int_reg);
+       if (ret < 0) {
+               dev_err(tps->dev, "Failed to read INT reg\n");
+               return ret;
+       }
+       int_reg &= ~TPS65217_INT_PBM;
+       tps65217_reg_write(tps, TPS65217_REG_INT, int_reg, 
TPS65217_PROTECT_NONE);
+       return 0;
+}
+
 static int tps65217_probe(struct i2c_client *client,
                                const struct i2c_device_id *ids)
 {
@@ -164,10 +244,13 @@ static int tps65217_probe(struct i2c_client *client,
        unsigned int version;
        unsigned long chip_id = ids->driver_data;
        const struct of_device_id *match;
+       struct device_node *node;
        bool status_off = false;
+       int irq = -1, irq_gpio = -1;
        int ret;
 
-       if (client->dev.of_node) {
+       node = client->dev.of_node;
+       if (node) {
                match = of_match_device(tps65217_of_match, &client->dev);
                if (!match) {
                        dev_err(&client->dev,
@@ -175,8 +258,31 @@ static int tps65217_probe(struct i2c_client *client,
                        return -EINVAL;
                }
                chip_id = (unsigned long)match->data;
-               status_off = of_property_read_bool(client->dev.of_node,
+               status_off = of_property_read_bool(node,
                                        "ti,pmic-shutdown-controller");
+
+               /* at first try to get irq via OF method */
+               irq = irq_of_parse_and_map(node, 0);
+               if (irq <= 0) {
+                       irq = -1;
+                       irq_gpio = of_get_named_gpio(node, "irq-gpio", 0);
+                       if (irq_gpio >= 0) {
+                               /* valid gpio; convert to irq */
+                               ret = devm_gpio_request_one(&client->dev,
+                                       irq_gpio, GPIOF_DIR_IN,
+                                       "tps65217-gpio-irq");
+                               if (ret != 0)
+                                       dev_warn(&client->dev, "Failed to "
+                                               "request gpio #%d\n", irq_gpio);
+                               irq = gpio_to_irq(irq_gpio);
+                               if (irq <= 0) {
+                                       dev_warn(&client->dev, "Failed to "
+                                               "convert gpio #%d to irq\n",
+                                               irq_gpio);
+                                       irq = -1;
+                               }
+                       }
+               }
        }
 
        if (!chip_id) {
@@ -200,6 +306,18 @@ static int tps65217_probe(struct i2c_client *client,
                return ret;
        }
 
+       tps->irq = irq;
+       tps->irq_gpio = irq_gpio;
+
+       /* we got an irq, request it */
+       if (tps->irq >= 0) {
+               ret = tps65217_probe_pwr_but(tps);
+               if (ret < 0) {
+                       dev_err(tps->dev, "Failed to probe pwr_but\n");
+                       return ret;
+               }
+       }
+
        ret = mfd_add_devices(tps->dev, -1, tps65217s,
                              ARRAY_SIZE(tps65217s), NULL, 0, NULL);
        if (ret < 0) {
diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h
index ac7fba4..05d24a6 100644
--- a/include/linux/mfd/tps65217.h
+++ b/include/linux/mfd/tps65217.h
@@ -257,6 +257,11 @@ struct tps65217 {
        unsigned long id;
        struct regulator_desc desc[TPS65217_NUM_REGULATOR];
        struct regmap *regmap;
+
+       /* Power button and IRQ handling */
+       int irq_gpio;   /* might not be set */
+       int irq;
+       struct input_dev *pwr_but;
 };
 
 static inline struct tps65217 *dev_to_tps65217(struct device *dev)
-- 
2.6.2

Regards,
John




> On Apr 17, 2016, at 4:05 PM, William Hermans <[email protected]> wrote:
> 
> I'll *NOT* be using a TI kernel, period.
> 
> On Sun, Apr 17, 2016 at 4:02 PM, John Syne <[email protected] 
> <mailto:[email protected]>> wrote:
> OK, I see the problem. The file I was looking at is different to the one you 
> linked to. I am using the 4.1.13-ti-r33 kernel, which means that you are 
> missing a patch. Build your own kernel and then look at this file again.
> 
> Regards,
> John
> 
> 
> 
> 
>> On Apr 17, 2016, at 3:55 PM, William Hermans <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> https://github.com/torvalds/linux/blob/master/drivers/mfd/tps65217.c#L164 
>> <https://github.com/torvalds/linux/blob/master/drivers/mfd/tps65217.c#L164>
>> 
>> Nothing there at line 164, then on line 165 starts a function. Which 
>> contains the code I linked to yesterday. Which is the power push button 
>> code. Which again, is not helping . . . So let's walk through that function. 
>> Which happens in this order . ..
>> 
>> variable type definitions declarations.
>> conditional check to find device tree definition node.
>> test chip_id, return if failure.
>> attempt and test to allocate memory for the tps object.
>> attempt to map the tps object to the PMIC registers
>> mfd device add, and test device add.
>> attempt to read the PMIC registers, and test return code.
>> 
>> Here it gets a bit fuzzy however, it seems as though the code is attempting 
>> to reset the system by setting various register bits in the PMIC ?! I know 
>> all about the registers of the PMIC, or rather can find otu what is what 
>> really quick by reading the datasheet which I have right in front of me. 
>> That is not what I'm having an issue grasping. It seems to me that a 
>> shutdown in this manner would not be clean. However, it could be that 
>> setting these register bits as such may not cause an immediate power down. 
>> *That* is what I find unclear.
>> 
>> /* Set the PMIC to shutdown on PWR_EN toggle */
>>     if (status_off) {
>>         ret = tps65217_set_bits(tps, TPS65217_REG_STATUS,
>>                 TPS65217_STATUS_OFF, TPS65217_STATUS_OFF,
>>                 TPS65217_PROTECT_NONE);
>>         if (ret)
>>             dev_warn(tps->dev, "unable to set the status OFF\n");
>>     }
>> 
>> The comment above the code seems to indicate that PWR_EN is causing a 
>> shutdown based on being toggle. However, PWR_EN is *NOT* a button, or even a 
>> line connected to a button. From the data sheet . . .
>> 
>> PWR_EN
>> Enable input for DCDC1, 2, 3 converters and LDO1, 2, 3, 4. Pull this pin 
>> high to start the
>> power-up sequence.
>> 
>>  In the schematic, PWR_EN is not connected to any button. Period. The button 
>> is connected to PB_IN.
>> 
>> Anyway, the rest of the code is inconsequential.
>> 
>> On Sun, Apr 17, 2016 at 3:23 PM, John Syne <[email protected] 
>> <mailto:[email protected]>> wrote:
>> Never mind, I found it.
>> 
>> drivers/mfd/tps65217.c line 164
>> 
>> Regards,
>> John
>> 
>> 
>> 
>> 
>>> On Apr 17, 2016, at 2:37 PM, William Hermans <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>> So no one has any idea ? I'm looking for the module, that traps power 
>>> events, and shuts down the BBB. All I need is a file name. It's pretty hard 
>>> making sense of the mess that is /drivers/mfd, and the documentation does 
>>> not seem to be helpful either.
>>> 
>>> Documentation/power/regulator/charger-management.txt does not exist in my 
>>> repo, nor in Linus' repo either. There is a similar file, but nothing 
>>> apparently related to our hardware. Passed that, most of the stuff int the 
>>> Documentation/power directory seems to be related to ACPI, which again, has 
>>> nothing to do with even our architecture . . .
>>> 
>>> On Sat, Apr 16, 2016 at 9:09 PM, William Hermans <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> So I've only found this so far. 
>>> https://github.com/torvalds/linux/blob/master/drivers/mfd/tps65217.c#L222-#L229
>>>  
>>> <https://github.com/torvalds/linux/blob/master/drivers/mfd/tps65217.c#L222-%23L229>
>>> 
>>> Which I pretty much had already figured out this morning right after I 
>>> posted. Pretty much, the PMIC sees a condition, that needs attention. It 
>>> writes some values to registers that relate to the given condition, and 
>>> then sends an NMI out to the am335x processor. Where the am335x processor 
>>> immediately picks up that the PMIC needs attention( the whole point of an 
>>> NMI ), reads the register values out of the PMIC to determine what action 
>>> needs to be taken. Which in the case of the power button being pressed. the 
>>> am335x issues a shutdown now -h ( Linux ) Which looking at the code, 
>>> actually seems like the LKM is actually writing to the PMIC registers to do 
>>> this ?!
>>> 
>>> Anyway, no idea how a power good condition is being acted on *still*. 
>>> Meaning, no idea how when a battery is connected, when the external power 
>>> somehow goes missing. How that particular shutdown is happening, and from 
>>> where.
>>> 
>>> On Sat, Apr 16, 2016 at 4:32 PM, John Syne <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> I’m not sure, but best place to look would be 
>>> Documentation/power/regulator/charger-management.txt. I believe the PMIC 
>>> issues event when AC is removed. 
>>> 
>>> Regards,
>>> John
>>> 
>>> 
>>> 
>>> 
>>>> On Apr 16, 2016, at 12:59 PM, William Hermans <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> 
>>>> Also from what I've read this behavior is different between console and 
>>>> LXDE images. So if this is true I understand that. I do not want the 
>>>> behaviors that each of these images provides, but wish to customize my own.
>>>> 
>>>> 
>>>> On Sat, Apr 16, 2016 at 12:55 PM, William Hermans <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> When a battery is connected to a beaglebone black, how does the software 
>>>> know to issue a shutdown when power is no longer coming in ? More 
>>>> specifically I'm interested in which file / script performs this action, 
>>>> and what mechanism triggers this behavior.
>>>> 
>>>> My intentions are to modify / customize what actually happens when power 
>>>> to the board is battery only.
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> -- 
>>>> For more options, visit http://beagleboard.org/discuss 
>>>> <http://beagleboard.org/discuss>
>>>> --- 
>>>> You received this message because you are subscribed to the Google Groups 
>>>> "BeagleBoard" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>>> email to [email protected] 
>>>> <mailto:[email protected]>.
>>>> For more options, visit https://groups.google.com/d/optout 
>>>> <https://groups.google.com/d/optout>.
>>>> 
>>>> 
>>>> -- 
>>>> For more options, visit http://beagleboard.org/discuss 
>>>> <http://beagleboard.org/discuss>
>>>> --- 
>>>> You received this message because you are subscribed to the Google Groups 
>>>> "BeagleBoard" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>>> email to [email protected] 
>>>> <mailto:[email protected]>.
>>>> For more options, visit https://groups.google.com/d/optout 
>>>> <https://groups.google.com/d/optout>.
>>> 
>>> 
>>> -- 
>>> For more options, visit http://beagleboard.org/discuss 
>>> <http://beagleboard.org/discuss>
>>> --- 
>>> You received this message because you are subscribed to the Google Groups 
>>> "BeagleBoard" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>> email to [email protected] 
>>> <mailto:[email protected]>.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/beagleboard/F27E94CA-369F-4E5D-8555-EEAD3B034C28%40gmail.com
>>>  
>>> <https://groups.google.com/d/msgid/beagleboard/F27E94CA-369F-4E5D-8555-EEAD3B034C28%40gmail.com?utm_medium=email&utm_source=footer>.
>>> 
>>> For more options, visit https://groups.google.com/d/optout 
>>> <https://groups.google.com/d/optout>.
>>> 
>>> 
>>> 
>>> -- 
>>> For more options, visit http://beagleboard.org/discuss 
>>> <http://beagleboard.org/discuss>
>>> --- 
>>> You received this message because you are subscribed to the Google Groups 
>>> "BeagleBoard" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>> email to [email protected] 
>>> <mailto:[email protected]>.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/beagleboard/CALHSORqNNeWN9uW_WDsTQC%2BNuArTq%2BtjGMVO5a%2Be-S6cyDk21w%40mail.gmail.com
>>>  
>>> <https://groups.google.com/d/msgid/beagleboard/CALHSORqNNeWN9uW_WDsTQC%2BNuArTq%2BtjGMVO5a%2Be-S6cyDk21w%40mail.gmail.com?utm_medium=email&utm_source=footer>.
>>> For more options, visit https://groups.google.com/d/optout 
>>> <https://groups.google.com/d/optout>.
>> 
>> 
>> -- 
>> For more options, visit http://beagleboard.org/discuss 
>> <http://beagleboard.org/discuss>
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "BeagleBoard" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected] 
>> <mailto:[email protected]>.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/beagleboard/D02D2BC4-66ED-434B-B7D9-66154797FDB7%40gmail.com
>>  
>> <https://groups.google.com/d/msgid/beagleboard/D02D2BC4-66ED-434B-B7D9-66154797FDB7%40gmail.com?utm_medium=email&utm_source=footer>.
>> 
>> For more options, visit https://groups.google.com/d/optout 
>> <https://groups.google.com/d/optout>.
>> 
>> 
>> -- 
>> For more options, visit http://beagleboard.org/discuss 
>> <http://beagleboard.org/discuss>
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "BeagleBoard" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected] 
>> <mailto:[email protected]>.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/beagleboard/CALHSORpC%3DDMupx5%2B57geCv20kHM3xO7DduTRkcbAg2f-RoXK0Q%40mail.gmail.com
>>  
>> <https://groups.google.com/d/msgid/beagleboard/CALHSORpC%3DDMupx5%2B57geCv20kHM3xO7DduTRkcbAg2f-RoXK0Q%40mail.gmail.com?utm_medium=email&utm_source=footer>.
>> For more options, visit https://groups.google.com/d/optout 
>> <https://groups.google.com/d/optout>.
> 
> 
> -- 
> For more options, visit http://beagleboard.org/discuss 
> <http://beagleboard.org/discuss>
> --- 
> You received this message because you are subscribed to the Google Groups 
> "BeagleBoard" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected] 
> <mailto:[email protected]>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/beagleboard/AF28B73F-B1CF-436A-988A-C9B0F685B39A%40gmail.com
>  
> <https://groups.google.com/d/msgid/beagleboard/AF28B73F-B1CF-436A-988A-C9B0F685B39A%40gmail.com?utm_medium=email&utm_source=footer>.
> 
> For more options, visit https://groups.google.com/d/optout 
> <https://groups.google.com/d/optout>.
> 
> 
> -- 
> For more options, visit http://beagleboard.org/discuss 
> <http://beagleboard.org/discuss>
> --- 
> You received this message because you are subscribed to the Google Groups 
> "BeagleBoard" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected] 
> <mailto:[email protected]>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/beagleboard/CALHSORq8%2Bn5s4vs_0ZUVJ0qaf-4puQWowGWYRTHfO7yi%3DM2V9g%40mail.gmail.com
>  
> <https://groups.google.com/d/msgid/beagleboard/CALHSORq8%2Bn5s4vs_0ZUVJ0qaf-4puQWowGWYRTHfO7yi%3DM2V9g%40mail.gmail.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout 
> <https://groups.google.com/d/optout>.

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/beagleboard/2A3CC1B5-64A5-4449-8BB2-3874E479ED8E%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to