twx-linux/include/linux/mfd
Krzysztof Kozlowski 297d716f62 power_supply: Change ownership from driver to core
Change the ownership of power_supply structure from each driver
implementing the class to the power supply core.

The patch changes power_supply_register() function thus all drivers
implementing power supply class are adjusted.

Each driver provides the implementation of power supply. However it
should not be the owner of power supply class instance because it is
exposed by core to other subsystems with power_supply_get_by_name().
These other subsystems have no knowledge when the driver will unregister
the power supply. This leads to several issues when driver is unbound -
mostly because user of power supply accesses freed memory.

Instead let the core own the instance of struct 'power_supply'.  Other
users of this power supply will still access valid memory because it
will be freed when device reference count reaches 0. Currently this
means "it will leak" but power_supply_put() call in next patches will
solve it.

This solves invalid memory references in following race condition
scenario:

Thread 1: charger manager
Thread 2: power supply driver, used by charger manager

THREAD 1 (charger manager)         THREAD 2 (power supply driver)
==========================         ==============================
psy = power_supply_get_by_name()
                                   Driver unbind, .remove
                                     power_supply_unregister()
                                     Device fully removed
psy->get_property()

The 'get_property' call is executed in invalid context because the driver was
unbound and struct 'power_supply' memory was freed.

This could be observed easily with charger manager driver (here compiled
with max17040 fuel gauge):

$ cat /sys/devices/virtual/power_supply/cm-battery/capacity &
$ echo "1-0036" > /sys/bus/i2c/drivers/max17040/unbind
[   55.725123] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[   55.732584] pgd = d98d4000
[   55.734060] [00000000] *pgd=5afa2831, *pte=00000000, *ppte=00000000
[   55.740318] Internal error: Oops: 80000007 [#1] PREEMPT SMP ARM
[   55.746210] Modules linked in:
[   55.749259] CPU: 1 PID: 2936 Comm: cat Tainted: G        W       3.19.0-rc1-next-20141226-00048-gf79f475f3c44-dirty #1496
[   55.760190] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[   55.766270] task: d9b76f00 ti: daf54000 task.ti: daf54000
[   55.771647] PC is at 0x0
[   55.774182] LR is at charger_get_property+0x2f4/0x36c
[   55.779201] pc : [<00000000>]    lr : [<c034b0b4>]    psr: 60000013
[   55.779201] sp : daf55e90  ip : 00000003  fp : 00000000
[   55.790657] r10: 00000000  r9 : c06e2878  r8 : d9b26c68
[   55.795865] r7 : dad81610  r6 : daec7410  r5 : daf55ebc  r4 : 00000000
[   55.802367] r3 : 00000000  r2 : daf55ebc  r1 : 0000002a  r0 : d9b26c68
[   55.808879] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[   55.815994] Control: 10c5387d  Table: 598d406a  DAC: 00000015
[   55.821723] Process cat (pid: 2936, stack limit = 0xdaf54210)
[   55.827451] Stack: (0xdaf55e90 to 0xdaf56000)
[   55.831795] 5e80:                                     60000013 c01459c4 0000002a c06f8ef8
[   55.839956] 5ea0: db651000 c06f8ef8 daebac00 c04cb668 daebac08 c0346864 00000000 c01459c4
[   55.848115] 5ec0: d99eaa80 c06f8ef8 00000fff 00001000 db651000 c027f25c c027f240 d99eaa80
[   55.856274] 5ee0: d9a06c00 c0146218 daf55f18 00001000 d99eaa80 db4c18c0 00000001 00000001
[   55.864468] 5f00: daf55f80 c0144c78 c0144c54 c0107f90 00015000 d99eaab0 00000000 00000000
[   55.872603] 5f20: 000051c7 00000000 db4c18c0 c04a9370 00015000 00001000 daf55f80 00001000
[   55.880763] 5f40: daf54000 00015000 00000000 c00e53dc db4c18c0 c00e548c 0000000d 00008124
[   55.888937] 5f60: 00000001 00000000 00000000 db4c18c0 db4c18c0 00001000 00015000 c00e5550
[   55.897099] 5f80: 00000000 00000000 00001000 00001000 00015000 00000003 00000003 c000f364
[   55.905239] 5fa0: 00000000 c000f1a0 00001000 00015000 00000003 00015000 00001000 0001333c
[   55.913399] 5fc0: 00001000 00015000 00000003 00000003 00000002 00000000 00000000 00000000
[   55.921560] 5fe0: 7fffe000 be999850 0000a225 b6f3c19c 60000010 00000003 00000000 00000000
[   55.929744] [<c034b0b4>] (charger_get_property) from [<c0346864>] (power_supply_show_property+0x48/0x20c)
[   55.939286] [<c0346864>] (power_supply_show_property) from [<c027f25c>] (dev_attr_show+0x1c/0x48)
[   55.948130] [<c027f25c>] (dev_attr_show) from [<c0146218>] (sysfs_kf_seq_show+0x84/0x104)
[   55.956298] [<c0146218>] (sysfs_kf_seq_show) from [<c0144c78>] (kernfs_seq_show+0x24/0x28)
[   55.964536] [<c0144c78>] (kernfs_seq_show) from [<c0107f90>] (seq_read+0x1b0/0x484)
[   55.972172] [<c0107f90>] (seq_read) from [<c00e53dc>] (__vfs_read+0x18/0x4c)
[   55.979188] [<c00e53dc>] (__vfs_read) from [<c00e548c>] (vfs_read+0x7c/0x100)
[   55.986304] [<c00e548c>] (vfs_read) from [<c00e5550>] (SyS_read+0x40/0x8c)
[   55.993164] [<c00e5550>] (SyS_read) from [<c000f1a0>] (ret_fast_syscall+0x0/0x48)
[   56.000626] Code: bad PC value
[   56.011652] ---[ end trace 7b64343fbdae8ef1 ]---

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>

[for the nvec part]
Reviewed-by: Marc Dietrich <marvin24@gmx.de>

[for compal-laptop.c]
Acked-by: Darren Hart <dvhart@linux.intel.com>

[for the mfd part]
Acked-by: Lee Jones <lee.jones@linaro.org>

[for the hid part]
Acked-by: Jiri Kosina <jkosina@suse.cz>

[for the acpi part]
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Signed-off-by: Sebastian Reichel <sre@kernel.org>
2015-03-13 23:15:51 +01:00
..
abx500 power_supply: Change ownership from driver to core 2015-03-13 23:15:51 +01:00
arizona sound updates for 3.19-rc1 2014-12-11 13:20:50 -08:00
da9052 mfd: da9052: Avoid setting read_flag_mask for da9052-i2c driver 2014-09-26 08:15:54 +01:00
da9055
da9063 mfd: da9063: Add device tree support 2015-01-22 16:04:04 +00:00
da9150 mfd: Add support for DA9150 combined charger & fuel-gauge device 2015-01-22 15:55:54 +00:00
pcf50633
samsung regulator: s2mps11: Fix wrong calculation of register offset 2015-01-08 18:16:58 +00:00
syscon ARM: SoC driver updates 2015-02-17 09:38:59 -08:00
wm831x
wm8350 power_supply: Change ownership from driver to core 2015-03-13 23:15:51 +01:00
wm8994
88pm80x.h
88pm860x.h
aat2870.h
ab3100.h
abx500.h mfd: abx500-core: Remove unused function abx500_dump_all_banks() 2014-06-03 08:11:51 +01:00
adp5520.h
as3711.h
as3722.h
asic3.h
atmel-hlcdc.h mfd: Add atmel-hlcdc driver 2014-11-25 16:18:43 +00:00
axp20x.h mfd: axp20x: Add support for fuel gauge cell driver 2015-01-22 15:56:05 +00:00
bcm590xx.h mfd: bcm590xx: Add support for secondary I2C slave address 2014-05-21 10:40:08 +01:00
core.h mfd: core: Add helper function to register hotplug devices 2014-11-10 16:30:03 +00:00
cros_ec_commands.h i2c: cros_ec: Remove EC_I2C_FLAG_10BIT 2014-09-30 08:06:02 +02:00
cros_ec.h mfd: cros_ec: stop calling ->cmd_xfer() directly 2014-10-06 21:29:07 +01:00
da903x.h
davinci_voicecodec.h ASoC: cq93vc: Remove unused state struct 2014-11-27 11:11:30 +00:00
db8500-prcmu.h
dbx500-prcmu.h
dln2.h mfd: Add support for Diolan DLN-2 devices 2014-11-10 16:30:05 +00:00
ds1wm.h
ezx-pcap.h
hi6421-pmic.h mfd: Add HI6421 PMIC Core driver 2014-09-26 08:23:43 +01:00
htc-egpio.h
htc-pasic3.h
intel_msic.h
intel_soc_pmic.h mfd: intel_soc_pmic: Core driver 2014-06-17 15:59:20 +01:00
ipaq-micro.h mfd: Add driver for Atmel Microcontroller on iPaq h3xxx 2014-06-03 08:11:42 +01:00
janz.h
kempld.h mfd: Add sysfs attributes for Kontron PLD firmware revision 2014-06-03 08:11:11 +01:00
lm3533.h
lp3943.h
lp8788-isink.h
lp8788.h
lpc_ich.h mfd: lpc_ich: Add support for iTCO v3 2014-03-19 09:00:02 +00:00
max8907.h
max8925.h
max8997-private.h
max8997.h
max8998-private.h
max8998.h
max14577-private.h charger: max14577: Configure battery-dependent settings from DTS and sysfs 2014-09-24 15:25:49 +01:00
max14577.h charger: max14577: Configure battery-dependent settings from DTS and sysfs 2014-09-24 15:25:49 +01:00
max77686-private.h mfd: max77686/802: Remove support for board files 2015-01-22 16:03:55 +00:00
max77686.h mfd: max77686/802: Remove support for board files 2015-01-22 16:03:55 +00:00
max77693-private.h mfd: max77693: Add defines for MAX77693 charger driver 2015-01-20 14:04:12 +01:00
max77693.h mfd: max77693: Improve support for the flash cell 2014-09-26 08:15:43 +01:00
mc13xxx.h mfd: mc13xxx: Use regmap irq framework for interrupts 2014-07-09 14:58:10 +01:00
mc13783.h mfd: mc13xxx: Use regmap irq framework for interrupts 2014-07-09 14:58:10 +01:00
mc13892.h
mcp.h
menelaus.h
palmas.h regulator: palmas: Rename reg_info to palmas_reg_info 2014-07-03 15:25:52 +01:00
qcom_rpm.h mfd: qcom-rpm: Driver for the Qualcomm RPM 2015-01-22 16:04:00 +00:00
rc5t583.h
rdc321x.h mfd: rdc321x: Fix off-by-one for ngpio setting 2014-06-03 08:11:17 +01:00
retu.h
rk808.h mfd: RK808: Add new mfd driver for RK808 2014-09-26 08:15:56 +01:00
rn5t618.h mfd: Add Ricoh RN5T618 PMIC core driver 2014-09-26 08:15:51 +01:00
rt5033-private.h mfd: rt5033: Add Richtek RT5033 driver core. 2015-01-22 15:55:47 +00:00
rt5033.h power_supply: Change ownership from driver to core 2015-03-13 23:15:51 +01:00
rtsx_common.h mmc: rtsx: Revert "mmc: rtsx: add support for pre_req and post_req" 2014-05-08 08:44:50 +01:00
rtsx_pci.h mfd: rtsx: Add func to split u32 into register 2014-12-08 10:05:39 +00:00
rtsx_usb.h mfd: Add realtek USB card reader driver 2014-03-19 08:58:18 +00:00
si476x-core.h
si476x-platform.h
si476x-reports.h
smsc.h
sta2x11-mfd.h
stmpe.h gpio: stmpe: enforce device tree only mode 2015-01-20 11:03:22 +01:00
stw481x.h
syscon.h mfd: syscon: Include linux/err.h to fix build error 2014-06-03 08:11:41 +01:00
t7l66xb.h
tc3589x.h gpio: tc3589x: get rid of platform data 2015-01-15 17:23:19 +01:00
tc6387xb.h
tc6393xb.h
ti_am335x_tscadc.h Input: ti_am335x_tsc - remove udelay in interrupt handler 2015-02-03 11:50:38 -08:00
tmio.h mmc: tmio: remove TMIO_MMC_HAVE_CTL_DMA_REG flag 2015-01-20 10:24:36 +01:00
tps6105x.h
tps6507x.h
tps6586x.h regulator: tps6586x: Add support for the TPS658640 2014-05-26 16:48:02 +01:00
tps65090.h Immutable branch between MFD and Regulator due for v3.16 merge-window. 2014-04-29 10:01:28 -07:00
tps65217.h mfd: tps65217: Tell regmap what registers are valid 2014-09-26 08:23:50 +01:00
tps65218.h mfd: tps65218: Remove unused *rdev[] from struct tps65218 2014-06-03 08:11:13 +01:00
tps65910.h mfd: tps65910: Rid data size incompatibility warn when building for 64bit 2014-07-09 16:38:01 +01:00
tps65912.h
tps80031.h
twl4030-audio.h
twl6040.h mfd: twl6040: Optional clk32k clock handling 2014-06-03 08:11:20 +01:00
ucb1x00.h
viperboard.h
wl1273-core.h
wm8400-audio.h
wm8400-private.h
wm8400.h