^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * battery.c - ACPI Battery Driver (Revision: 2.0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/async.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/suspend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/power_supply.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <acpi/battery.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PREFIX "ACPI: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define ACPI_BATTERY_CAPACITY_VALID(capacity) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) ((capacity) != 0 && (capacity) != ACPI_BATTERY_VALUE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define ACPI_BATTERY_DEVICE_NAME "Battery"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* Battery power unit: 0 means mW, 1 means mA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define ACPI_BATTERY_POWER_UNIT_MA 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define ACPI_BATTERY_STATE_DISCHARGING 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define ACPI_BATTERY_STATE_CHARGING 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define ACPI_BATTERY_STATE_CRITICAL 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define _COMPONENT ACPI_BATTERY_COMPONENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ACPI_MODULE_NAME("battery");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) MODULE_AUTHOR("Paul Diefenbaugh");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) MODULE_DESCRIPTION("ACPI Battery Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static async_cookie_t async_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static bool battery_driver_registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static int battery_bix_broken_package;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static int battery_notification_delay_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static int battery_ac_is_broken;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static int battery_check_pmic = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static int battery_quirk_notcharging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static unsigned int cache_time = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) module_param(cache_time, uint, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static const struct acpi_device_id battery_device_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {"PNP0C0A", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Microsoft Surface Go 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {"MSHW0146", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {"", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MODULE_DEVICE_TABLE(acpi, battery_device_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Lists of PMIC ACPI HIDs with an (often better) native battery driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static const char * const acpi_battery_blacklist[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) "INT33F4", /* X-Powers AXP288 PMIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ACPI_BATTERY_ALARM_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ACPI_BATTERY_XINFO_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* On Lenovo Thinkpad models from 2010 and 2011, the power unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) switches between mWh and mAh depending on whether the system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) is running on battery or not. When mAh is the unit, most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) reported values are incorrect and need to be adjusted by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) 10000/design_voltage. Verified on x201, t410, t410s, and x220.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) Pre-2010 and 2012 models appear to always report in mWh and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) are thus unaffected (tested with t42, t61, t500, x200, x300,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) and x230). Also, in mid-2012 Lenovo issued a BIOS update for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) the 2011 models that fixes the issue (tested on x220 with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) post-1.29 BIOS), but as of Nov. 2012, no such update is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) available for the 2010 models. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ACPI_BATTERY_QUIRK_THINKPAD_MAH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* for batteries reporting current capacity with design capacity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * on a full charge, but showing degradation in full charge cap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct acpi_battery {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct mutex sysfs_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct power_supply *bat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct power_supply_desc bat_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct acpi_device *device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct notifier_block pm_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) unsigned long update_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int rate_now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int capacity_now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int voltage_now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int design_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int full_charge_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int technology;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int design_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int design_capacity_warning;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int design_capacity_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int cycle_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int measurement_accuracy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int max_sampling_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int min_sampling_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int max_averaging_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int min_averaging_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) int capacity_granularity_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int capacity_granularity_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int alarm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) char model_number[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) char serial_number[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) char type[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) char oem_info[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int power_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define to_acpi_battery(x) power_supply_get_drvdata(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static inline int acpi_battery_present(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return battery->device->status.battery_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static int acpi_battery_technology(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (!strcasecmp("NiCd", battery->type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return POWER_SUPPLY_TECHNOLOGY_NiCd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (!strcasecmp("NiMH", battery->type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return POWER_SUPPLY_TECHNOLOGY_NiMH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (!strcasecmp("LION", battery->type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return POWER_SUPPLY_TECHNOLOGY_LION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (!strncasecmp("LI-ION", battery->type, 6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return POWER_SUPPLY_TECHNOLOGY_LION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (!strcasecmp("LiP", battery->type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return POWER_SUPPLY_TECHNOLOGY_LIPO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static int acpi_battery_get_state(struct acpi_battery *battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static int acpi_battery_is_charged(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* charging, discharging or critical low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (battery->state != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* battery not reporting charge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) battery->capacity_now == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* good batteries update full_charge as the batteries degrade */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (battery->full_charge_capacity == battery->capacity_now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* fallback to using design values for broken batteries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (battery->design_capacity <= battery->capacity_now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* we don't do any sort of metric based on percentages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static bool acpi_battery_is_degraded(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) battery->full_charge_capacity < battery->design_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static int acpi_battery_handle_discharging(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * Some devices wrongly report discharging if the battery's charge level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * was above the device's start charging threshold atm the AC adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * was plugged in and the device thus did not start a new charge cycle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if ((battery_ac_is_broken || power_supply_is_system_supplied()) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) battery->rate_now == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return POWER_SUPPLY_STATUS_NOT_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int acpi_battery_get_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int full_capacity = ACPI_BATTERY_VALUE_UNKNOWN, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct acpi_battery *battery = to_acpi_battery(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (acpi_battery_present(battery)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* run battery update only if it is present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) acpi_battery_get_state(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) } else if (psp != POWER_SUPPLY_PROP_PRESENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case POWER_SUPPLY_PROP_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (battery->state & ACPI_BATTERY_STATE_DISCHARGING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) val->intval = acpi_battery_handle_discharging(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) else if (battery->state & ACPI_BATTERY_STATE_CHARGING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) val->intval = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) else if (acpi_battery_is_charged(battery))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) val->intval = POWER_SUPPLY_STATUS_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) else if (battery_quirk_notcharging)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) case POWER_SUPPLY_PROP_PRESENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) val->intval = acpi_battery_present(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) case POWER_SUPPLY_PROP_TECHNOLOGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) val->intval = acpi_battery_technology(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case POWER_SUPPLY_PROP_CYCLE_COUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) val->intval = battery->cycle_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) val->intval = battery->design_voltage * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case POWER_SUPPLY_PROP_VOLTAGE_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) val->intval = battery->voltage_now * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) case POWER_SUPPLY_PROP_CURRENT_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) case POWER_SUPPLY_PROP_POWER_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) val->intval = battery->rate_now * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) val->intval = battery->design_capacity * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) case POWER_SUPPLY_PROP_CHARGE_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case POWER_SUPPLY_PROP_ENERGY_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) val->intval = battery->full_charge_capacity * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) case POWER_SUPPLY_PROP_CHARGE_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case POWER_SUPPLY_PROP_ENERGY_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) val->intval = battery->capacity_now * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case POWER_SUPPLY_PROP_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) full_capacity = battery->full_charge_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) else if (ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) full_capacity = battery->design_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) val->intval = battery->capacity_now * 100/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) full_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (battery->state & ACPI_BATTERY_STATE_CRITICAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) else if (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) (battery->capacity_now <= battery->alarm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) else if (acpi_battery_is_charged(battery))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) case POWER_SUPPLY_PROP_MODEL_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) val->strval = battery->model_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) case POWER_SUPPLY_PROP_MANUFACTURER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) val->strval = battery->oem_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) case POWER_SUPPLY_PROP_SERIAL_NUMBER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) val->strval = battery->serial_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static enum power_supply_property charge_battery_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) POWER_SUPPLY_PROP_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) POWER_SUPPLY_PROP_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) POWER_SUPPLY_PROP_TECHNOLOGY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) POWER_SUPPLY_PROP_CYCLE_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) POWER_SUPPLY_PROP_VOLTAGE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) POWER_SUPPLY_PROP_CURRENT_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) POWER_SUPPLY_PROP_CHARGE_FULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) POWER_SUPPLY_PROP_CHARGE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) POWER_SUPPLY_PROP_CAPACITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) POWER_SUPPLY_PROP_CAPACITY_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) POWER_SUPPLY_PROP_MODEL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) POWER_SUPPLY_PROP_MANUFACTURER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) POWER_SUPPLY_PROP_SERIAL_NUMBER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static enum power_supply_property charge_battery_full_cap_broken_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) POWER_SUPPLY_PROP_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) POWER_SUPPLY_PROP_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) POWER_SUPPLY_PROP_TECHNOLOGY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) POWER_SUPPLY_PROP_CYCLE_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) POWER_SUPPLY_PROP_VOLTAGE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) POWER_SUPPLY_PROP_CURRENT_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) POWER_SUPPLY_PROP_CHARGE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) POWER_SUPPLY_PROP_MODEL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) POWER_SUPPLY_PROP_MANUFACTURER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) POWER_SUPPLY_PROP_SERIAL_NUMBER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static enum power_supply_property energy_battery_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) POWER_SUPPLY_PROP_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) POWER_SUPPLY_PROP_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) POWER_SUPPLY_PROP_TECHNOLOGY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) POWER_SUPPLY_PROP_CYCLE_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) POWER_SUPPLY_PROP_VOLTAGE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) POWER_SUPPLY_PROP_POWER_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) POWER_SUPPLY_PROP_ENERGY_FULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) POWER_SUPPLY_PROP_ENERGY_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) POWER_SUPPLY_PROP_CAPACITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) POWER_SUPPLY_PROP_CAPACITY_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) POWER_SUPPLY_PROP_MODEL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) POWER_SUPPLY_PROP_MANUFACTURER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) POWER_SUPPLY_PROP_SERIAL_NUMBER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static enum power_supply_property energy_battery_full_cap_broken_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) POWER_SUPPLY_PROP_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) POWER_SUPPLY_PROP_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) POWER_SUPPLY_PROP_TECHNOLOGY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) POWER_SUPPLY_PROP_CYCLE_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) POWER_SUPPLY_PROP_VOLTAGE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) POWER_SUPPLY_PROP_POWER_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) POWER_SUPPLY_PROP_ENERGY_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) POWER_SUPPLY_PROP_MODEL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) POWER_SUPPLY_PROP_MANUFACTURER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) POWER_SUPPLY_PROP_SERIAL_NUMBER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* --------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) Battery Management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) -------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct acpi_offsets {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) size_t offset; /* offset inside struct acpi_sbs_battery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) u8 mode; /* int or string? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static const struct acpi_offsets state_offsets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {offsetof(struct acpi_battery, state), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {offsetof(struct acpi_battery, rate_now), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {offsetof(struct acpi_battery, capacity_now), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {offsetof(struct acpi_battery, voltage_now), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static const struct acpi_offsets info_offsets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {offsetof(struct acpi_battery, power_unit), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {offsetof(struct acpi_battery, design_capacity), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {offsetof(struct acpi_battery, full_charge_capacity), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {offsetof(struct acpi_battery, technology), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {offsetof(struct acpi_battery, design_voltage), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {offsetof(struct acpi_battery, design_capacity_warning), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {offsetof(struct acpi_battery, design_capacity_low), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {offsetof(struct acpi_battery, capacity_granularity_1), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {offsetof(struct acpi_battery, capacity_granularity_2), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {offsetof(struct acpi_battery, model_number), 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {offsetof(struct acpi_battery, serial_number), 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {offsetof(struct acpi_battery, type), 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {offsetof(struct acpi_battery, oem_info), 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static const struct acpi_offsets extended_info_offsets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {offsetof(struct acpi_battery, revision), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {offsetof(struct acpi_battery, power_unit), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {offsetof(struct acpi_battery, design_capacity), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {offsetof(struct acpi_battery, full_charge_capacity), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {offsetof(struct acpi_battery, technology), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {offsetof(struct acpi_battery, design_voltage), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {offsetof(struct acpi_battery, design_capacity_warning), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {offsetof(struct acpi_battery, design_capacity_low), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {offsetof(struct acpi_battery, cycle_count), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {offsetof(struct acpi_battery, measurement_accuracy), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {offsetof(struct acpi_battery, max_sampling_time), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {offsetof(struct acpi_battery, min_sampling_time), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {offsetof(struct acpi_battery, max_averaging_interval), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {offsetof(struct acpi_battery, min_averaging_interval), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {offsetof(struct acpi_battery, capacity_granularity_1), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {offsetof(struct acpi_battery, capacity_granularity_2), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {offsetof(struct acpi_battery, model_number), 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {offsetof(struct acpi_battery, serial_number), 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {offsetof(struct acpi_battery, type), 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {offsetof(struct acpi_battery, oem_info), 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static int extract_package(struct acpi_battery *battery,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) union acpi_object *package,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) const struct acpi_offsets *offsets, int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) union acpi_object *element;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (package->type != ACPI_TYPE_PACKAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) for (i = 0; i < num; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (package->package.count <= i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) element = &package->package.elements[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (offsets[i].mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) u8 *ptr = (u8 *)battery + offsets[i].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (element->type == ACPI_TYPE_STRING ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) element->type == ACPI_TYPE_BUFFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) strncpy(ptr, element->string.pointer, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) else if (element->type == ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) strncpy(ptr, (u8 *)&element->integer.value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ptr[sizeof(u64)] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *ptr = 0; /* don't have value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int *x = (int *)((u8 *)battery + offsets[i].offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) *x = (element->type == ACPI_TYPE_INTEGER) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) element->integer.value : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static int acpi_battery_get_status(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (acpi_bus_get_status(battery->device)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static int extract_battery_info(const int use_bix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct acpi_battery *battery,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) const struct acpi_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) int result = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (use_bix && battery_bix_broken_package)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) result = extract_package(battery, buffer->pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) extended_info_offsets + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ARRAY_SIZE(extended_info_offsets) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) else if (use_bix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) result = extract_package(battery, buffer->pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) extended_info_offsets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ARRAY_SIZE(extended_info_offsets));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) result = extract_package(battery, buffer->pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) info_offsets, ARRAY_SIZE(info_offsets));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) battery->full_charge_capacity = battery->design_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) battery->power_unit && battery->design_voltage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) battery->design_capacity = battery->design_capacity *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 10000 / battery->design_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) battery->full_charge_capacity = battery->full_charge_capacity *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 10000 / battery->design_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) battery->design_capacity_warning =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) battery->design_capacity_warning *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 10000 / battery->design_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /* Curiously, design_capacity_low, unlike the rest of them,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) is correct. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /* capacity_granularity_* equal 1 on the systems tested, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) it's impossible to tell if they would need an adjustment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) or not if their values were higher. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) battery->capacity_now > battery->full_charge_capacity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) battery->capacity_now = battery->full_charge_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static int acpi_battery_get_info(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) const int xinfo = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) int use_bix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) int result = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (!acpi_battery_present(battery))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) for (use_bix = xinfo ? 1 : 0; use_bix >= 0; use_bix--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) acpi_status status = AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) mutex_lock(&battery->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) status = acpi_evaluate_object(battery->device->handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) use_bix ? "_BIX":"_BIF",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) NULL, &buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) mutex_unlock(&battery->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) use_bix ? "_BIX":"_BIF"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) result = extract_battery_info(use_bix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) battery,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) &buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) kfree(buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (!result && !use_bix && xinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) pr_warn(FW_BUG "The _BIX method is broken, using _BIF.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static int acpi_battery_get_state(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) acpi_status status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (!acpi_battery_present(battery))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (battery->update_time &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) time_before(jiffies, battery->update_time +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) msecs_to_jiffies(cache_time)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) mutex_lock(&battery->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) status = acpi_evaluate_object(battery->device->handle, "_BST",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) NULL, &buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) mutex_unlock(&battery->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) result = extract_package(battery, buffer.pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) state_offsets, ARRAY_SIZE(state_offsets));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) battery->update_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) kfree(buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /* For buggy DSDTs that report negative 16-bit values for either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * charging or discharging current and/or report 0 as 65536
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * due to bad math.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) (s16)(battery->rate_now) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) battery->rate_now = abs((s16)battery->rate_now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) pr_warn_once(FW_BUG "battery: (dis)charge rate invalid.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) && battery->capacity_now >= 0 && battery->capacity_now <= 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) battery->capacity_now = (battery->capacity_now *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) battery->full_charge_capacity) / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) battery->power_unit && battery->design_voltage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) battery->capacity_now = battery->capacity_now *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 10000 / battery->design_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) battery->capacity_now > battery->full_charge_capacity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) battery->capacity_now = battery->full_charge_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static int acpi_battery_set_alarm(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) acpi_status status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (!acpi_battery_present(battery) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) mutex_lock(&battery->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) status = acpi_execute_simple_method(battery->device->handle, "_BTP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) battery->alarm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) mutex_unlock(&battery->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static int acpi_battery_init_alarm(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) /* See if alarms are supported, and if so, set default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (!acpi_has_method(battery->device->handle, "_BTP")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (!battery->alarm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) battery->alarm = battery->design_capacity_warning;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return acpi_battery_set_alarm(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static ssize_t acpi_battery_alarm_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return sprintf(buf, "%d\n", battery->alarm * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) static ssize_t acpi_battery_alarm_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) unsigned long x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (sscanf(buf, "%lu\n", &x) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) battery->alarm = x/1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (acpi_battery_present(battery))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) acpi_battery_set_alarm(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) static const struct device_attribute alarm_attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) .attr = {.name = "alarm", .mode = 0644},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) .show = acpi_battery_alarm_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) .store = acpi_battery_alarm_store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * The Battery Hooking API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * This API is used inside other drivers that need to expose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * platform-specific behaviour within the generic driver in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * generic way.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static LIST_HEAD(acpi_battery_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static LIST_HEAD(battery_hook_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static DEFINE_MUTEX(hook_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct acpi_battery *battery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * In order to remove a hook, we first need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * de-register all the batteries that are registered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) mutex_lock(&hook_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) list_for_each_entry(battery, &acpi_battery_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) hook->remove_battery(battery->bat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) list_del(&hook->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) mutex_unlock(&hook_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) pr_info("extension unregistered: %s\n", hook->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) void battery_hook_unregister(struct acpi_battery_hook *hook)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) __battery_hook_unregister(hook, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) EXPORT_SYMBOL_GPL(battery_hook_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) void battery_hook_register(struct acpi_battery_hook *hook)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct acpi_battery *battery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) mutex_lock(&hook_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) INIT_LIST_HEAD(&hook->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) list_add(&hook->list, &battery_hook_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * Now that the driver is registered, we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * to notify the hook that a battery is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * for each battery, so that the driver may add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * its attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) list_for_each_entry(battery, &acpi_battery_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (hook->add_battery(battery->bat)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * If a add-battery returns non-zero,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) * the registration of the extension has failed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) * and we will not add it to the list of loaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * hooks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) pr_err("extension failed to load: %s", hook->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) __battery_hook_unregister(hook, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) pr_info("new extension: %s\n", hook->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) mutex_unlock(&hook_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) EXPORT_SYMBOL_GPL(battery_hook_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * This function gets called right after the battery sysfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * attributes have been added, so that the drivers that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * define custom sysfs attributes can add their own.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static void battery_hook_add_battery(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct acpi_battery_hook *hook_node, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) mutex_lock(&hook_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) INIT_LIST_HEAD(&battery->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) list_add(&battery->list, &acpi_battery_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) * Since we added a new battery to the list, we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * iterate over the hooks and call add_battery for each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * hook that was registered. This usually happens
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * when a battery gets hotplugged or initialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * during the battery module initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) list_for_each_entry_safe(hook_node, tmp, &battery_hook_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (hook_node->add_battery(battery->bat)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * The notification of the extensions has failed, to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * prevent further errors we will unload the extension.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) pr_err("error in extension, unloading: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) hook_node->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) __battery_hook_unregister(hook_node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) mutex_unlock(&hook_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) static void battery_hook_remove_battery(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct acpi_battery_hook *hook;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) mutex_lock(&hook_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * Before removing the hook, we need to remove all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * custom attributes from the battery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) list_for_each_entry(hook, &battery_hook_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) hook->remove_battery(battery->bat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /* Then, just remove the battery from the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) list_del(&battery->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) mutex_unlock(&hook_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) static void __exit battery_hook_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct acpi_battery_hook *hook;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) struct acpi_battery_hook *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * At this point, the acpi_bus_unregister_driver()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * has called remove for all batteries. We just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * need to remove the hooks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) __battery_hook_unregister(hook, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) mutex_destroy(&hook_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) static int sysfs_add_battery(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct power_supply_config psy_cfg = { .drv_data = battery, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) bool full_cap_broken = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) !ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) full_cap_broken = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (full_cap_broken) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) battery->bat_desc.properties =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) charge_battery_full_cap_broken_props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) battery->bat_desc.num_properties =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) ARRAY_SIZE(charge_battery_full_cap_broken_props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) battery->bat_desc.properties = charge_battery_props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) battery->bat_desc.num_properties =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) ARRAY_SIZE(charge_battery_props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (full_cap_broken) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) battery->bat_desc.properties =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) energy_battery_full_cap_broken_props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) battery->bat_desc.num_properties =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) ARRAY_SIZE(energy_battery_full_cap_broken_props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) battery->bat_desc.properties = energy_battery_props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) battery->bat_desc.num_properties =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ARRAY_SIZE(energy_battery_props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) battery->bat_desc.name = acpi_device_bid(battery->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) battery->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) battery->bat_desc.get_property = acpi_battery_get_property;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) battery->bat = power_supply_register_no_ws(&battery->device->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) &battery->bat_desc, &psy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (IS_ERR(battery->bat)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) int result = PTR_ERR(battery->bat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) battery->bat = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) battery_hook_add_battery(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return device_create_file(&battery->bat->dev, &alarm_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) static void sysfs_remove_battery(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) mutex_lock(&battery->sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (!battery->bat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) mutex_unlock(&battery->sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) battery_hook_remove_battery(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) device_remove_file(&battery->bat->dev, &alarm_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) power_supply_unregister(battery->bat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) battery->bat = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) mutex_unlock(&battery->sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) static void find_battery(const struct dmi_header *dm, void *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct acpi_battery *battery = (struct acpi_battery *)private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) /* Note: the hardcoded offsets below have been extracted from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) the source code of dmidecode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) const u8 *dmi_data = (const u8 *)(dm + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (dm->length >= 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) dmi_capacity *= dmi_data[17];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (battery->design_capacity * battery->design_voltage / 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) != dmi_capacity &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) battery->design_capacity * 10 == dmi_capacity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) &battery->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * According to the ACPI spec, some kinds of primary batteries can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * report percentage battery remaining capacity directly to OS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * In this case, it reports the Last Full Charged Capacity == 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * and BatteryPresentRate == 0xFFFFFFFF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * Now we found some battery reports percentage remaining capacity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * even if it's rechargeable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * https://bugzilla.kernel.org/show_bug.cgi?id=15979
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * Handle this correctly so that they won't break userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) static void acpi_battery_quirks(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (battery->full_charge_capacity == 100 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) battery->capacity_now >= 0 && battery->capacity_now <= 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) battery->full_charge_capacity = battery->design_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) battery->capacity_now = (battery->capacity_now *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) battery->full_charge_capacity) / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) const char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) s = dmi_get_system_info(DMI_PRODUCT_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (s && !strncasecmp(s, "ThinkPad", 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) dmi_walk(find_battery, battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) &battery->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) battery->design_voltage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) battery->design_capacity =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) battery->design_capacity *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 10000 / battery->design_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) battery->full_charge_capacity =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) battery->full_charge_capacity *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) 10000 / battery->design_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) battery->design_capacity_warning =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) battery->design_capacity_warning *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) 10000 / battery->design_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) battery->capacity_now = battery->capacity_now *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) 10000 / battery->design_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (acpi_battery_is_degraded(battery) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) battery->capacity_now > battery->full_charge_capacity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) set_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) battery->capacity_now = battery->full_charge_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) static int acpi_battery_update(struct acpi_battery *battery, bool resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) int result = acpi_battery_get_status(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (!acpi_battery_present(battery)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) sysfs_remove_battery(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) battery->update_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (!battery->update_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) result = acpi_battery_get_info(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) acpi_battery_init_alarm(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) result = acpi_battery_get_state(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) acpi_battery_quirks(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (!battery->bat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) result = sysfs_add_battery(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) * Wakeup the system if battery is critical low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) * or lower than the alarm level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) (battery->capacity_now <= battery->alarm)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) acpi_pm_wakeup_event(&battery->device->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static void acpi_battery_refresh(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) int power_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (!battery->bat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) power_unit = battery->power_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) acpi_battery_get_info(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (power_unit == battery->power_unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /* The battery has changed its reporting units. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) sysfs_remove_battery(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) sysfs_add_battery(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) /* --------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) Driver Interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) -------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static void acpi_battery_notify(struct acpi_device *device, u32 event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct acpi_battery *battery = acpi_driver_data(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct power_supply *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (!battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) old = battery->bat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) * On Acer Aspire V5-573G notifications are sometimes triggered too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) * early. For example, when AC is unplugged and notification is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * triggered, battery state is still reported as "Full", and changes to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * "Discharging" only after short delay, without any notification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (battery_notification_delay_ms > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) msleep(battery_notification_delay_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (event == ACPI_BATTERY_NOTIFY_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) acpi_battery_refresh(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) acpi_battery_update(battery, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) acpi_bus_generate_netlink_event(device->pnp.device_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) dev_name(&device->dev), event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) acpi_battery_present(battery));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) acpi_notifier_call_chain(device, event, acpi_battery_present(battery));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) /* acpi_battery_update could remove power_supply object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (old && battery->bat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) power_supply_changed(battery->bat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) static int battery_notify(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) unsigned long mode, void *_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) struct acpi_battery *battery = container_of(nb, struct acpi_battery,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) pm_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) case PM_POST_HIBERNATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) case PM_POST_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (!acpi_battery_present(battery))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (battery->bat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) acpi_battery_refresh(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) result = acpi_battery_get_info(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) result = sysfs_add_battery(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) acpi_battery_init_alarm(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) acpi_battery_get_state(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) battery_bix_broken_package_quirk(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) battery_bix_broken_package = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) battery_notification_delay_quirk(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) battery_notification_delay_ms = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) battery_ac_is_broken_quirk(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) battery_ac_is_broken = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) battery_do_not_check_pmic_quirk(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) battery_check_pmic = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) static int __init battery_quirk_not_charging(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) battery_quirk_notcharging = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) static const struct dmi_system_id bat_dmi_table[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* NEC LZ750/LS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) .callback = battery_bix_broken_package_quirk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) /* Acer Aspire V5-573G */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) .callback = battery_notification_delay_quirk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) /* Point of View mobii wintab p800w */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) .callback = battery_ac_is_broken_quirk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) /* Above matches are too generic, add bios-date match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) /* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) .callback = battery_do_not_check_pmic_quirk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) /* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) .callback = battery_do_not_check_pmic_quirk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) DMI_MATCH(DMI_PRODUCT_NAME, "80XF"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) * On Lenovo ThinkPads the BIOS specification defines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) * a state when the bits for charging and discharging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) * are both set to 0. That state is "Not Charging".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) .callback = battery_quirk_not_charging,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) .ident = "Lenovo ThinkPad",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) /* Microsoft Surface Go 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) .callback = battery_notification_delay_quirk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go 3"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) * Some machines'(E,G Lenovo Z480) ECs are not stable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) * during boot up and this causes battery driver fails to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) * probed due to failure of getting battery information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) * from EC sometimes. After several retries, the operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) * may work. So add retry code here and 20ms sleep between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) * every retries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) static int acpi_battery_update_retry(struct acpi_battery *battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) int retry, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) for (retry = 5; retry; retry--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) ret = acpi_battery_update(battery, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) static int acpi_battery_add(struct acpi_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) struct acpi_battery *battery = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (!device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (device->dep_unmet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (!battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) battery->device = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) device->driver_data = battery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) mutex_init(&battery->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) mutex_init(&battery->sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (acpi_has_method(battery->device->handle, "_BIX"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) result = acpi_battery_update_retry(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) pr_info(PREFIX "%s Slot [%s] (battery %s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) device->status.battery_present ? "present" : "absent");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) battery->pm_nb.notifier_call = battery_notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) register_pm_notifier(&battery->pm_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) device_init_wakeup(&device->dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) sysfs_remove_battery(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) mutex_destroy(&battery->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) mutex_destroy(&battery->sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) kfree(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) static int acpi_battery_remove(struct acpi_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) struct acpi_battery *battery = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (!device || !acpi_driver_data(device))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) device_init_wakeup(&device->dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) battery = acpi_driver_data(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) unregister_pm_notifier(&battery->pm_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) sysfs_remove_battery(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) mutex_destroy(&battery->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) mutex_destroy(&battery->sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) kfree(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) /* this is needed to learn about changes made in suspended state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) static int acpi_battery_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) struct acpi_battery *battery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) battery = acpi_driver_data(to_acpi_device(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (!battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) battery->update_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) acpi_battery_update(battery, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) #define acpi_battery_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) static struct acpi_driver acpi_battery_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) .name = "battery",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) .class = ACPI_BATTERY_CLASS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) .ids = battery_device_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) .add = acpi_battery_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) .remove = acpi_battery_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) .notify = acpi_battery_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) .drv.pm = &acpi_battery_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) dmi_check_system(bat_dmi_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (battery_check_pmic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) pr_info(PREFIX ACPI_BATTERY_DEVICE_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) ": found native %s PMIC, not loading\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) acpi_battery_blacklist[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) result = acpi_bus_register_driver(&acpi_battery_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) battery_driver_registered = (result == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) static int __init acpi_battery_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) if (acpi_disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) async_cookie = async_schedule(acpi_battery_init_async, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) static void __exit acpi_battery_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) async_synchronize_cookie(async_cookie + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (battery_driver_registered) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) acpi_bus_unregister_driver(&acpi_battery_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) battery_hook_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) module_init(acpi_battery_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) module_exit(acpi_battery_exit);