Skip to content

Commit 3b5dd3a

Browse files
reid-psre
authored andcommitted
power: supply: sbs-battery: Use gpio_desc and sleeping calls for battery detect
Switch to using new gpio_desc interface and devm gpio get calls to automatically manage gpio resource. Use gpiod_get_value which handles active high / low calls. If gpio_detect is set then force loading of the driver as it is reasonable to assume that the battery may not be present. Update the is_present flag immediately in the IRQ. Remove legacy gpio specification from platform data. Signed-off-by: Phil Reid <[email protected]> Signed-off-by: Sebastian Reichel <[email protected]>
1 parent 528e350 commit 3b5dd3a

File tree

2 files changed

+34
-71
lines changed

2 files changed

+34
-71
lines changed

drivers/power/supply/sbs-battery.c

Lines changed: 34 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include <linux/i2c.h>
2727
#include <linux/slab.h>
2828
#include <linux/interrupt.h>
29-
#include <linux/gpio.h>
29+
#include <linux/gpio/consumer.h>
3030
#include <linux/of.h>
3131
#include <linux/stat.h>
3232

@@ -165,7 +165,7 @@ struct sbs_info {
165165
struct power_supply *power_supply;
166166
struct sbs_platform_data *pdata;
167167
bool is_present;
168-
bool gpio_detect;
168+
struct gpio_desc *gpio_detect;
169169
bool enable_detection;
170170
int last_state;
171171
int poll_time;
@@ -306,13 +306,11 @@ static int sbs_get_battery_presence_and_health(
306306
s32 ret;
307307
struct sbs_info *chip = i2c_get_clientdata(client);
308308

309-
if (psp == POWER_SUPPLY_PROP_PRESENT &&
310-
chip->gpio_detect) {
311-
ret = gpio_get_value(chip->pdata->battery_detect);
312-
if (ret == chip->pdata->battery_detect_present)
313-
val->intval = 1;
314-
else
315-
val->intval = 0;
309+
if (psp == POWER_SUPPLY_PROP_PRESENT && chip->gpio_detect) {
310+
ret = gpiod_get_value_cansleep(chip->gpio_detect);
311+
if (ret < 0)
312+
return ret;
313+
val->intval = ret;
316314
chip->is_present = val->intval;
317315
return ret;
318316
}
@@ -683,7 +681,12 @@ static irqreturn_t sbs_irq(int irq, void *devid)
683681
{
684682
struct sbs_info *chip = devid;
685683
struct power_supply *battery = chip->power_supply;
684+
int ret;
686685

686+
ret = gpiod_get_value_cansleep(chip->gpio_detect);
687+
if (ret < 0)
688+
return ret;
689+
chip->is_present = ret;
687690
power_supply_changed(battery);
688691

689692
return IRQ_HANDLED;
@@ -750,35 +753,29 @@ static const struct of_device_id sbs_dt_ids[] = {
750753
};
751754
MODULE_DEVICE_TABLE(of, sbs_dt_ids);
752755

753-
static struct sbs_platform_data *sbs_of_populate_pdata(
754-
struct i2c_client *client)
756+
static struct sbs_platform_data *sbs_of_populate_pdata(struct sbs_info *chip)
755757
{
758+
struct i2c_client *client = chip->client;
756759
struct device_node *of_node = client->dev.of_node;
757-
struct sbs_platform_data *pdata = client->dev.platform_data;
758-
enum of_gpio_flags gpio_flags;
760+
struct sbs_platform_data *pdata;
759761
int rc;
760762
u32 prop;
761763

762764
/* verify this driver matches this device */
763765
if (!of_node)
764766
return NULL;
765767

766-
/* if platform data is set, honor it */
767-
if (pdata)
768-
return pdata;
769-
770768
/* first make sure at least one property is set, otherwise
771769
* it won't change behavior from running without pdata.
772770
*/
773771
if (!of_get_property(of_node, "sbs,i2c-retry-count", NULL) &&
774-
!of_get_property(of_node, "sbs,poll-retry-count", NULL) &&
775-
!of_get_property(of_node, "sbs,battery-detect-gpios", NULL))
772+
!of_get_property(of_node, "sbs,poll-retry-count", NULL))
776773
goto of_out;
777774

778775
pdata = devm_kzalloc(&client->dev, sizeof(struct sbs_platform_data),
779776
GFP_KERNEL);
780777
if (!pdata)
781-
goto of_out;
778+
return ERR_PTR(-ENOMEM);
782779

783780
rc = of_property_read_u32(of_node, "sbs,i2c-retry-count", &prop);
784781
if (!rc)
@@ -788,27 +785,14 @@ static struct sbs_platform_data *sbs_of_populate_pdata(
788785
if (!rc)
789786
pdata->poll_retry_count = prop;
790787

791-
if (!of_get_property(of_node, "sbs,battery-detect-gpios", NULL)) {
792-
pdata->battery_detect = -1;
793-
goto of_out;
794-
}
795-
796-
pdata->battery_detect = of_get_named_gpio_flags(of_node,
797-
"sbs,battery-detect-gpios", 0, &gpio_flags);
798-
799-
if (gpio_flags & OF_GPIO_ACTIVE_LOW)
800-
pdata->battery_detect_present = 0;
801-
else
802-
pdata->battery_detect_present = 1;
803-
804788
of_out:
805789
return pdata;
806790
}
807791
#else
808792
static struct sbs_platform_data *sbs_of_populate_pdata(
809-
struct i2c_client *client)
793+
struct sbs_info *client)
810794
{
811-
return client->dev.platform_data;
795+
return ERR_PTR(-ENOSYS);
812796
}
813797
#endif
814798

@@ -846,7 +830,6 @@ static int sbs_probe(struct i2c_client *client,
846830

847831
chip->client = client;
848832
chip->enable_detection = false;
849-
chip->gpio_detect = false;
850833
psy_cfg.of_node = client->dev.of_node;
851834
psy_cfg.drv_data = chip;
852835
/* ignore first notification of external change, it is generated
@@ -855,38 +838,30 @@ static int sbs_probe(struct i2c_client *client,
855838
chip->ignore_changes = 1;
856839
chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN;
857840

858-
pdata = sbs_of_populate_pdata(client);
841+
if (!pdata)
842+
pdata = sbs_of_populate_pdata(chip);
843+
844+
if (IS_ERR(pdata))
845+
return PTR_ERR(pdata);
846+
847+
chip->pdata = pdata;
859848

860-
if (pdata) {
861-
chip->gpio_detect = gpio_is_valid(pdata->battery_detect);
862-
chip->pdata = pdata;
849+
chip->gpio_detect = devm_gpiod_get_optional(&client->dev,
850+
"sbs,battery-detect", GPIOD_IN);
851+
if (IS_ERR(chip->gpio_detect)) {
852+
dev_err(&client->dev, "Failed to get gpio: %ld\n",
853+
PTR_ERR(chip->gpio_detect));
854+
return PTR_ERR(chip->gpio_detect);
863855
}
864856

865857
i2c_set_clientdata(client, chip);
866858

867859
if (!chip->gpio_detect)
868860
goto skip_gpio;
869861

870-
rc = gpio_request(pdata->battery_detect, dev_name(&client->dev));
871-
if (rc) {
872-
dev_warn(&client->dev, "Failed to request gpio: %d\n", rc);
873-
chip->gpio_detect = false;
874-
goto skip_gpio;
875-
}
876-
877-
rc = gpio_direction_input(pdata->battery_detect);
878-
if (rc) {
879-
dev_warn(&client->dev, "Failed to get gpio as input: %d\n", rc);
880-
gpio_free(pdata->battery_detect);
881-
chip->gpio_detect = false;
882-
goto skip_gpio;
883-
}
884-
885-
irq = gpio_to_irq(pdata->battery_detect);
862+
irq = gpiod_to_irq(chip->gpio_detect);
886863
if (irq <= 0) {
887864
dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq);
888-
gpio_free(pdata->battery_detect);
889-
chip->gpio_detect = false;
890865
goto skip_gpio;
891866
}
892867

@@ -895,8 +870,6 @@ static int sbs_probe(struct i2c_client *client,
895870
dev_name(&client->dev), chip);
896871
if (rc) {
897872
dev_warn(&client->dev, "Failed to request irq: %d\n", rc);
898-
gpio_free(pdata->battery_detect);
899-
chip->gpio_detect = false;
900873
goto skip_gpio;
901874
}
902875

@@ -905,7 +878,7 @@ static int sbs_probe(struct i2c_client *client,
905878
* Before we register, we might need to make sure we can actually talk
906879
* to the battery.
907880
*/
908-
if (!force_load) {
881+
if (!(force_load || chip->gpio_detect)) {
909882
rc = sbs_read_word_data(client, sbs_data[REG_STATUS].addr);
910883

911884
if (rc < 0) {
@@ -934,19 +907,13 @@ static int sbs_probe(struct i2c_client *client,
934907
return 0;
935908

936909
exit_psupply:
937-
if (chip->gpio_detect)
938-
gpio_free(pdata->battery_detect);
939-
940910
return rc;
941911
}
942912

943913
static int sbs_remove(struct i2c_client *client)
944914
{
945915
struct sbs_info *chip = i2c_get_clientdata(client);
946916

947-
if (chip->gpio_detect)
948-
gpio_free(chip->pdata->battery_detect);
949-
950917
cancel_delayed_work_sync(&chip->work);
951918

952919
return 0;

include/linux/power/sbs-battery.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,11 @@
2626

2727
/**
2828
* struct sbs_platform_data - platform data for sbs devices
29-
* @battery_detect: GPIO which is used to detect battery presence
30-
* @battery_detect_present: gpio state when battery is present (0 / 1)
3129
* @i2c_retry_count: # of times to retry on i2c IO failure
3230
* @poll_retry_count: # of times to retry looking for new status after
3331
* external change notification
3432
*/
3533
struct sbs_platform_data {
36-
int battery_detect;
37-
int battery_detect_present;
3834
int i2c_retry_count;
3935
int poll_retry_count;
4036
};

0 commit comments

Comments
 (0)