From ae07a26163cf0295804e0175fc5c25c86384dc59 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 7 May 2020 13:26:09 +0200 Subject: [PATCH] 4.4-stable patches added patches: net-don-t-delete-routes-in-different-vrfs.patch net-vrf-fix-dst-reference-counting.patch power-bq27xxx-fix-reading-for-bq27000-and-bq27010.patch power-bq27xxx-fix-register-numbers-of-bq27500.patch power-bq27xxx_battery-fix-bq27541-averagepower-register-address.patch power-test_power-correctly-handle-empty-writes.patch power_supply-tps65217-charger-fix-null-deref-during-property-export.patch --- ...on-t-delete-routes-in-different-vrfs.patch | 106 +++++ .../net-vrf-fix-dst-reference-counting.patch | 392 ++++++++++++++++++ ...-fix-reading-for-bq27000-and-bq27010.patch | 85 ++++ ...7xxx-fix-register-numbers-of-bq27500.patch | 39 ++ ...q27541-averagepower-register-address.patch | 36 ++ ..._power-correctly-handle-empty-writes.patch | 32 ++ ...ix-null-deref-during-property-export.patch | 61 +++ queue-4.4/series | 7 + 8 files changed, 758 insertions(+) create mode 100644 queue-4.4/net-don-t-delete-routes-in-different-vrfs.patch create mode 100644 queue-4.4/net-vrf-fix-dst-reference-counting.patch create mode 100644 queue-4.4/power-bq27xxx-fix-reading-for-bq27000-and-bq27010.patch create mode 100644 queue-4.4/power-bq27xxx-fix-register-numbers-of-bq27500.patch create mode 100644 queue-4.4/power-bq27xxx_battery-fix-bq27541-averagepower-register-address.patch create mode 100644 queue-4.4/power-test_power-correctly-handle-empty-writes.patch create mode 100644 queue-4.4/power_supply-tps65217-charger-fix-null-deref-during-property-export.patch diff --git a/queue-4.4/net-don-t-delete-routes-in-different-vrfs.patch b/queue-4.4/net-don-t-delete-routes-in-different-vrfs.patch new file mode 100644 index 00000000000..7eb6ab8e2f8 --- /dev/null +++ b/queue-4.4/net-don-t-delete-routes-in-different-vrfs.patch @@ -0,0 +1,106 @@ +From 5a56a0b3a45dd0cc5b2f7bec6afd053a474ed9f5 Mon Sep 17 00:00:00 2001 +From: Mark Tomlinson +Date: Mon, 5 Sep 2016 10:20:20 +1200 +Subject: net: Don't delete routes in different VRFs + +From: Mark Tomlinson + +commit 5a56a0b3a45dd0cc5b2f7bec6afd053a474ed9f5 upstream. + +When deleting an IP address from an interface, there is a clean-up of +routes which refer to this local address. However, there was no check to +see that the VRF matched. This meant that deletion wasn't confined to +the VRF it should have been. + +To solve this, a new field has been added to fib_info to hold a table +id. When removing fib entries corresponding to a local ip address, this +table id is also used in the comparison. + +The table id is populated when the fib_info is created. This was already +done in some places, but not in ip_rt_ioctl(). This has now been fixed. + +Fixes: 021dd3b8a142 ("net: Add routes to the table associated with the device") +Acked-by: David Ahern +Tested-by: David Ahern +Signed-off-by: Mark Tomlinson +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/ip_fib.h | 3 ++- + net/ipv4/fib_frontend.c | 3 ++- + net/ipv4/fib_semantics.c | 8 ++++++-- + 3 files changed, 10 insertions(+), 4 deletions(-) + +--- a/include/net/ip_fib.h ++++ b/include/net/ip_fib.h +@@ -112,6 +112,7 @@ struct fib_info { + unsigned char fib_scope; + unsigned char fib_type; + __be32 fib_prefsrc; ++ u32 fib_tb_id; + u32 fib_priority; + struct dst_metrics *fib_metrics; + #define fib_mtu fib_metrics->metrics[RTAX_MTU-1] +@@ -320,7 +321,7 @@ void fib_flush_external(struct net *net) + /* Exported by fib_semantics.c */ + int ip_fib_check_default(__be32 gw, struct net_device *dev); + int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force); +-int fib_sync_down_addr(struct net *net, __be32 local); ++int fib_sync_down_addr(struct net_device *dev, __be32 local); + int fib_sync_up(struct net_device *dev, unsigned int nh_flags); + void fib_sync_mtu(struct net_device *dev, u32 orig_mtu); + +--- a/net/ipv4/fib_frontend.c ++++ b/net/ipv4/fib_frontend.c +@@ -509,6 +509,7 @@ static int rtentry_to_fib_config(struct + if (!dev) + return -ENODEV; + cfg->fc_oif = dev->ifindex; ++ cfg->fc_table = l3mdev_fib_table(dev); + if (colon) { + struct in_ifaddr *ifa; + struct in_device *in_dev = __in_dev_get_rtnl(dev); +@@ -1034,7 +1035,7 @@ no_promotions: + * First of all, we scan fib_info list searching + * for stray nexthop entries, then ignite fib_flush. + */ +- if (fib_sync_down_addr(dev_net(dev), ifa->ifa_local)) ++ if (fib_sync_down_addr(dev, ifa->ifa_local)) + fib_flush(dev_net(dev)); + } + } +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -1069,6 +1069,7 @@ struct fib_info *fib_create_info(struct + fi->fib_priority = cfg->fc_priority; + fi->fib_prefsrc = cfg->fc_prefsrc; + fi->fib_type = cfg->fc_type; ++ fi->fib_tb_id = cfg->fc_table; + + fi->fib_nhs = nhs; + change_nexthops(fi) { +@@ -1352,18 +1353,21 @@ nla_put_failure: + * referring to it. + * - device went down -> we must shutdown all nexthops going via it. + */ +-int fib_sync_down_addr(struct net *net, __be32 local) ++int fib_sync_down_addr(struct net_device *dev, __be32 local) + { + int ret = 0; + unsigned int hash = fib_laddr_hashfn(local); + struct hlist_head *head = &fib_info_laddrhash[hash]; ++ struct net *net = dev_net(dev); ++ int tb_id = l3mdev_fib_table(dev); + struct fib_info *fi; + + if (!fib_info_laddrhash || local == 0) + return 0; + + hlist_for_each_entry(fi, head, fib_lhash) { +- if (!net_eq(fi->fib_net, net)) ++ if (!net_eq(fi->fib_net, net) || ++ fi->fib_tb_id != tb_id) + continue; + if (fi->fib_prefsrc == local) { + fi->fib_flags |= RTNH_F_DEAD; diff --git a/queue-4.4/net-vrf-fix-dst-reference-counting.patch b/queue-4.4/net-vrf-fix-dst-reference-counting.patch new file mode 100644 index 00000000000..6aefc2f32df --- /dev/null +++ b/queue-4.4/net-vrf-fix-dst-reference-counting.patch @@ -0,0 +1,392 @@ +From 9ab179d83b4e31ea277a123492e419067c2f129a Mon Sep 17 00:00:00 2001 +From: David Ahern +Date: Thu, 7 Apr 2016 11:10:06 -0700 +Subject: net: vrf: Fix dst reference counting + +From: David Ahern + +commit 9ab179d83b4e31ea277a123492e419067c2f129a upstream. + +Vivek reported a kernel exception deleting a VRF with an active +connection through it. The root cause is that the socket has a cached +reference to a dst that is destroyed. Converting the dst_destroy to +dst_release and letting proper reference counting kick in does not +work as the dst has a reference to the device which needs to be released +as well. + +I talked to Hannes about this at netdev and he pointed out the ipv4 and +ipv6 dst handling has dst_ifdown for just this scenario. Rather than +continuing with the reinvented dst wheel in VRF just remove it and +leverage the ipv4 and ipv6 versions. + +Fixes: 193125dbd8eb2 ("net: Introduce VRF device driver") +Fixes: 35402e3136634 ("net: Add IPv6 support to VRF device") + +Signed-off-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/vrf.c | 177 ++++-------------------------------------------- + include/net/ip6_route.h | 3 + include/net/route.h | 3 + net/ipv4/route.c | 7 + + net/ipv6/route.c | 7 + + 5 files changed, 30 insertions(+), 167 deletions(-) + +--- a/drivers/net/vrf.c ++++ b/drivers/net/vrf.c +@@ -71,41 +71,6 @@ struct pcpu_dstats { + struct u64_stats_sync syncp; + }; + +-static struct dst_entry *vrf_ip_check(struct dst_entry *dst, u32 cookie) +-{ +- return dst; +-} +- +-static int vrf_ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb) +-{ +- return ip_local_out(net, sk, skb); +-} +- +-static unsigned int vrf_v4_mtu(const struct dst_entry *dst) +-{ +- /* TO-DO: return max ethernet size? */ +- return dst->dev->mtu; +-} +- +-static void vrf_dst_destroy(struct dst_entry *dst) +-{ +- /* our dst lives forever - or until the device is closed */ +-} +- +-static unsigned int vrf_default_advmss(const struct dst_entry *dst) +-{ +- return 65535 - 40; +-} +- +-static struct dst_ops vrf_dst_ops = { +- .family = AF_INET, +- .local_out = vrf_ip_local_out, +- .check = vrf_ip_check, +- .mtu = vrf_v4_mtu, +- .destroy = vrf_dst_destroy, +- .default_advmss = vrf_default_advmss, +-}; +- + /* neighbor handling is done with actual device; do not want + * to flip skb->dev for those ndisc packets. This really fails + * for multiple next protocols (e.g., NEXTHDR_HOP). But it is +@@ -363,46 +328,6 @@ static netdev_tx_t vrf_xmit(struct sk_bu + } + + #if IS_ENABLED(CONFIG_IPV6) +-static struct dst_entry *vrf_ip6_check(struct dst_entry *dst, u32 cookie) +-{ +- return dst; +-} +- +-static struct dst_ops vrf_dst_ops6 = { +- .family = AF_INET6, +- .local_out = ip6_local_out, +- .check = vrf_ip6_check, +- .mtu = vrf_v4_mtu, +- .destroy = vrf_dst_destroy, +- .default_advmss = vrf_default_advmss, +-}; +- +-static int init_dst_ops6_kmem_cachep(void) +-{ +- vrf_dst_ops6.kmem_cachep = kmem_cache_create("vrf_ip6_dst_cache", +- sizeof(struct rt6_info), +- 0, +- SLAB_HWCACHE_ALIGN, +- NULL); +- +- if (!vrf_dst_ops6.kmem_cachep) +- return -ENOMEM; +- +- return 0; +-} +- +-static void free_dst_ops6_kmem_cachep(void) +-{ +- kmem_cache_destroy(vrf_dst_ops6.kmem_cachep); +-} +- +-static int vrf_input6(struct sk_buff *skb) +-{ +- skb->dev->stats.rx_errors++; +- kfree_skb(skb); +- return 0; +-} +- + /* modelled after ip6_finish_output2 */ + static int vrf_finish_output6(struct net *net, struct sock *sk, + struct sk_buff *skb) +@@ -445,67 +370,34 @@ static int vrf_output6(struct net *net, + !(IP6CB(skb)->flags & IP6SKB_REROUTED)); + } + +-static void vrf_rt6_destroy(struct net_vrf *vrf) ++static void vrf_rt6_release(struct net_vrf *vrf) + { +- dst_destroy(&vrf->rt6->dst); +- free_percpu(vrf->rt6->rt6i_pcpu); ++ dst_release(&vrf->rt6->dst); + vrf->rt6 = NULL; + } + + static int vrf_rt6_create(struct net_device *dev) + { + struct net_vrf *vrf = netdev_priv(dev); +- struct dst_entry *dst; ++ struct net *net = dev_net(dev); + struct rt6_info *rt6; +- int cpu; + int rc = -ENOMEM; + +- rt6 = dst_alloc(&vrf_dst_ops6, dev, 0, +- DST_OBSOLETE_NONE, +- (DST_HOST | DST_NOPOLICY | DST_NOXFRM)); ++ rt6 = ip6_dst_alloc(net, dev, ++ DST_HOST | DST_NOPOLICY | DST_NOXFRM | DST_NOCACHE); + if (!rt6) + goto out; + +- dst = &rt6->dst; +- +- rt6->rt6i_pcpu = alloc_percpu_gfp(struct rt6_info *, GFP_KERNEL); +- if (!rt6->rt6i_pcpu) { +- dst_destroy(dst); +- goto out; +- } +- for_each_possible_cpu(cpu) { +- struct rt6_info **p = per_cpu_ptr(rt6->rt6i_pcpu, cpu); +- *p = NULL; +- } +- +- memset(dst + 1, 0, sizeof(*rt6) - sizeof(*dst)); +- +- INIT_LIST_HEAD(&rt6->rt6i_siblings); +- INIT_LIST_HEAD(&rt6->rt6i_uncached); +- +- rt6->dst.input = vrf_input6; + rt6->dst.output = vrf_output6; +- +- rt6->rt6i_table = fib6_get_table(dev_net(dev), vrf->tb_id); +- +- atomic_set(&rt6->dst.__refcnt, 2); +- ++ rt6->rt6i_table = fib6_get_table(net, vrf->tb_id); ++ dst_hold(&rt6->dst); + vrf->rt6 = rt6; + rc = 0; + out: + return rc; + } + #else +-static int init_dst_ops6_kmem_cachep(void) +-{ +- return 0; +-} +- +-static void free_dst_ops6_kmem_cachep(void) +-{ +-} +- +-static void vrf_rt6_destroy(struct net_vrf *vrf) ++static void vrf_rt6_release(struct net_vrf *vrf) + { + } + +@@ -577,11 +469,11 @@ static int vrf_output(struct net *net, s + !(IPCB(skb)->flags & IPSKB_REROUTED)); + } + +-static void vrf_rtable_destroy(struct net_vrf *vrf) ++static void vrf_rtable_release(struct net_vrf *vrf) + { + struct dst_entry *dst = (struct dst_entry *)vrf->rth; + +- dst_destroy(dst); ++ dst_release(dst); + vrf->rth = NULL; + } + +@@ -590,22 +482,10 @@ static struct rtable *vrf_rtable_create( + struct net_vrf *vrf = netdev_priv(dev); + struct rtable *rth; + +- rth = dst_alloc(&vrf_dst_ops, dev, 2, +- DST_OBSOLETE_NONE, +- (DST_HOST | DST_NOPOLICY | DST_NOXFRM)); ++ rth = rt_dst_alloc(dev, 0, RTN_UNICAST, 1, 1, 0); + if (rth) { + rth->dst.output = vrf_output; +- rth->rt_genid = rt_genid_ipv4(dev_net(dev)); +- rth->rt_flags = 0; +- rth->rt_type = RTN_UNICAST; +- rth->rt_is_input = 0; +- rth->rt_iif = 0; +- rth->rt_pmtu = 0; +- rth->rt_gateway = 0; +- rth->rt_uses_gateway = 0; + rth->rt_table_id = vrf->tb_id; +- INIT_LIST_HEAD(&rth->rt_uncached); +- rth->rt_uncached_list = NULL; + } + + return rth; +@@ -739,8 +619,8 @@ static void vrf_dev_uninit(struct net_de + // struct list_head *head = &queue->all_slaves; + // struct slave *slave, *next; + +- vrf_rtable_destroy(vrf); +- vrf_rt6_destroy(vrf); ++ vrf_rtable_release(vrf); ++ vrf_rt6_release(vrf); + + // list_for_each_entry_safe(slave, next, head, list) + // vrf_del_slave(dev, slave->dev); +@@ -772,7 +652,7 @@ static int vrf_dev_init(struct net_devic + return 0; + + out_rth: +- vrf_rtable_destroy(vrf); ++ vrf_rtable_release(vrf); + out_stats: + free_percpu(dev->dstats); + dev->dstats = NULL; +@@ -805,7 +685,7 @@ static struct rtable *vrf_get_rtable(con + struct net_vrf *vrf = netdev_priv(dev); + + rth = vrf->rth; +- atomic_inc(&rth->dst.__refcnt); ++ dst_hold(&rth->dst); + } + + return rth; +@@ -856,7 +736,7 @@ static struct dst_entry *vrf_get_rt6_dst + struct net_vrf *vrf = netdev_priv(dev); + + rt = vrf->rt6; +- atomic_inc(&rt->dst.__refcnt); ++ dst_hold(&rt->dst); + } + + return (struct dst_entry *)rt; +@@ -1003,19 +883,6 @@ static int __init vrf_init_module(void) + { + int rc; + +- vrf_dst_ops.kmem_cachep = +- kmem_cache_create("vrf_ip_dst_cache", +- sizeof(struct rtable), 0, +- SLAB_HWCACHE_ALIGN, +- NULL); +- +- if (!vrf_dst_ops.kmem_cachep) +- return -ENOMEM; +- +- rc = init_dst_ops6_kmem_cachep(); +- if (rc != 0) +- goto error2; +- + register_netdevice_notifier(&vrf_notifier_block); + + rc = rtnl_link_register(&vrf_link_ops); +@@ -1026,22 +893,10 @@ static int __init vrf_init_module(void) + + error: + unregister_netdevice_notifier(&vrf_notifier_block); +- free_dst_ops6_kmem_cachep(); +-error2: +- kmem_cache_destroy(vrf_dst_ops.kmem_cachep); + return rc; + } + +-static void __exit vrf_cleanup_module(void) +-{ +- rtnl_link_unregister(&vrf_link_ops); +- unregister_netdevice_notifier(&vrf_notifier_block); +- kmem_cache_destroy(vrf_dst_ops.kmem_cachep); +- free_dst_ops6_kmem_cachep(); +-} +- + module_init(vrf_init_module); +-module_exit(vrf_cleanup_module); + MODULE_AUTHOR("Shrijeet Mukherjee, David Ahern"); + MODULE_DESCRIPTION("Device driver to instantiate VRF domains"); + MODULE_LICENSE("GPL"); +--- a/include/net/ip6_route.h ++++ b/include/net/ip6_route.h +@@ -103,6 +103,9 @@ void fib6_force_start_gc(struct net *net + struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, + const struct in6_addr *addr, bool anycast); + ++struct rt6_info *ip6_dst_alloc(struct net *net, struct net_device *dev, ++ int flags); ++ + /* + * support functions for ND + * +--- a/include/net/route.h ++++ b/include/net/route.h +@@ -210,6 +210,9 @@ unsigned int inet_addr_type_dev_table(st + void ip_rt_multicast_event(struct in_device *); + int ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg); + void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt); ++struct rtable *rt_dst_alloc(struct net_device *dev, ++ unsigned int flags, u16 type, ++ bool nopolicy, bool noxfrm, bool will_cache); + + struct in_ifaddr; + void fib_add_ifaddr(struct in_ifaddr *); +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1500,9 +1500,9 @@ static void rt_set_nexthop(struct rtable + #endif + } + +-static struct rtable *rt_dst_alloc(struct net_device *dev, +- unsigned int flags, u16 type, +- bool nopolicy, bool noxfrm, bool will_cache) ++struct rtable *rt_dst_alloc(struct net_device *dev, ++ unsigned int flags, u16 type, ++ bool nopolicy, bool noxfrm, bool will_cache) + { + struct rtable *rt; + +@@ -1531,6 +1531,7 @@ static struct rtable *rt_dst_alloc(struc + + return rt; + } ++EXPORT_SYMBOL(rt_dst_alloc); + + /* called in rcu_read_lock() section */ + static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -339,9 +339,9 @@ static struct rt6_info *__ip6_dst_alloc( + return rt; + } + +-static struct rt6_info *ip6_dst_alloc(struct net *net, +- struct net_device *dev, +- int flags) ++struct rt6_info *ip6_dst_alloc(struct net *net, ++ struct net_device *dev, ++ int flags) + { + struct rt6_info *rt = __ip6_dst_alloc(net, dev, flags); + +@@ -365,6 +365,7 @@ static struct rt6_info *ip6_dst_alloc(st + + return rt; + } ++EXPORT_SYMBOL(ip6_dst_alloc); + + static void ip6_dst_destroy(struct dst_entry *dst) + { diff --git a/queue-4.4/power-bq27xxx-fix-reading-for-bq27000-and-bq27010.patch b/queue-4.4/power-bq27xxx-fix-reading-for-bq27000-and-bq27010.patch new file mode 100644 index 00000000000..da06fcfa178 --- /dev/null +++ b/queue-4.4/power-bq27xxx-fix-reading-for-bq27000-and-bq27010.patch @@ -0,0 +1,85 @@ +From 549d7b317c761dbf4ed0c2945aec3acc9ca7ae14 Mon Sep 17 00:00:00 2001 +From: "H. Nikolaus Schaller" +Date: Thu, 17 Dec 2015 11:12:53 +0100 +Subject: power: bq27xxx: fix reading for bq27000 and bq27010 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: H. Nikolaus Schaller + +commit 549d7b317c761dbf4ed0c2945aec3acc9ca7ae14 upstream. + +bug: the driver reports funny capacity values: + +root@letux:/sys/class/power_supply/bq27000-battery# cat uevent +POWER_SUPPLY_NAME=bq27000-battery +POWER_SUPPLY_STATUS=Charging +POWER_SUPPLY_PRESENT=1 +POWER_SUPPLY_VOLTAGE_NOW=3702000 +POWER_SUPPLY_CURRENT_NOW=-464635 +POWER_SUPPLY_CAPACITY=1536 <- over 100% is magic +POWER_SUPPLY_CAPACITY_LEVEL=Normal +POWER_SUPPLY_TEMP=311 +POWER_SUPPLY_TIME_TO_FULL_NOW=10440 +POWER_SUPPLY_TECHNOLOGY=Li-ion +POWER_SUPPLY_CHARGE_FULL=805450 +POWER_SUPPLY_CHARGE_NOW=1068 +POWER_SUPPLY_CHARGE_FULL_DESIGN=8844998 <- battery has just 1200 mAh +POWER_SUPPLY_CYCLE_COUNT=21 +POWER_SUPPLY_ENERGY_NOW=0 +POWER_SUPPLY_POWER_AVG=0 +POWER_SUPPLY_HEALTH=Good +POWER_SUPPLY_MANUFACTURER=Texas Instruments + +reason: the state of charge and the design capacity register are single +byte only. The design capacity returns the higer order byte. + +tested: GTA04 with Openmoko/FIC HF08x battery (using hdq) + +Fixes: d74534c27775 ("power: bq27xxx_battery: Add support for additional bq27xxx family devices") +Signed-off-by: H. Nikolaus Schaller +Acked-by: Andrew F. Davis +Reviewed-by: Pali Rohár +Signed-off-by: Sebastian Reichel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/power/bq27xxx_battery.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/drivers/power/bq27xxx_battery.c ++++ b/drivers/power/bq27xxx_battery.c +@@ -471,7 +471,10 @@ static int bq27xxx_battery_read_soc(stru + { + int soc; + +- soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false); ++ if (di->chip == BQ27000 || di->chip == BQ27010) ++ soc = bq27xxx_read(di, BQ27XXX_REG_SOC, true); ++ else ++ soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false); + + if (soc < 0) + dev_dbg(di->dev, "error reading State-of-Charge\n"); +@@ -536,7 +539,10 @@ static int bq27xxx_battery_read_dcap(str + { + int dcap; + +- dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, false); ++ if (di->chip == BQ27000 || di->chip == BQ27010) ++ dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, true); ++ else ++ dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, false); + + if (dcap < 0) { + dev_dbg(di->dev, "error reading initial last measured discharge\n"); +@@ -544,7 +550,7 @@ static int bq27xxx_battery_read_dcap(str + } + + if (di->chip == BQ27000 || di->chip == BQ27010) +- dcap *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS; ++ dcap = (dcap << 8) * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS; + else + dcap *= 1000; + diff --git a/queue-4.4/power-bq27xxx-fix-register-numbers-of-bq27500.patch b/queue-4.4/power-bq27xxx-fix-register-numbers-of-bq27500.patch new file mode 100644 index 00000000000..a0ae0df57a0 --- /dev/null +++ b/queue-4.4/power-bq27xxx-fix-register-numbers-of-bq27500.patch @@ -0,0 +1,39 @@ +From 099867a16a0fa9fd5aafc32e3b1a6f8a90f17834 Mon Sep 17 00:00:00 2001 +From: "H. Nikolaus Schaller" +Date: Thu, 17 Dec 2015 11:12:54 +0100 +Subject: power: bq27xxx: fix register numbers of bq27500 + +From: H. Nikolaus Schaller + +commit 099867a16a0fa9fd5aafc32e3b1a6f8a90f17834 upstream. + +bug: according to data sheet some register numbers are wrong. + +tested: no + +Fixes: d74534c27775 ("power: bq27xxx_battery: Add support for additional bq27xxx family devices") +Signed-off-by: H. Nikolaus Schaller +Acked-by: Andrew F. Davis +Signed-off-by: Sebastian Reichel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/power/bq27xxx_battery.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/power/bq27xxx_battery.c ++++ b/drivers/power/bq27xxx_battery.c +@@ -198,10 +198,10 @@ static u8 bq27500_regs[] = { + INVALID_REG_ADDR, /* TTECP - NA */ + 0x0c, /* NAC */ + 0x12, /* LMD(FCC) */ +- 0x1e, /* CYCT */ ++ 0x2a, /* CYCT */ + INVALID_REG_ADDR, /* AE - NA */ +- 0x20, /* SOC(RSOC) */ +- 0x2e, /* DCAP(ILMD) */ ++ 0x2c, /* SOC(RSOC) */ ++ 0x3c, /* DCAP(ILMD) */ + INVALID_REG_ADDR, /* AP - NA */ + }; + diff --git a/queue-4.4/power-bq27xxx_battery-fix-bq27541-averagepower-register-address.patch b/queue-4.4/power-bq27xxx_battery-fix-bq27541-averagepower-register-address.patch new file mode 100644 index 00000000000..31a4fe0d4d9 --- /dev/null +++ b/queue-4.4/power-bq27xxx_battery-fix-bq27541-averagepower-register-address.patch @@ -0,0 +1,36 @@ +From 265b60497a57da56a4be7d5c72983ae89dc0765e Mon Sep 17 00:00:00 2001 +From: Liu Xiang +Date: Sat, 9 Jan 2016 22:10:39 +0800 +Subject: power: bq27xxx_battery: Fix bq27541 AveragePower register address + +From: Liu Xiang + +commit 265b60497a57da56a4be7d5c72983ae89dc0765e upstream. + +Currently in bq27541 driver, the average power register address is +incorrectly set to 0x76, which would result in an error: +bq27xxx-battery 2-0055: error reading average power register 10: -11 +According to the bq27541 datasheet, fix this problem by setting +the average power register address to 0x24. + +Fixes: d74534c27775 ("power: bq27xxx_battery: Add support for additional bq27xxx family devices") +Signed-off-by: Liu Xiang +Acked-by: Andrew F. Davis +Signed-off-by: Sebastian Reichel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/power/bq27xxx_battery.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/power/bq27xxx_battery.c ++++ b/drivers/power/bq27xxx_battery.c +@@ -242,7 +242,7 @@ static u8 bq27541_regs[] = { + INVALID_REG_ADDR, /* AE - NA */ + 0x2c, /* SOC(RSOC) */ + 0x3c, /* DCAP */ +- 0x76, /* AP */ ++ 0x24, /* AP */ + }; + + static u8 bq27545_regs[] = { diff --git a/queue-4.4/power-test_power-correctly-handle-empty-writes.patch b/queue-4.4/power-test_power-correctly-handle-empty-writes.patch new file mode 100644 index 00000000000..fc4ee837ccf --- /dev/null +++ b/queue-4.4/power-test_power-correctly-handle-empty-writes.patch @@ -0,0 +1,32 @@ +From 6b9140f39c2aaf76791197fbab0839c0e4af56e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Dec 2015 12:43:36 -0500 +Subject: power: test_power: correctly handle empty writes + +From: Sasha Levin + +commit 6b9140f39c2aaf76791197fbab0839c0e4af56e8 upstream. + +Writing 0 length data into test_power makes it access an invalid array +location and kill the system. + +Fixes: f17ef9b2d ("power: Make test_power driver more dynamic.") +Signed-off-by: Sasha Levin +Signed-off-by: Sebastian Reichel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/power/test_power.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/power/test_power.c ++++ b/drivers/power/test_power.c +@@ -301,6 +301,8 @@ static int map_get_value(struct battery_ + buf[MAX_KEYLENGTH-1] = '\0'; + + cr = strnlen(buf, MAX_KEYLENGTH) - 1; ++ if (cr < 0) ++ return def_val; + if (buf[cr] == '\n') + buf[cr] = '\0'; + diff --git a/queue-4.4/power_supply-tps65217-charger-fix-null-deref-during-property-export.patch b/queue-4.4/power_supply-tps65217-charger-fix-null-deref-during-property-export.patch new file mode 100644 index 00000000000..a042ddbf1d0 --- /dev/null +++ b/queue-4.4/power_supply-tps65217-charger-fix-null-deref-during-property-export.patch @@ -0,0 +1,61 @@ +From 362761299eea7dfc3a4870551de36e08758b9254 Mon Sep 17 00:00:00 2001 +From: Marcin Niestroj +Date: Tue, 14 Jun 2016 15:29:24 +0200 +Subject: power_supply: tps65217-charger: Fix NULL deref during property export + +From: Marcin Niestroj + +commit 362761299eea7dfc3a4870551de36e08758b9254 upstream. + +This bug leads to: + +[ 1.906411] Unable to handle kernel NULL pointer dereference at virtual address 0000000c +[ 1.914878] pgd = c0004000 +[ 1.917786] [0000000c] *pgd=00000000 +[ 1.921536] Internal error: Oops: 5 [#1] SMP ARM +[ 1.926357] Modules linked in: +[ 1.929556] CPU: 0 PID: 14 Comm: kworker/0:1 Not tainted 4.4.5 #18 +[ 1.936006] Hardware name: Generic AM33XX (Flattened Device Tree) +[ 1.942383] Workqueue: events power_supply_changed_work +[ 1.947842] task: de2c41c0 ti: de2c8000 task.ti: de2c8000 +[ 1.953483] PC is at tps65217_ac_get_property+0x14/0x28 +[ 1.958937] LR is at tps65217_ac_get_property+0x10/0x28 + +Driver was trying to use drv_data in property get handler. However drv_data +was not set, so it caused NULL pointer dereference. This patch properly +sets drv_data during probe by power_supply_config parameter, so the +property get handler works as desired. + +Signed-off-by: Marcin Niestroj +Fixes: 3636859b280c ("power_supply: Add support for tps65217-charger") +Signed-off-by: Sebastian Reichel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/power/tps65217_charger.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/power/tps65217_charger.c ++++ b/drivers/power/tps65217_charger.c +@@ -197,6 +197,7 @@ static int tps65217_charger_probe(struct + { + struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); + struct tps65217_charger *charger; ++ struct power_supply_config cfg = {}; + int ret; + + dev_dbg(&pdev->dev, "%s\n", __func__); +@@ -209,9 +210,12 @@ static int tps65217_charger_probe(struct + charger->tps = tps; + charger->dev = &pdev->dev; + ++ cfg.of_node = pdev->dev.of_node; ++ cfg.drv_data = charger; ++ + charger->ac = devm_power_supply_register(&pdev->dev, + &tps65217_charger_desc, +- NULL); ++ &cfg); + if (IS_ERR(charger->ac)) { + dev_err(&pdev->dev, "failed: power supply register\n"); + return PTR_ERR(charger->ac); diff --git a/queue-4.4/series b/queue-4.4/series index 2f3cd51795f..89270f970ee 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -237,3 +237,10 @@ net-ethernet-fec-fix-fixed-link-phydev-leaks.patch net-ethernet-ti-davinci_emac-fix-fixed-link-phydev-and-of-node-leaks.patch net-dsa-move-dsa-slave-destroy-code-to-slave.c.patch net-dsa-slave-fix-fixed-link-phydev-leaks.patch +power-bq27xxx-fix-reading-for-bq27000-and-bq27010.patch +power-bq27xxx-fix-register-numbers-of-bq27500.patch +power-test_power-correctly-handle-empty-writes.patch +power-bq27xxx_battery-fix-bq27541-averagepower-register-address.patch +power_supply-tps65217-charger-fix-null-deref-during-property-export.patch +net-vrf-fix-dst-reference-counting.patch +net-don-t-delete-routes-in-different-vrfs.patch -- 2.47.3