mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
Merge 5.10.182 into android12-5.10-lts
Changes in 5.10.182
x86/cpu: Add Raptor Lake to Intel family
x86/cpu: Drop spurious underscore from RAPTOR_LAKE #define
power: supply: bq27xxx: fix polarity of current_now
power: supply: bq27xxx: fix sign of current_now for newer ICs
power: supply: bq27xxx: make status more robust
power: supply: bq27xxx: Add cache parameter to bq27xxx_battery_current_and_status()
power: supply: bq27xxx: expose battery data when CI=1
power: supply: bq27xxx: Move bq27xxx_battery_update() down
power: supply: bq27xxx: Ensure power_supply_changed() is called on current sign changes
power: supply: bq27xxx: After charger plug in/out wait 0.5s for things to stabilize
power: supply: core: Refactor power_supply_set_input_current_limit_from_supplier()
power: supply: bq24190: Call power_supply_changed() after updating input current
regulator: Add regmap helper for ramp-delay setting
regulator: pca9450: Convert to use regulator_set_ramp_delay_regmap
regulator: pca9450: Fix BUCK2 enable_mask
net/mlx5: devcom only supports 2 ports
net/mlx5: Devcom, serialize devcom registration
net: phy: mscc: enable VSC8501/2 RGMII RX clock
bluetooth: Add cmd validity checks at the start of hci_sock_ioctl()
binder: fix UAF caused by faulty buffer cleanup
ipv{4,6}/raw: fix output xfrm lookup wrt protocol
netfilter: ctnetlink: Support offloaded conntrack entry deletion
Linux 5.10.182
Change-Id: I4c11a7f5fce0d9088f193a488a28b779944291a5
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
VERSION = 5
|
VERSION = 5
|
||||||
PATCHLEVEL = 10
|
PATCHLEVEL = 10
|
||||||
SUBLEVEL = 181
|
SUBLEVEL = 182
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = Dare mighty things
|
NAME = Dare mighty things
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,8 @@
|
|||||||
#define INTEL_FAM6_RAPTORLAKE_P 0xBA
|
#define INTEL_FAM6_RAPTORLAKE_P 0xBA
|
||||||
#define INTEL_FAM6_RAPTORLAKE_S 0xBF
|
#define INTEL_FAM6_RAPTORLAKE_S 0xBF
|
||||||
|
|
||||||
|
#define INTEL_FAM6_RAPTORLAKE 0xB7
|
||||||
|
|
||||||
/* "Small Core" Processors (Atom) */
|
/* "Small Core" Processors (Atom) */
|
||||||
|
|
||||||
#define INTEL_FAM6_ATOM_BONNELL 0x1C /* Diamondville, Pineview */
|
#define INTEL_FAM6_ATOM_BONNELL 0x1C /* Diamondville, Pineview */
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <linux/mlx5/vport.h>
|
#include <linux/mlx5/vport.h>
|
||||||
#include "lib/devcom.h"
|
#include "lib/devcom.h"
|
||||||
|
#include "mlx5_core.h"
|
||||||
|
|
||||||
static LIST_HEAD(devcom_list);
|
static LIST_HEAD(devcom_list);
|
||||||
|
|
||||||
@@ -14,7 +15,7 @@ static LIST_HEAD(devcom_list);
|
|||||||
struct mlx5_devcom_component {
|
struct mlx5_devcom_component {
|
||||||
struct {
|
struct {
|
||||||
void *data;
|
void *data;
|
||||||
} device[MLX5_MAX_PORTS];
|
} device[MLX5_DEVCOM_PORTS_SUPPORTED];
|
||||||
|
|
||||||
mlx5_devcom_event_handler_t handler;
|
mlx5_devcom_event_handler_t handler;
|
||||||
struct rw_semaphore sem;
|
struct rw_semaphore sem;
|
||||||
@@ -25,7 +26,7 @@ struct mlx5_devcom_list {
|
|||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
|
||||||
struct mlx5_devcom_component components[MLX5_DEVCOM_NUM_COMPONENTS];
|
struct mlx5_devcom_component components[MLX5_DEVCOM_NUM_COMPONENTS];
|
||||||
struct mlx5_core_dev *devs[MLX5_MAX_PORTS];
|
struct mlx5_core_dev *devs[MLX5_DEVCOM_PORTS_SUPPORTED];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mlx5_devcom {
|
struct mlx5_devcom {
|
||||||
@@ -74,13 +75,16 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
|
|||||||
|
|
||||||
if (!mlx5_core_is_pf(dev))
|
if (!mlx5_core_is_pf(dev))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_DEVCOM_PORTS_SUPPORTED)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
mlx5_dev_list_lock();
|
||||||
sguid0 = mlx5_query_nic_system_image_guid(dev);
|
sguid0 = mlx5_query_nic_system_image_guid(dev);
|
||||||
list_for_each_entry(iter, &devcom_list, list) {
|
list_for_each_entry(iter, &devcom_list, list) {
|
||||||
struct mlx5_core_dev *tmp_dev = NULL;
|
struct mlx5_core_dev *tmp_dev = NULL;
|
||||||
|
|
||||||
idx = -1;
|
idx = -1;
|
||||||
for (i = 0; i < MLX5_MAX_PORTS; i++) {
|
for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++) {
|
||||||
if (iter->devs[i])
|
if (iter->devs[i])
|
||||||
tmp_dev = iter->devs[i];
|
tmp_dev = iter->devs[i];
|
||||||
else
|
else
|
||||||
@@ -100,8 +104,10 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
|
|||||||
|
|
||||||
if (!priv) {
|
if (!priv) {
|
||||||
priv = mlx5_devcom_list_alloc();
|
priv = mlx5_devcom_list_alloc();
|
||||||
if (!priv)
|
if (!priv) {
|
||||||
return ERR_PTR(-ENOMEM);
|
devcom = ERR_PTR(-ENOMEM);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
new_priv = true;
|
new_priv = true;
|
||||||
@@ -112,12 +118,14 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
|
|||||||
if (!devcom) {
|
if (!devcom) {
|
||||||
if (new_priv)
|
if (new_priv)
|
||||||
kfree(priv);
|
kfree(priv);
|
||||||
return ERR_PTR(-ENOMEM);
|
devcom = ERR_PTR(-ENOMEM);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_priv)
|
if (new_priv)
|
||||||
list_add(&priv->list, &devcom_list);
|
list_add(&priv->list, &devcom_list);
|
||||||
|
out:
|
||||||
|
mlx5_dev_list_unlock();
|
||||||
return devcom;
|
return devcom;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,20 +138,23 @@ void mlx5_devcom_unregister_device(struct mlx5_devcom *devcom)
|
|||||||
if (IS_ERR_OR_NULL(devcom))
|
if (IS_ERR_OR_NULL(devcom))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mlx5_dev_list_lock();
|
||||||
priv = devcom->priv;
|
priv = devcom->priv;
|
||||||
priv->devs[devcom->idx] = NULL;
|
priv->devs[devcom->idx] = NULL;
|
||||||
|
|
||||||
kfree(devcom);
|
kfree(devcom);
|
||||||
|
|
||||||
for (i = 0; i < MLX5_MAX_PORTS; i++)
|
for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
|
||||||
if (priv->devs[i])
|
if (priv->devs[i])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (i != MLX5_MAX_PORTS)
|
if (i != MLX5_DEVCOM_PORTS_SUPPORTED)
|
||||||
return;
|
goto out;
|
||||||
|
|
||||||
list_del(&priv->list);
|
list_del(&priv->list);
|
||||||
kfree(priv);
|
kfree(priv);
|
||||||
|
out:
|
||||||
|
mlx5_dev_list_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mlx5_devcom_register_component(struct mlx5_devcom *devcom,
|
void mlx5_devcom_register_component(struct mlx5_devcom *devcom,
|
||||||
@@ -192,7 +203,7 @@ int mlx5_devcom_send_event(struct mlx5_devcom *devcom,
|
|||||||
|
|
||||||
comp = &devcom->priv->components[id];
|
comp = &devcom->priv->components[id];
|
||||||
down_write(&comp->sem);
|
down_write(&comp->sem);
|
||||||
for (i = 0; i < MLX5_MAX_PORTS; i++)
|
for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
|
||||||
if (i != devcom->idx && comp->device[i].data) {
|
if (i != devcom->idx && comp->device[i].data) {
|
||||||
err = comp->handler(event, comp->device[i].data,
|
err = comp->handler(event, comp->device[i].data,
|
||||||
event_data);
|
event_data);
|
||||||
@@ -240,7 +251,7 @@ void *mlx5_devcom_get_peer_data(struct mlx5_devcom *devcom,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MLX5_MAX_PORTS; i++)
|
for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
|
||||||
if (i != devcom->idx)
|
if (i != devcom->idx)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include <linux/mlx5/driver.h>
|
#include <linux/mlx5/driver.h>
|
||||||
|
|
||||||
|
#define MLX5_DEVCOM_PORTS_SUPPORTED 2
|
||||||
|
|
||||||
enum mlx5_devcom_components {
|
enum mlx5_devcom_components {
|
||||||
MLX5_DEVCOM_ESW_OFFLOADS,
|
MLX5_DEVCOM_ESW_OFFLOADS,
|
||||||
|
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ enum rgmii_clock_delay {
|
|||||||
#define VSC8502_RGMII_CNTL 20
|
#define VSC8502_RGMII_CNTL 20
|
||||||
#define VSC8502_RGMII_RX_DELAY_MASK 0x0070
|
#define VSC8502_RGMII_RX_DELAY_MASK 0x0070
|
||||||
#define VSC8502_RGMII_TX_DELAY_MASK 0x0007
|
#define VSC8502_RGMII_TX_DELAY_MASK 0x0007
|
||||||
|
#define VSC8502_RGMII_RX_CLK_DISABLE 0x0800
|
||||||
|
|
||||||
#define MSCC_PHY_WOL_LOWER_MAC_ADDR 21
|
#define MSCC_PHY_WOL_LOWER_MAC_ADDR 21
|
||||||
#define MSCC_PHY_WOL_MID_MAC_ADDR 22
|
#define MSCC_PHY_WOL_MID_MAC_ADDR 22
|
||||||
|
|||||||
@@ -527,14 +527,27 @@ out_unlock:
|
|||||||
* * 2.0 ns (which causes the data to be sampled at exactly half way between
|
* * 2.0 ns (which causes the data to be sampled at exactly half way between
|
||||||
* clock transitions at 1000 Mbps) if delays should be enabled
|
* clock transitions at 1000 Mbps) if delays should be enabled
|
||||||
*/
|
*/
|
||||||
static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl,
|
static int vsc85xx_update_rgmii_cntl(struct phy_device *phydev, u32 rgmii_cntl,
|
||||||
u16 rgmii_rx_delay_mask,
|
u16 rgmii_rx_delay_mask,
|
||||||
u16 rgmii_tx_delay_mask)
|
u16 rgmii_tx_delay_mask)
|
||||||
{
|
{
|
||||||
u16 rgmii_rx_delay_pos = ffs(rgmii_rx_delay_mask) - 1;
|
u16 rgmii_rx_delay_pos = ffs(rgmii_rx_delay_mask) - 1;
|
||||||
u16 rgmii_tx_delay_pos = ffs(rgmii_tx_delay_mask) - 1;
|
u16 rgmii_tx_delay_pos = ffs(rgmii_tx_delay_mask) - 1;
|
||||||
u16 reg_val = 0;
|
u16 reg_val = 0;
|
||||||
int rc;
|
u16 mask = 0;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
/* For traffic to pass, the VSC8502 family needs the RX_CLK disable bit
|
||||||
|
* to be unset for all PHY modes, so do that as part of the paged
|
||||||
|
* register modification.
|
||||||
|
* For some family members (like VSC8530/31/40/41) this bit is reserved
|
||||||
|
* and read-only, and the RX clock is enabled by default.
|
||||||
|
*/
|
||||||
|
if (rgmii_cntl == VSC8502_RGMII_CNTL)
|
||||||
|
mask |= VSC8502_RGMII_RX_CLK_DISABLE;
|
||||||
|
|
||||||
|
if (phy_interface_is_rgmii(phydev))
|
||||||
|
mask |= rgmii_rx_delay_mask | rgmii_tx_delay_mask;
|
||||||
|
|
||||||
mutex_lock(&phydev->lock);
|
mutex_lock(&phydev->lock);
|
||||||
|
|
||||||
@@ -545,10 +558,9 @@ static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl,
|
|||||||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
|
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
|
||||||
reg_val |= RGMII_CLK_DELAY_2_0_NS << rgmii_tx_delay_pos;
|
reg_val |= RGMII_CLK_DELAY_2_0_NS << rgmii_tx_delay_pos;
|
||||||
|
|
||||||
rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
|
if (mask)
|
||||||
rgmii_cntl,
|
rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
|
||||||
rgmii_rx_delay_mask | rgmii_tx_delay_mask,
|
rgmii_cntl, mask, reg_val);
|
||||||
reg_val);
|
|
||||||
|
|
||||||
mutex_unlock(&phydev->lock);
|
mutex_unlock(&phydev->lock);
|
||||||
|
|
||||||
@@ -557,19 +569,11 @@ static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl,
|
|||||||
|
|
||||||
static int vsc85xx_default_config(struct phy_device *phydev)
|
static int vsc85xx_default_config(struct phy_device *phydev)
|
||||||
{
|
{
|
||||||
int rc;
|
|
||||||
|
|
||||||
phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
|
phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
|
||||||
|
|
||||||
if (phy_interface_mode_is_rgmii(phydev->interface)) {
|
return vsc85xx_update_rgmii_cntl(phydev, VSC8502_RGMII_CNTL,
|
||||||
rc = vsc85xx_rgmii_set_skews(phydev, VSC8502_RGMII_CNTL,
|
VSC8502_RGMII_RX_DELAY_MASK,
|
||||||
VSC8502_RGMII_RX_DELAY_MASK,
|
VSC8502_RGMII_TX_DELAY_MASK);
|
||||||
VSC8502_RGMII_TX_DELAY_MASK);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vsc85xx_get_tunable(struct phy_device *phydev,
|
static int vsc85xx_get_tunable(struct phy_device *phydev,
|
||||||
@@ -1646,13 +1650,11 @@ static int vsc8584_config_init(struct phy_device *phydev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (phy_interface_is_rgmii(phydev)) {
|
ret = vsc85xx_update_rgmii_cntl(phydev, VSC8572_RGMII_CNTL,
|
||||||
ret = vsc85xx_rgmii_set_skews(phydev, VSC8572_RGMII_CNTL,
|
VSC8572_RGMII_RX_DELAY_MASK,
|
||||||
VSC8572_RGMII_RX_DELAY_MASK,
|
VSC8572_RGMII_TX_DELAY_MASK);
|
||||||
VSC8572_RGMII_TX_DELAY_MASK);
|
if (ret)
|
||||||
if (ret)
|
return ret;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = genphy_soft_reset(phydev);
|
ret = genphy_soft_reset(phydev);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|||||||
@@ -1203,8 +1203,19 @@ static void bq24190_input_current_limit_work(struct work_struct *work)
|
|||||||
struct bq24190_dev_info *bdi =
|
struct bq24190_dev_info *bdi =
|
||||||
container_of(work, struct bq24190_dev_info,
|
container_of(work, struct bq24190_dev_info,
|
||||||
input_current_limit_work.work);
|
input_current_limit_work.work);
|
||||||
|
union power_supply_propval val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
power_supply_set_input_current_limit_from_supplier(bdi->charger);
|
ret = power_supply_get_property_from_supplier(bdi->charger,
|
||||||
|
POWER_SUPPLY_PROP_CURRENT_MAX,
|
||||||
|
&val);
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bq24190_charger_set_property(bdi->charger,
|
||||||
|
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||||
|
&val);
|
||||||
|
power_supply_changed(bdi->charger);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sync the input-current-limit with our parent supply (if we have one) */
|
/* Sync the input-current-limit with our parent supply (if we have one) */
|
||||||
|
|||||||
@@ -1507,14 +1507,6 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
|
|||||||
*/
|
*/
|
||||||
static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
|
static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
|
||||||
{
|
{
|
||||||
int flags;
|
|
||||||
|
|
||||||
if (di->opts & BQ27XXX_O_ZERO) {
|
|
||||||
flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
|
|
||||||
if (flags >= 0 && (flags & BQ27000_FLAG_CI))
|
|
||||||
return -ENODATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC);
|
return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1668,6 +1660,18 @@ static bool bq27xxx_battery_dead(struct bq27xxx_device_info *di, u16 flags)
|
|||||||
return flags & (BQ27XXX_FLAG_SOC1 | BQ27XXX_FLAG_SOCF);
|
return flags & (BQ27XXX_FLAG_SOC1 | BQ27XXX_FLAG_SOCF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if reported battery capacity is inaccurate
|
||||||
|
*/
|
||||||
|
static bool bq27xxx_battery_capacity_inaccurate(struct bq27xxx_device_info *di,
|
||||||
|
u16 flags)
|
||||||
|
{
|
||||||
|
if (di->opts & BQ27XXX_O_HAS_CI)
|
||||||
|
return (flags & BQ27000_FLAG_CI);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
|
static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
|
||||||
{
|
{
|
||||||
/* Unlikely but important to return first */
|
/* Unlikely but important to return first */
|
||||||
@@ -1677,14 +1681,89 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
|
|||||||
return POWER_SUPPLY_HEALTH_COLD;
|
return POWER_SUPPLY_HEALTH_COLD;
|
||||||
if (unlikely(bq27xxx_battery_dead(di, di->cache.flags)))
|
if (unlikely(bq27xxx_battery_dead(di, di->cache.flags)))
|
||||||
return POWER_SUPPLY_HEALTH_DEAD;
|
return POWER_SUPPLY_HEALTH_DEAD;
|
||||||
|
if (unlikely(bq27xxx_battery_capacity_inaccurate(di, di->cache.flags)))
|
||||||
|
return POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED;
|
||||||
|
|
||||||
return POWER_SUPPLY_HEALTH_GOOD;
|
return POWER_SUPPLY_HEALTH_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool bq27xxx_battery_is_full(struct bq27xxx_device_info *di, int flags)
|
||||||
|
{
|
||||||
|
if (di->opts & BQ27XXX_O_ZERO)
|
||||||
|
return (flags & BQ27000_FLAG_FC);
|
||||||
|
else if (di->opts & BQ27Z561_O_BITS)
|
||||||
|
return (flags & BQ27Z561_FLAG_FC);
|
||||||
|
else
|
||||||
|
return (flags & BQ27XXX_FLAG_FC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the battery average current in µA and the status
|
||||||
|
* Note that current can be negative signed as well
|
||||||
|
* Or 0 if something fails.
|
||||||
|
*/
|
||||||
|
static int bq27xxx_battery_current_and_status(
|
||||||
|
struct bq27xxx_device_info *di,
|
||||||
|
union power_supply_propval *val_curr,
|
||||||
|
union power_supply_propval *val_status,
|
||||||
|
struct bq27xxx_reg_cache *cache)
|
||||||
|
{
|
||||||
|
bool single_flags = (di->opts & BQ27XXX_O_ZERO);
|
||||||
|
int curr;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
|
||||||
|
if (curr < 0) {
|
||||||
|
dev_err(di->dev, "error reading current\n");
|
||||||
|
return curr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache) {
|
||||||
|
flags = cache->flags;
|
||||||
|
} else {
|
||||||
|
flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, single_flags);
|
||||||
|
if (flags < 0) {
|
||||||
|
dev_err(di->dev, "error reading flags\n");
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (di->opts & BQ27XXX_O_ZERO) {
|
||||||
|
if (!(flags & BQ27000_FLAG_CHGS)) {
|
||||||
|
dev_dbg(di->dev, "negative current!\n");
|
||||||
|
curr = -curr;
|
||||||
|
}
|
||||||
|
|
||||||
|
curr = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
|
||||||
|
} else {
|
||||||
|
/* Other gauges return signed value */
|
||||||
|
curr = (int)((s16)curr) * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val_curr)
|
||||||
|
val_curr->intval = curr;
|
||||||
|
|
||||||
|
if (val_status) {
|
||||||
|
if (curr > 0) {
|
||||||
|
val_status->intval = POWER_SUPPLY_STATUS_CHARGING;
|
||||||
|
} else if (curr < 0) {
|
||||||
|
val_status->intval = POWER_SUPPLY_STATUS_DISCHARGING;
|
||||||
|
} else {
|
||||||
|
if (bq27xxx_battery_is_full(di, flags))
|
||||||
|
val_status->intval = POWER_SUPPLY_STATUS_FULL;
|
||||||
|
else
|
||||||
|
val_status->intval =
|
||||||
|
POWER_SUPPLY_STATUS_NOT_CHARGING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
|
static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
|
||||||
{
|
{
|
||||||
|
union power_supply_propval status = di->last_status;
|
||||||
struct bq27xxx_reg_cache cache = {0, };
|
struct bq27xxx_reg_cache cache = {0, };
|
||||||
bool has_ci_flag = di->opts & BQ27XXX_O_HAS_CI;
|
|
||||||
bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
|
bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
|
||||||
|
|
||||||
cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
|
cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
|
||||||
@@ -1692,41 +1771,40 @@ static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
|
|||||||
cache.flags = -1; /* read error */
|
cache.flags = -1; /* read error */
|
||||||
if (cache.flags >= 0) {
|
if (cache.flags >= 0) {
|
||||||
cache.temperature = bq27xxx_battery_read_temperature(di);
|
cache.temperature = bq27xxx_battery_read_temperature(di);
|
||||||
if (has_ci_flag && (cache.flags & BQ27000_FLAG_CI)) {
|
if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
|
||||||
dev_info_once(di->dev, "battery is not calibrated! ignoring capacity values\n");
|
cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
|
||||||
cache.capacity = -ENODATA;
|
if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
|
||||||
cache.energy = -ENODATA;
|
cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
|
||||||
cache.time_to_empty = -ENODATA;
|
if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
|
||||||
cache.time_to_empty_avg = -ENODATA;
|
cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
|
||||||
cache.time_to_full = -ENODATA;
|
|
||||||
cache.charge_full = -ENODATA;
|
|
||||||
cache.health = -ENODATA;
|
|
||||||
} else {
|
|
||||||
if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
|
|
||||||
cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
|
|
||||||
if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
|
|
||||||
cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
|
|
||||||
if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
|
|
||||||
cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
|
|
||||||
|
|
||||||
cache.charge_full = bq27xxx_battery_read_fcc(di);
|
cache.charge_full = bq27xxx_battery_read_fcc(di);
|
||||||
cache.capacity = bq27xxx_battery_read_soc(di);
|
cache.capacity = bq27xxx_battery_read_soc(di);
|
||||||
if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
|
if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
|
||||||
cache.energy = bq27xxx_battery_read_energy(di);
|
cache.energy = bq27xxx_battery_read_energy(di);
|
||||||
di->cache.flags = cache.flags;
|
di->cache.flags = cache.flags;
|
||||||
cache.health = bq27xxx_battery_read_health(di);
|
cache.health = bq27xxx_battery_read_health(di);
|
||||||
}
|
|
||||||
if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
|
if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
|
||||||
cache.cycle_count = bq27xxx_battery_read_cyct(di);
|
cache.cycle_count = bq27xxx_battery_read_cyct(di);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On gauges with signed current reporting the current must be
|
||||||
|
* checked to detect charging <-> discharging status changes.
|
||||||
|
*/
|
||||||
|
if (!(di->opts & BQ27XXX_O_ZERO))
|
||||||
|
bq27xxx_battery_current_and_status(di, NULL, &status, &cache);
|
||||||
|
|
||||||
/* We only have to read charge design full once */
|
/* We only have to read charge design full once */
|
||||||
if (di->charge_design_full <= 0)
|
if (di->charge_design_full <= 0)
|
||||||
di->charge_design_full = bq27xxx_battery_read_dcap(di);
|
di->charge_design_full = bq27xxx_battery_read_dcap(di);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((di->cache.capacity != cache.capacity) ||
|
if ((di->cache.capacity != cache.capacity) ||
|
||||||
(di->cache.flags != cache.flags))
|
(di->cache.flags != cache.flags) ||
|
||||||
|
(di->last_status.intval != status.intval)) {
|
||||||
|
di->last_status.intval = status.intval;
|
||||||
power_supply_changed(di->bat);
|
power_supply_changed(di->bat);
|
||||||
|
}
|
||||||
|
|
||||||
if (memcmp(&di->cache, &cache, sizeof(cache)) != 0)
|
if (memcmp(&di->cache, &cache, sizeof(cache)) != 0)
|
||||||
di->cache = cache;
|
di->cache = cache;
|
||||||
@@ -1754,39 +1832,6 @@ static void bq27xxx_battery_poll(struct work_struct *work)
|
|||||||
bq27xxx_battery_update(di);
|
bq27xxx_battery_update(di);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the battery average current in µA
|
|
||||||
* Note that current can be negative signed as well
|
|
||||||
* Or 0 if something fails.
|
|
||||||
*/
|
|
||||||
static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
|
|
||||||
union power_supply_propval *val)
|
|
||||||
{
|
|
||||||
int curr;
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
|
|
||||||
if (curr < 0) {
|
|
||||||
dev_err(di->dev, "error reading current\n");
|
|
||||||
return curr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (di->opts & BQ27XXX_O_ZERO) {
|
|
||||||
flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
|
|
||||||
if (flags & BQ27000_FLAG_CHGS) {
|
|
||||||
dev_dbg(di->dev, "negative current!\n");
|
|
||||||
curr = -curr;
|
|
||||||
}
|
|
||||||
|
|
||||||
val->intval = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
|
|
||||||
} else {
|
|
||||||
/* Other gauges return signed value */
|
|
||||||
val->intval = (int)((s16)curr) * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the average power in µW
|
* Get the average power in µW
|
||||||
* Return < 0 if something fails.
|
* Return < 0 if something fails.
|
||||||
@@ -1813,43 +1858,6 @@ static int bq27xxx_battery_pwr_avg(struct bq27xxx_device_info *di,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
|
|
||||||
union power_supply_propval *val)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
if (di->opts & BQ27XXX_O_ZERO) {
|
|
||||||
if (di->cache.flags & BQ27000_FLAG_FC)
|
|
||||||
status = POWER_SUPPLY_STATUS_FULL;
|
|
||||||
else if (di->cache.flags & BQ27000_FLAG_CHGS)
|
|
||||||
status = POWER_SUPPLY_STATUS_CHARGING;
|
|
||||||
else
|
|
||||||
status = POWER_SUPPLY_STATUS_DISCHARGING;
|
|
||||||
} else if (di->opts & BQ27Z561_O_BITS) {
|
|
||||||
if (di->cache.flags & BQ27Z561_FLAG_FC)
|
|
||||||
status = POWER_SUPPLY_STATUS_FULL;
|
|
||||||
else if (di->cache.flags & BQ27Z561_FLAG_DIS_CH)
|
|
||||||
status = POWER_SUPPLY_STATUS_DISCHARGING;
|
|
||||||
else
|
|
||||||
status = POWER_SUPPLY_STATUS_CHARGING;
|
|
||||||
} else {
|
|
||||||
if (di->cache.flags & BQ27XXX_FLAG_FC)
|
|
||||||
status = POWER_SUPPLY_STATUS_FULL;
|
|
||||||
else if (di->cache.flags & BQ27XXX_FLAG_DSC)
|
|
||||||
status = POWER_SUPPLY_STATUS_DISCHARGING;
|
|
||||||
else
|
|
||||||
status = POWER_SUPPLY_STATUS_CHARGING;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((status == POWER_SUPPLY_STATUS_DISCHARGING) &&
|
|
||||||
(power_supply_am_i_supplied(di->bat) > 0))
|
|
||||||
status = POWER_SUPPLY_STATUS_NOT_CHARGING;
|
|
||||||
|
|
||||||
val->intval = status;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
|
static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
|
||||||
union power_supply_propval *val)
|
union power_supply_propval *val)
|
||||||
{
|
{
|
||||||
@@ -1935,7 +1943,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
|
|||||||
|
|
||||||
switch (psp) {
|
switch (psp) {
|
||||||
case POWER_SUPPLY_PROP_STATUS:
|
case POWER_SUPPLY_PROP_STATUS:
|
||||||
ret = bq27xxx_battery_status(di, val);
|
ret = bq27xxx_battery_current_and_status(di, NULL, val, NULL);
|
||||||
break;
|
break;
|
||||||
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
|
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
|
||||||
ret = bq27xxx_battery_voltage(di, val);
|
ret = bq27xxx_battery_voltage(di, val);
|
||||||
@@ -1944,7 +1952,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
|
|||||||
val->intval = di->cache.flags < 0 ? 0 : 1;
|
val->intval = di->cache.flags < 0 ? 0 : 1;
|
||||||
break;
|
break;
|
||||||
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
||||||
ret = bq27xxx_battery_current(di, val);
|
ret = bq27xxx_battery_current_and_status(di, val, NULL, NULL);
|
||||||
break;
|
break;
|
||||||
case POWER_SUPPLY_PROP_CAPACITY:
|
case POWER_SUPPLY_PROP_CAPACITY:
|
||||||
ret = bq27xxx_simple_value(di->cache.capacity, val);
|
ret = bq27xxx_simple_value(di->cache.capacity, val);
|
||||||
@@ -2014,8 +2022,8 @@ static void bq27xxx_external_power_changed(struct power_supply *psy)
|
|||||||
{
|
{
|
||||||
struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
|
struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
|
||||||
|
|
||||||
cancel_delayed_work_sync(&di->work);
|
/* After charger plug in/out wait 0.5s for things to stabilize */
|
||||||
schedule_delayed_work(&di->work, 0);
|
mod_delayed_work(system_wq, &di->work, HZ / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
|
int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
|
||||||
|
|||||||
@@ -386,46 +386,49 @@ int power_supply_is_system_supplied(void)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(power_supply_is_system_supplied);
|
EXPORT_SYMBOL_GPL(power_supply_is_system_supplied);
|
||||||
|
|
||||||
static int __power_supply_get_supplier_max_current(struct device *dev,
|
struct psy_get_supplier_prop_data {
|
||||||
void *data)
|
struct power_supply *psy;
|
||||||
|
enum power_supply_property psp;
|
||||||
|
union power_supply_propval *val;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __power_supply_get_supplier_property(struct device *dev, void *_data)
|
||||||
{
|
{
|
||||||
union power_supply_propval ret = {0,};
|
|
||||||
struct power_supply *epsy = dev_get_drvdata(dev);
|
struct power_supply *epsy = dev_get_drvdata(dev);
|
||||||
struct power_supply *psy = data;
|
struct psy_get_supplier_prop_data *data = _data;
|
||||||
|
|
||||||
if (__power_supply_is_supplied_by(epsy, psy))
|
if (__power_supply_is_supplied_by(epsy, data->psy))
|
||||||
if (!epsy->desc->get_property(epsy,
|
if (!epsy->desc->get_property(epsy, data->psp, data->val))
|
||||||
POWER_SUPPLY_PROP_CURRENT_MAX,
|
return 1; /* Success */
|
||||||
&ret))
|
|
||||||
return ret.intval;
|
|
||||||
|
|
||||||
return 0;
|
return 0; /* Continue iterating */
|
||||||
}
|
}
|
||||||
|
|
||||||
int power_supply_set_input_current_limit_from_supplier(struct power_supply *psy)
|
int power_supply_get_property_from_supplier(struct power_supply *psy,
|
||||||
|
enum power_supply_property psp,
|
||||||
|
union power_supply_propval *val)
|
||||||
{
|
{
|
||||||
union power_supply_propval val = {0,};
|
struct psy_get_supplier_prop_data data = {
|
||||||
int curr;
|
.psy = psy,
|
||||||
|
.psp = psp,
|
||||||
if (!psy->desc->set_property)
|
.val = val,
|
||||||
return -EINVAL;
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is not intended for use with a supply with multiple
|
* This function is not intended for use with a supply with multiple
|
||||||
* suppliers, we simply pick the first supply to report a non 0
|
* suppliers, we simply pick the first supply to report the psp.
|
||||||
* max-current.
|
|
||||||
*/
|
*/
|
||||||
curr = class_for_each_device(power_supply_class, NULL, psy,
|
ret = class_for_each_device(power_supply_class, NULL, &data,
|
||||||
__power_supply_get_supplier_max_current);
|
__power_supply_get_supplier_property);
|
||||||
if (curr <= 0)
|
if (ret < 0)
|
||||||
return (curr == 0) ? -ENODEV : curr;
|
return ret;
|
||||||
|
if (ret == 0)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
val.intval = curr;
|
return 0;
|
||||||
|
|
||||||
return psy->desc->set_property(psy,
|
|
||||||
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(power_supply_set_input_current_limit_from_supplier);
|
EXPORT_SYMBOL_GPL(power_supply_get_property_from_supplier);
|
||||||
|
|
||||||
int power_supply_set_battery_charged(struct power_supply *psy)
|
int power_supply_set_battery_charged(struct power_supply *psy)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -879,3 +879,68 @@ bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2)
|
|||||||
return reg1->rdev == reg2->rdev;
|
return reg1->rdev == reg2->rdev;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(regulator_is_equal);
|
EXPORT_SYMBOL_GPL(regulator_is_equal);
|
||||||
|
|
||||||
|
static int find_closest_bigger(unsigned int target, const unsigned int *table,
|
||||||
|
unsigned int num_sel, unsigned int *sel)
|
||||||
|
{
|
||||||
|
unsigned int s, tmp, max, maxsel = 0;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
max = table[0];
|
||||||
|
|
||||||
|
for (s = 0; s < num_sel; s++) {
|
||||||
|
if (table[s] > max) {
|
||||||
|
max = table[s];
|
||||||
|
maxsel = s;
|
||||||
|
}
|
||||||
|
if (table[s] >= target) {
|
||||||
|
if (!found || table[s] - target < tmp - target) {
|
||||||
|
tmp = table[s];
|
||||||
|
*sel = s;
|
||||||
|
found = true;
|
||||||
|
if (tmp == target)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
*sel = maxsel;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* regulator_set_ramp_delay_regmap - set_ramp_delay() helper
|
||||||
|
*
|
||||||
|
* @rdev: regulator to operate on
|
||||||
|
*
|
||||||
|
* Regulators that use regmap for their register I/O can set the ramp_reg
|
||||||
|
* and ramp_mask fields in their descriptor and then use this as their
|
||||||
|
* set_ramp_delay operation, saving some code.
|
||||||
|
*/
|
||||||
|
int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned int sel;
|
||||||
|
|
||||||
|
if (!rdev->desc->n_ramp_values)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
|
||||||
|
rdev->desc->n_ramp_values, &sel);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
dev_warn(rdev_get_dev(rdev),
|
||||||
|
"Can't set ramp-delay %u, setting %u\n", ramp_delay,
|
||||||
|
rdev->desc->ramp_delay_table[sel]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sel <<= ffs(rdev->desc->ramp_mask) - 1;
|
||||||
|
|
||||||
|
return regmap_update_bits(rdev->regmap, rdev->desc->ramp_reg,
|
||||||
|
rdev->desc->ramp_mask, sel);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(regulator_set_ramp_delay_regmap);
|
||||||
|
|||||||
@@ -65,32 +65,9 @@ static const struct regmap_config pca9450_regmap_config = {
|
|||||||
* 10: 25mV/4usec
|
* 10: 25mV/4usec
|
||||||
* 11: 25mV/8usec
|
* 11: 25mV/8usec
|
||||||
*/
|
*/
|
||||||
static int pca9450_dvs_set_ramp_delay(struct regulator_dev *rdev,
|
static const unsigned int pca9450_dvs_buck_ramp_table[] = {
|
||||||
int ramp_delay)
|
25000, 12500, 6250, 3125
|
||||||
{
|
};
|
||||||
int id = rdev_get_id(rdev);
|
|
||||||
unsigned int ramp_value;
|
|
||||||
|
|
||||||
switch (ramp_delay) {
|
|
||||||
case 1 ... 3125:
|
|
||||||
ramp_value = BUCK1_RAMP_3P125MV;
|
|
||||||
break;
|
|
||||||
case 3126 ... 6250:
|
|
||||||
ramp_value = BUCK1_RAMP_6P25MV;
|
|
||||||
break;
|
|
||||||
case 6251 ... 12500:
|
|
||||||
ramp_value = BUCK1_RAMP_12P5MV;
|
|
||||||
break;
|
|
||||||
case 12501 ... 25000:
|
|
||||||
ramp_value = BUCK1_RAMP_25MV;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ramp_value = BUCK1_RAMP_25MV;
|
|
||||||
}
|
|
||||||
|
|
||||||
return regmap_update_bits(rdev->regmap, PCA9450_REG_BUCK1CTRL + id * 3,
|
|
||||||
BUCK1_RAMP_MASK, ramp_value << 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
|
static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
|
||||||
.enable = regulator_enable_regmap,
|
.enable = regulator_enable_regmap,
|
||||||
@@ -100,7 +77,7 @@ static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
|
|||||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||||
.set_ramp_delay = pca9450_dvs_set_ramp_delay,
|
.set_ramp_delay = regulator_set_ramp_delay_regmap,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct regulator_ops pca9450_buck_regulator_ops = {
|
static const struct regulator_ops pca9450_buck_regulator_ops = {
|
||||||
@@ -251,6 +228,10 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
|
|||||||
.vsel_mask = BUCK1OUT_DVS0_MASK,
|
.vsel_mask = BUCK1OUT_DVS0_MASK,
|
||||||
.enable_reg = PCA9450_REG_BUCK1CTRL,
|
.enable_reg = PCA9450_REG_BUCK1CTRL,
|
||||||
.enable_mask = BUCK1_ENMODE_MASK,
|
.enable_mask = BUCK1_ENMODE_MASK,
|
||||||
|
.ramp_reg = PCA9450_REG_BUCK1CTRL,
|
||||||
|
.ramp_mask = BUCK1_RAMP_MASK,
|
||||||
|
.ramp_delay_table = pca9450_dvs_buck_ramp_table,
|
||||||
|
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_parse_cb = pca9450_set_dvs_levels,
|
.of_parse_cb = pca9450_set_dvs_levels,
|
||||||
},
|
},
|
||||||
@@ -275,7 +256,11 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
|
|||||||
.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
|
.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
|
||||||
.vsel_mask = BUCK2OUT_DVS0_MASK,
|
.vsel_mask = BUCK2OUT_DVS0_MASK,
|
||||||
.enable_reg = PCA9450_REG_BUCK2CTRL,
|
.enable_reg = PCA9450_REG_BUCK2CTRL,
|
||||||
.enable_mask = BUCK1_ENMODE_MASK,
|
.enable_mask = BUCK2_ENMODE_MASK,
|
||||||
|
.ramp_reg = PCA9450_REG_BUCK2CTRL,
|
||||||
|
.ramp_mask = BUCK2_RAMP_MASK,
|
||||||
|
.ramp_delay_table = pca9450_dvs_buck_ramp_table,
|
||||||
|
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_parse_cb = pca9450_set_dvs_levels,
|
.of_parse_cb = pca9450_set_dvs_levels,
|
||||||
},
|
},
|
||||||
@@ -301,6 +286,10 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
|
|||||||
.vsel_mask = BUCK3OUT_DVS0_MASK,
|
.vsel_mask = BUCK3OUT_DVS0_MASK,
|
||||||
.enable_reg = PCA9450_REG_BUCK3CTRL,
|
.enable_reg = PCA9450_REG_BUCK3CTRL,
|
||||||
.enable_mask = BUCK3_ENMODE_MASK,
|
.enable_mask = BUCK3_ENMODE_MASK,
|
||||||
|
.ramp_reg = PCA9450_REG_BUCK3CTRL,
|
||||||
|
.ramp_mask = BUCK3_RAMP_MASK,
|
||||||
|
.ramp_delay_table = pca9450_dvs_buck_ramp_table,
|
||||||
|
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_parse_cb = pca9450_set_dvs_levels,
|
.of_parse_cb = pca9450_set_dvs_levels,
|
||||||
},
|
},
|
||||||
@@ -477,6 +466,10 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
|
|||||||
.vsel_mask = BUCK1OUT_DVS0_MASK,
|
.vsel_mask = BUCK1OUT_DVS0_MASK,
|
||||||
.enable_reg = PCA9450_REG_BUCK1CTRL,
|
.enable_reg = PCA9450_REG_BUCK1CTRL,
|
||||||
.enable_mask = BUCK1_ENMODE_MASK,
|
.enable_mask = BUCK1_ENMODE_MASK,
|
||||||
|
.ramp_reg = PCA9450_REG_BUCK1CTRL,
|
||||||
|
.ramp_mask = BUCK1_RAMP_MASK,
|
||||||
|
.ramp_delay_table = pca9450_dvs_buck_ramp_table,
|
||||||
|
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_parse_cb = pca9450_set_dvs_levels,
|
.of_parse_cb = pca9450_set_dvs_levels,
|
||||||
},
|
},
|
||||||
@@ -501,7 +494,11 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
|
|||||||
.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
|
.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
|
||||||
.vsel_mask = BUCK2OUT_DVS0_MASK,
|
.vsel_mask = BUCK2OUT_DVS0_MASK,
|
||||||
.enable_reg = PCA9450_REG_BUCK2CTRL,
|
.enable_reg = PCA9450_REG_BUCK2CTRL,
|
||||||
.enable_mask = BUCK1_ENMODE_MASK,
|
.enable_mask = BUCK2_ENMODE_MASK,
|
||||||
|
.ramp_reg = PCA9450_REG_BUCK2CTRL,
|
||||||
|
.ramp_mask = BUCK2_RAMP_MASK,
|
||||||
|
.ramp_delay_table = pca9450_dvs_buck_ramp_table,
|
||||||
|
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_parse_cb = pca9450_set_dvs_levels,
|
.of_parse_cb = pca9450_set_dvs_levels,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
#ifndef __LINUX_BQ27X00_BATTERY_H__
|
#ifndef __LINUX_BQ27X00_BATTERY_H__
|
||||||
#define __LINUX_BQ27X00_BATTERY_H__
|
#define __LINUX_BQ27X00_BATTERY_H__
|
||||||
|
|
||||||
|
#include <linux/power_supply.h>
|
||||||
|
|
||||||
enum bq27xxx_chip {
|
enum bq27xxx_chip {
|
||||||
BQ27000 = 1, /* bq27000, bq27200 */
|
BQ27000 = 1, /* bq27000, bq27200 */
|
||||||
BQ27010, /* bq27010, bq27210 */
|
BQ27010, /* bq27010, bq27210 */
|
||||||
@@ -69,6 +71,7 @@ struct bq27xxx_device_info {
|
|||||||
int charge_design_full;
|
int charge_design_full;
|
||||||
bool removed;
|
bool removed;
|
||||||
unsigned long last_update;
|
unsigned long last_update;
|
||||||
|
union power_supply_propval last_status;
|
||||||
struct delayed_work work;
|
struct delayed_work work;
|
||||||
struct power_supply *bat;
|
struct power_supply *bat;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
|||||||
@@ -438,8 +438,9 @@ power_supply_temp2resist_simple(struct power_supply_resistance_temp_table *table
|
|||||||
int table_len, int temp);
|
int table_len, int temp);
|
||||||
extern void power_supply_changed(struct power_supply *psy);
|
extern void power_supply_changed(struct power_supply *psy);
|
||||||
extern int power_supply_am_i_supplied(struct power_supply *psy);
|
extern int power_supply_am_i_supplied(struct power_supply *psy);
|
||||||
extern int power_supply_set_input_current_limit_from_supplier(
|
int power_supply_get_property_from_supplier(struct power_supply *psy,
|
||||||
struct power_supply *psy);
|
enum power_supply_property psp,
|
||||||
|
union power_supply_propval *val);
|
||||||
extern int power_supply_set_battery_charged(struct power_supply *psy);
|
extern int power_supply_set_battery_charged(struct power_supply *psy);
|
||||||
|
|
||||||
#ifdef CONFIG_POWER_SUPPLY
|
#ifdef CONFIG_POWER_SUPPLY
|
||||||
|
|||||||
@@ -376,6 +376,10 @@ struct regulator_desc {
|
|||||||
unsigned int pull_down_reg;
|
unsigned int pull_down_reg;
|
||||||
unsigned int pull_down_mask;
|
unsigned int pull_down_mask;
|
||||||
unsigned int pull_down_val_on;
|
unsigned int pull_down_val_on;
|
||||||
|
unsigned int ramp_reg;
|
||||||
|
unsigned int ramp_mask;
|
||||||
|
const unsigned int *ramp_delay_table;
|
||||||
|
unsigned int n_ramp_values;
|
||||||
|
|
||||||
unsigned int enable_time;
|
unsigned int enable_time;
|
||||||
|
|
||||||
@@ -542,6 +546,7 @@ int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
|
|||||||
int min_uA, int max_uA);
|
int min_uA, int max_uA);
|
||||||
int regulator_get_current_limit_regmap(struct regulator_dev *rdev);
|
int regulator_get_current_limit_regmap(struct regulator_dev *rdev);
|
||||||
void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
|
void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
|
||||||
|
int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper functions intended to be used by regulator drivers prior registering
|
* Helper functions intended to be used by regulator drivers prior registering
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ struct ipcm_cookie {
|
|||||||
__be32 addr;
|
__be32 addr;
|
||||||
int oif;
|
int oif;
|
||||||
struct ip_options_rcu *opt;
|
struct ip_options_rcu *opt;
|
||||||
|
__u8 protocol;
|
||||||
__u8 ttl;
|
__u8 ttl;
|
||||||
__s16 tos;
|
__s16 tos;
|
||||||
char priority;
|
char priority;
|
||||||
@@ -96,6 +97,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm,
|
|||||||
ipcm->sockc.tsflags = inet->sk.sk_tsflags;
|
ipcm->sockc.tsflags = inet->sk.sk_tsflags;
|
||||||
ipcm->oif = inet->sk.sk_bound_dev_if;
|
ipcm->oif = inet->sk.sk_bound_dev_if;
|
||||||
ipcm->addr = inet->inet_saddr;
|
ipcm->addr = inet->inet_saddr;
|
||||||
|
ipcm->protocol = inet->inet_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
|
#define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
|
||||||
|
|||||||
@@ -159,6 +159,8 @@ struct in_addr {
|
|||||||
#define MCAST_MSFILTER 48
|
#define MCAST_MSFILTER 48
|
||||||
#define IP_MULTICAST_ALL 49
|
#define IP_MULTICAST_ALL 49
|
||||||
#define IP_UNICAST_IF 50
|
#define IP_UNICAST_IF 50
|
||||||
|
#define IP_LOCAL_PORT_RANGE 51
|
||||||
|
#define IP_PROTOCOL 52
|
||||||
|
|
||||||
#define MCAST_EXCLUDE 0
|
#define MCAST_EXCLUDE 0
|
||||||
#define MCAST_INCLUDE 1
|
#define MCAST_INCLUDE 1
|
||||||
|
|||||||
@@ -980,6 +980,34 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
|
|||||||
|
|
||||||
BT_DBG("cmd %x arg %lx", cmd, arg);
|
BT_DBG("cmd %x arg %lx", cmd, arg);
|
||||||
|
|
||||||
|
/* Make sure the cmd is valid before doing anything */
|
||||||
|
switch (cmd) {
|
||||||
|
case HCIGETDEVLIST:
|
||||||
|
case HCIGETDEVINFO:
|
||||||
|
case HCIGETCONNLIST:
|
||||||
|
case HCIDEVUP:
|
||||||
|
case HCIDEVDOWN:
|
||||||
|
case HCIDEVRESET:
|
||||||
|
case HCIDEVRESTAT:
|
||||||
|
case HCISETSCAN:
|
||||||
|
case HCISETAUTH:
|
||||||
|
case HCISETENCRYPT:
|
||||||
|
case HCISETPTYPE:
|
||||||
|
case HCISETLINKPOL:
|
||||||
|
case HCISETLINKMODE:
|
||||||
|
case HCISETACLMTU:
|
||||||
|
case HCISETSCOMTU:
|
||||||
|
case HCIINQUIRY:
|
||||||
|
case HCISETRAW:
|
||||||
|
case HCIGETCONNINFO:
|
||||||
|
case HCIGETAUTHINFO:
|
||||||
|
case HCIBLOCKADDR:
|
||||||
|
case HCIUNBLOCKADDR:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOIOCTLCMD;
|
||||||
|
}
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
|
||||||
if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
|
if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
|
||||||
|
|||||||
@@ -317,7 +317,14 @@ int ip_cmsg_send(struct sock *sk, struct msghdr *msg, struct ipcm_cookie *ipc,
|
|||||||
ipc->tos = val;
|
ipc->tos = val;
|
||||||
ipc->priority = rt_tos2priority(ipc->tos);
|
ipc->priority = rt_tos2priority(ipc->tos);
|
||||||
break;
|
break;
|
||||||
|
case IP_PROTOCOL:
|
||||||
|
if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
|
||||||
|
return -EINVAL;
|
||||||
|
val = *(int *)CMSG_DATA(cmsg);
|
||||||
|
if (val < 1 || val > 255)
|
||||||
|
return -EINVAL;
|
||||||
|
ipc->protocol = val;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -1724,6 +1731,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
|||||||
case IP_MINTTL:
|
case IP_MINTTL:
|
||||||
val = inet->min_ttl;
|
val = inet->min_ttl;
|
||||||
break;
|
break;
|
||||||
|
case IP_PROTOCOL:
|
||||||
|
val = inet_sk(sk)->inet_num;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
return -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
|
|||||||
@@ -559,6 +559,9 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ipcm_init_sk(&ipc, inet);
|
ipcm_init_sk(&ipc, inet);
|
||||||
|
/* Keep backward compat */
|
||||||
|
if (hdrincl)
|
||||||
|
ipc.protocol = IPPROTO_RAW;
|
||||||
|
|
||||||
if (msg->msg_controllen) {
|
if (msg->msg_controllen) {
|
||||||
err = ip_cmsg_send(sk, msg, &ipc, false);
|
err = ip_cmsg_send(sk, msg, &ipc, false);
|
||||||
@@ -626,7 +629,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||||||
|
|
||||||
flowi4_init_output(&fl4, ipc.oif, ipc.sockc.mark, tos,
|
flowi4_init_output(&fl4, ipc.oif, ipc.sockc.mark, tos,
|
||||||
RT_SCOPE_UNIVERSE,
|
RT_SCOPE_UNIVERSE,
|
||||||
hdrincl ? IPPROTO_RAW : sk->sk_protocol,
|
hdrincl ? ipc.protocol : sk->sk_protocol,
|
||||||
inet_sk_flowi_flags(sk) |
|
inet_sk_flowi_flags(sk) |
|
||||||
(hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
|
(hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
|
||||||
daddr, saddr, 0, 0, sk->sk_uid);
|
daddr, saddr, 0, 0, sk->sk_uid);
|
||||||
|
|||||||
@@ -828,7 +828,8 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||||||
|
|
||||||
if (!proto)
|
if (!proto)
|
||||||
proto = inet->inet_num;
|
proto = inet->inet_num;
|
||||||
else if (proto != inet->inet_num)
|
else if (proto != inet->inet_num &&
|
||||||
|
inet->inet_num != IPPROTO_RAW)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (proto > 255)
|
if (proto > 255)
|
||||||
|
|||||||
@@ -1493,9 +1493,6 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
|
|||||||
|
|
||||||
static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data)
|
static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data)
|
||||||
{
|
{
|
||||||
if (test_bit(IPS_OFFLOAD_BIT, &ct->status))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return ctnetlink_filter_match(ct, data);
|
return ctnetlink_filter_match(ct, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1561,11 +1558,6 @@ static int ctnetlink_del_conntrack(struct net *net, struct sock *ctnl,
|
|||||||
|
|
||||||
ct = nf_ct_tuplehash_to_ctrack(h);
|
ct = nf_ct_tuplehash_to_ctrack(h);
|
||||||
|
|
||||||
if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) {
|
|
||||||
nf_ct_put(ct);
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cda[CTA_ID]) {
|
if (cda[CTA_ID]) {
|
||||||
__be32 id = nla_get_be32(cda[CTA_ID]);
|
__be32 id = nla_get_be32(cda[CTA_ID]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user