Files
kernel_google_b1c1/drivers/base/regmap/regmap-debugfs.c
lucaswei 2b5e67e8a2 Merge android-4.9-q (4.9.232) into android-msm-pixel-4.9-lts
Merge 4.9.232 into android-4.9-q
Linux 4.9.232
    perf: Make perf able to build with latest libbfd
    perf tools: Fix snprint warnings for gcc 8
    perf annotate: Use asprintf when formatting objdump command line
    perf probe: Fix to check blacklist address correctly
    xfs: set format back to extents if xfs_bmap_extents_to_btree
  * regmap: debugfs: check count when read regmap file
      drivers/base/regmap/regmap-debugfs.c
    drivers/net/wan/x25_asy: Fix to make it work
    ip6_gre: fix null-ptr-deref in ip6gre_init_net()
  * tcp: allow at most one TLP probe per flight
      include/linux/tcp.h
      net/ipv4/tcp_input.c
      net/ipv4/tcp_output.c
    AX.25: Prevent integer overflows in connect and sendmsg
    rxrpc: Fix sendmsg() returning EPIPE due to recvmsg() returning ENODATA
  * net: udp: Fix wrong clean up for IS_UDPLITE macro
      net/ipv4/udp.c
      net/ipv6/udp.c
  * net-sysfs: add a newline when printing 'tx_timeout' by sysfs
      net/core/net-sysfs.c
  * dev: Defer free of skbs in flush_backlog
      net/core/dev.c
    AX.25: Prevent out-of-bounds read in ax25_sendmsg()
    AX.25: Fix out-of-bounds read in ax25_connect()
    ath9k: Fix regression with Atheros 9271
    ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb
    parisc: Add atomic64_set_release() define to avoid CPU soft lockups
    io-mapping: indicate mapping failure
  * mm/memcg: fix refcount error while moving and swapping
      mm/memcontrol.c
  * Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation
      Makefile
  * vt: Reject zero-sized screen buffer size.
      drivers/tty/vt/vt.c
    serial: 8250_mtk: Fix high-speed baud rates clamping
    serial: 8250: fix null-ptr-deref in serial8250_start_tx()
    staging: comedi: addi_apci_1564: check INSN_CONFIG_DIGITAL_TRIG shift
    staging: comedi: addi_apci_1500: check INSN_CONFIG_DIGITAL_TRIG shift
    staging: comedi: ni_6527: fix INSN_CONFIG_DIGITAL_TRIG support
    staging: comedi: addi_apci_1032: check INSN_CONFIG_DIGITAL_TRIG shift
    staging: wlan-ng: properly check endpoint types
    Revert "cifs: Fix the target file was deleted when rename failed."
  * usb: xhci: Fix ASM2142/ASM3142 DMA addressing
      drivers/usb/host/xhci-pci.c
    usb: xhci-mtk: fix the failure of bandwidth allocation
    x86: math-emu: Fix up 'cmp' insn for clang ias
  * arm64: Use test_tsk_thread_flag() for checking TIF_SINGLESTEP
      arch/arm64/kernel/debug-monitors.c
    usb: gadget: udc: gr_udc: fix memleak on error handling path in gr_ep_init()
    dmaengine: ioat setting ioat timeout as module parameter
  * regmap: dev_get_regmap_match(): fix string comparison
      drivers/base/regmap/regmap.c
    dmaengine: tegra210-adma: Fix runtime PM imbalance on error
  * HID: apple: Disable Fn-key key-re-mapping on clone keyboards
      drivers/hid/hid-apple.c
    HID: i2c-hid: add Mediacom FlexBook edge13 to descriptor override
    scripts/decode_stacktrace: strip basepath from all paths
    net: smc91x: Fix possible memory leak in smc_drv_probe()
    net: dp83640: fix SIOCSHWTSTAMP to update the struct with actual configuration
  * ax88172a: fix ax88172a_unbind() failures
      drivers/net/usb/ax88172a.c
    hippi: Fix a size used in a 'pci_free_consistent()' in an error handling path
    bnxt_en: Fix race when modifying pause settings.
    btrfs: fix mount failure caused by race with umount
    btrfs: fix double free on ulist after backref resolution failure
    ASoC: rt5670: Correct RT5670_LDO_SEL_MASK
  * ALSA: info: Drop WARN_ON() from buffer NULL sanity check
      sound/core/info.c
    uprobes: Change handle_swbp() to send SIGTRAP with si_code=SI_KERNEL, to fix GDB regression
    SUNRPC reverting d03727b248d0 ("NFSv4 fix CLOSE not waiting for direct IO compeletion")
    drm/nouveau/i2c/g94-: increase NV_PMGR_DP_AUXCTL_TRANSACTREQ timeout
    net: sky2: initialize return of gm_phy_read
    drivers/net/wan/lapbether: Fixed the value of hard_header_len
    xtensa: update *pos in cpuinfo_op.next
    xtensa: fix __sync_fetch_and_{and,or}_4 declarations
    scsi: scsi_transport_spi: Fix function pointer check
    mac80211: allow rx of mesh eapol frames with default rx key
    pinctrl: amd: fix npins for uart0 in kerncz_groups
  * UPSTREAM: xtables: extend matches and targets with .usersize
      net/netfilter/xt_CT.c
      net/netfilter/xt_TEE.c
      net/netfilter/xt_bpf.c
      net/netfilter/xt_connlimit.c
      net/netfilter/xt_hashlimit.c
      net/netfilter/xt_limit.c
      net/netfilter/xt_quota.c
      net/netfilter/xt_string.c
  * UPSTREAM: ip6tables: use match, target and data copy_to_user helpers
      net/ipv6/netfilter/ip6_tables.c
  * UPSTREAM: iptables: use match, target and data copy_to_user helpers
      net/ipv4/netfilter/ip_tables.c
  * UPSTREAM: xtables: add xt_match, xt_target and data copy_to_user functions
      include/linux/netfilter/x_tables.h
      net/netfilter/x_tables.c
    Merge 4.9.231 into android-4.9-q
Linux 4.9.231
    x86/cpu: Move x86_cache_bits settings
  * irqchip/gic: Atomically update affinity
      drivers/irqchip/irq-gic.c
  * sched/fair: handle case of task_h_load() returning 0
      kernel/sched/fair.c
  * arm64: ptrace: Override SPSR.SS when single-stepping is enabled
      arch/arm64/include/asm/debug-monitors.h
      arch/arm64/kernel/debug-monitors.c
      arch/arm64/kernel/ptrace.c
    misc: atmel-ssc: lock with mutex instead of spinlock
    dmaengine: fsl-edma: Fix NULL pointer exception in fsl_edma_tx_handler
    hwmon: (emc2103) fix unable to change fan pwm1_enable attribute
    MIPS: Fix build for LTS kernel caused by backporting lpj adjustment
  * timer: Fix wheel index calculation on last level
      kernel/time/timer.c
    uio_pdrv_genirq: fix use without device tree and no interrupt
    Input: i8042 - add Lenovo XiaoXin Air 12 to i8042 nomux list
    mei: bus: don't clean driver pointer
  * fuse: Fix parameter for FS_IOC_{GET,SET}FLAGS
      fs/fuse/file.c
    virtio: virtio_console: add missing MODULE_DEVICE_TABLE() for rproc serial
    USB: serial: option: add Quectel EG95 LTE modem
    USB: serial: option: add GosunCn GM500 series
    USB: serial: ch341: add new Product ID for CH340
    USB: serial: cypress_m8: enable Simply Automated UPB PIM
    USB: serial: iuu_phoenix: fix memory corruption
    usb: gadget: function: fix missing spinlock in f_uac1_legacy
    usb: chipidea: core: add wakeup support for extcon
    usb: dwc2: Fix shutdown callback in platform
    USB: c67x00: fix use after free in c67x00_giveback_urb
  * ALSA: usb-audio: Fix race against the error recovery URB submission
      sound/usb/midi.c
    ALSA: line6: Perform sanity check for each URB creation
  * usb: core: Add a helper function to check the validity of EP type in URB
      drivers/usb/core/urb.c
      include/linux/usb.h
  * HID: magicmouse: do not set up autorepeat
      drivers/hid/hid-magicmouse.c
    mtd: rawnand: brcmnand: fix CS0 layout
    perf stat: Zero all the 'ena' and 'run' array slot stats for interval mode
    ARM: dts: socfpga: Align L2 cache-controller nodename with dtschema
    Revert "thermal: mediatek: fix register index error"
    staging: comedi: verify array index is correct before using it
    usb: gadget: udc: atmel: fix uninitialized read in debug printk
    spi: spi-sun6i: sun6i_spi_transfer_one(): fix setting of clock rate
    iio:health:afe4404 Fix timestamp alignment and prevent data leak.
    Revert "usb/ohci-platform: Fix a warning when hibernating"
  * Revert "usb/xhci-plat: Set PM runtime as active on resume"
      drivers/usb/host/xhci-plat.c
    Revert "usb/ehci-platform: Set PM runtime as active on resume"
    net: dsa: bcm_sf2: Fix node reference count
    spi: fix initial SPI_SR value in spi-fsl-dspi
    iio:health:afe4403 Fix timestamp alignment and prevent data leak.
    iio:pressure:ms5611 Fix buffer element alignment
    iio: pressure: zpa2326: handle pm_runtime_get_sync failure
    iio: mma8452: Add missed iio_device_unregister() call in mma8452_probe()
    iio: magnetometer: ak8974: Fix runtime PM imbalance on error
    iio:magnetometer:ak8974: Fix alignment and data leak issues
    i2c: eg20t: Load module automatically if ID matches
  * cgroup: Fix sock_cgroup_data on big-endian.
      include/linux/cgroup-defs.h
  * cgroup: fix cgroup_sk_alloc() for sk_clone_lock()
      include/linux/cgroup-defs.h
      include/linux/cgroup.h
      kernel/cgroup.c
      net/core/sock.c
  * tcp: md5: allow changing MD5 keys in all socket states
      net/ipv4/tcp.c
  * tcp: md5: do not send silly options in SYNCOOKIES
      net/ipv4/tcp_output.c
  * tcp: make sure listeners don't initialize congestion-control state
      net/ipv4/tcp.c
      net/ipv4/tcp_cong.c
  * genetlink: remove genl_bind
      include/net/genetlink.h
      net/netlink/genetlink.c
  * tcp: md5: refine tcp_md5_do_add()/tcp_md5_hash_key() barriers
      net/ipv4/tcp.c
      net/ipv4/tcp_ipv4.c
  * tcp: md5: add missing memory barriers in tcp_md5_do_add()/tcp_md5_hash_key()
      net/ipv4/tcp.c
      net/ipv4/tcp_ipv4.c
    net: usb: qmi_wwan: add support for Quectel EG95 LTE modem
  * net: Added pointer check for dst->ops->neigh_lookup in dst_neigh_lookup_skb
      include/net/dst.h
    llc: make sure applications use ARPHRD_ETHER
  * l2tp: remove skb_dst_set() from l2tp_xmit_skb()
      net/l2tp/l2tp_core.c
  * ipv4: fill fl4_icmp_{type,code} in ping_v4_sendmsg
      net/ipv4/ping.c
    s390/mm: fix huge pte soft dirty copying
    ARC: elf: use right ELF_ARCH
    ARC: entry: fix potential EFA clobber when TIF_SYSCALL_TRACE
    drm/radeon: fix double free
    btrfs: fix fatal extent_buffer readahead vs releasepage race
    Revert "ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb"
    KVM: x86: bit 8 of non-leaf PDPEs is not reserved
  * KVM: arm64: Fix definition of PAGE_HYP_DEVICE
      arch/arm64/include/asm/pgtable-prot.h
  * ALSA: usb-audio: add quirk for MacroSilicon MS2109
      sound/usb/quirks-table.h
    ALSA: hda - let hs_mic be picked ahead of hp_mic
    ALSA: opl3: fix infoleak in opl3
    net: macb: mark device wake capable when "magic-packet" property present
    bnxt_en: fix NULL dereference in case SR-IOV configuration fails
  * arm64: kgdb: Fix single-step exception handling oops
      arch/arm64/kernel/kgdb.c
  * ALSA: compress: fix partial_drain completion state
      include/sound/compress_driver.h
      sound/core/compress_offload.c
    smsc95xx: avoid memory leak in smsc95xx_bind
    smsc95xx: check return value of smsc95xx_reset
    net: cxgb4: fix return error value in t4_prep_fw
    scsi: mptscsih: Fix read sense data size
    ARM: imx6: add missing put_device() call in imx6q_suspend_init()
    cifs: update ctime and mtime during truncate
    s390/kasan: fix early pgm check handler execution
  * spi: spidev: fix a potential use-after-free in spidev_release()
      drivers/spi/spidev.c
  * spi: spidev: fix a race between spidev_release and spidev_remove
      drivers/spi/spidev.c
    gpu: host1x: Detach driver on unregister
    KVM: s390: reduce number of IO pins to 1
    ANDROID: cuttlefish_defconfig: Drop built-in cmdline (except nopti)
    Merge 4.9.230 into android-4.9-q
Linux 4.9.230
  * efi: Make it possible to disable efivar_ssdt entirely
      drivers/firmware/efi/Kconfig
  * netfilter: nf_conntrack_h323: lost .data_len definition for Q.931/ipv6
      net/netfilter/nf_conntrack_h323_main.c
    MIPS: Add missing EHB in mtc0 -> mfc0 sequence for DSPen
    cifs: Fix the target file was deleted when rename failed.
    SMB3: Honor persistent/resilient handle flags for multiuser mounts
    SMB3: Honor 'seal' flag for multiuser mounts
  * Revert "ALSA: usb-audio: Improve frames size computation"
      sound/usb/card.h
      sound/usb/endpoint.c
      sound/usb/endpoint.h
      sound/usb/pcm.c
    i2c: algo-pca: Add 0x78 as SCL stuck low status for PCA9665
    virtio-blk: free vblk-vqs in error path of virtblk_probe()
    hwmon: (acpi_power_meter) Fix potential memory leak in acpi_power_meter_add()
    hwmon: (max6697) Make sure the OVERT mask is set correctly
    cxgb4: parse TC-U32 key values and masks natively
  * sched/rt: Show the 'sched_rr_timeslice' SCHED_RR timeslice tuning knob in milliseconds
      include/linux/sched/sysctl.h
      kernel/sched/core.c
      kernel/sched/rt.c
      kernel/sysctl.c
    crypto: af_alg - fix use-after-free in af_alg_accept() due to bh_lock_sock()
  * kgdb: Avoid suspicious RCU usage warning
      kernel/debug/debug_core.c
    usb: usbtest: fix missing kfree(dev->buf) in usbtest_disconnect
  * mm/slub: fix stack overruns with SLUB_STATS
      mm/slub.c
  * mm/slub.c: fix corrupted freechain in deactivate_slab()
      mm/slub.c
    usbnet: smsc95xx: Fix use-after-free after removal
    EDAC/amd64: Read back the scrub rate PCI register on F15h
  * mm: fix swap cache node allocation mask
      mm/swap_state.c
    btrfs: fix data block group relocation failure due to concurrent scrub
    btrfs: cow_file_range() num_bytes and disk_num_bytes are same
    btrfs: fix a block group ref counter leak after failure to remove block group
    Merge 4.9.229 into android-4.9-q
Linux 4.9.229
    Revert "tty: hvc: Fix data abort due to race in hvc_open"
    xfs: add agf freeblocks verify in xfs_agf_verify
    NFSv4 fix CLOSE not waiting for direct IO compeletion
    pNFS/flexfiles: Fix list corruption if the mirror count changes
    SUNRPC: Properly set the @subbuf parameter of xdr_buf_subsegment()
    sunrpc: fixed rollback in rpc_gssd_dummy_populate()
    drm/radeon: fix fb_div check in ni_init_smc_spll_table()
  * tracing: Fix event trigger to accept redundant spaces
      kernel/trace/trace_events_trigger.c
  * arm64: perf: Report the PC value in REGS_ABI_32 mode
      arch/arm64/kernel/perf_regs.c
    ocfs2: fix panic on nfs server over ocfs2
    ocfs2: fix value of OCFS2_INVALID_SLOT
    ocfs2: load global_inode_alloc
  * mm/slab: use memzero_explicit() in kzfree()
      mm/slab_common.c
    KVM: X86: Fix MSR range of APIC registers in X2APIC mode
    ACPI: sysfs: Fix pm_profile_attr type
    ALSA: hda: Add NVIDIA codec IDs 9a & 9d through a0 to patch table
  * blktrace: break out of blktrace setup on concurrent calls
      kernel/trace/blktrace.c
  * kbuild: improve cc-option to clean up all temporary files
      scripts/Kbuild.include
    s390/ptrace: fix setting syscall number
    net: alx: fix race condition in alx_remove
    ata/libata: Fix usage of page address by page_address in ata_scsi_mode_select_xlat function
  * sched/core: Fix PI boosting between RT and DEADLINE tasks
      kernel/sched/core.c
    netfilter: ipset: fix unaligned atomic access
    usb: gadget: udc: Potential Oops in error handling code
    ARM: imx5: add missing put_device() call in imx_suspend_alloc_ocram()
    net: qed: fix excessive QM ILT lines consumption
    net: qed: fix NVMe login fails over VFs
    net: qed: fix left elements count calculation
    RDMA/mad: Fix possible memory leak in ib_mad_post_receive_mads()
    efi/esrt: Fix reference count leak in esre_create_sysfs_entry.
    cifs/smb3: Fix data inconsistent when zero file range
    cifs/smb3: Fix data inconsistent when punch hole
  * xhci: Poll for U0 after disabling USB2 LPM
      drivers/usb/host/xhci.c
  * ALSA: usb-audio: Fix OOB access of mixer element list
      sound/usb/mixer.c
      sound/usb/mixer.h
      sound/usb/mixer_quirks.c
  * ALSA: usb-audio: Clean up mixer element list traverse
      sound/usb/mixer.c
      sound/usb/mixer.h
      sound/usb/mixer_quirks.c
      sound/usb/mixer_scarlett.c
  * ALSA: usb-audio: uac1: Invalidate ctl on interrupt
      sound/usb/mixer.c
    cdc-acm: Add DISABLE_ECHO quirk for Microchip/SMSC chip
  * xhci: Fix enumeration issue when setting max packet size for FS devices.
      drivers/usb/host/xhci.c
  * xhci: Fix incorrect EP_STATE_MASK
      drivers/usb/host/xhci.h
  * ALSA: usb-audio: add quirk for Denon DCD-1500RE
      sound/usb/quirks.c
    usb: host: ehci-exynos: Fix error check in exynos_ehci_probe()
    USB: ehci: reopen solution for Synopsys HC bug
  * usb: add USB_QUIRK_DELAY_INIT for Logitech C922
      drivers/usb/core/quirks.c
    usb: dwc2: Postponed gadget registration to the udc class driver
    USB: ohci-sm501: Add missed iounmap() in remove
  * net: core: reduce recursion limit value
      include/linux/netdevice.h
  * net: Do not clear the sock TX queue in sk_set_socket()
      include/net/sock.h
      net/core/sock.c
  * net: Fix the arp error in some cases
      net/ipv4/fib_semantics.c
  * sctp: Don't advertise IPv4 addresses if ipv6only is set on the socket
      include/net/sctp/constants.h
  * tcp: grow window for OOO packets only for SACK flows
      net/ipv4/tcp_input.c
    ip6_gre: fix use-after-free in ip6gre_tunnel_lookup()
  * tcp_cubic: fix spurious HYSTART_DELAY exit upon drop in min RTT
      net/ipv4/tcp_cubic.c
  * ip_tunnel: fix use-after-free in ip_tunnel_lookup()
      net/ipv4/ip_tunnel.c
    tg3: driver sleeps indefinitely when EEH errors exceed eeh_max_freezes
    rxrpc: Fix notification call on completion of discarded calls
    rocker: fix incorrect error handling in dma_rings_init
  * net: usb: ax88179_178a: fix packet alignment padding
      drivers/net/usb/ax88179_178a.c
  * net: fix memleak in register_netdevice()
      net/core/dev.c
  * mld: fix memory leak in ipv6_mc_destroy_dev()
      net/ipv6/mcast.c
    fix a braino in "sparc32: fix register window handling in genregs32_[gs]et()"
  * net: sched: export __netdev_watchdog_up()
      net/sched/sch_generic.c
  * l2tp: Allow duplicate session creation with UDP
      net/l2tp/l2tp_core.c
  * scsi: scsi_devinfo: handle non-terminated strings
      drivers/scsi/scsi_devinfo.c
    mtd: rawnand: tmio: Fix the probe error path
    mtd: rawnand: mtk: Fix the probe error path
    mtd: rawnand: plat_nand: Fix the probe error path
    mtd: rawnand: socrates: Fix the probe error path
    mtd: rawnand: orion: Fix the probe error path
    mtd: rawnand: xway: Fix the probe error path
    mtd: rawnand: sharpsl: Fix the probe error path
    mtd: rawnand: diskonchip: Fix the probe error path
    mtd: rawnand: Pass a nand_chip object to nand_release()
  * media: dvb_frontend: fix return error code
      drivers/media/dvb-core/dvb_frontend.c
  * media: dvb_frontend: fix wrong cast in compat_ioctl
      drivers/media/dvb-core/dvb_frontend.c
  * media: dvb_frontend: Add commands implementation for compat ioct
      drivers/media/dvb-core/dvb_frontend.c
  * media: dvb_frontend: Add compat_ioctl callback
      drivers/media/dvb-core/dvb_frontend.c
      fs/compat_ioctl.c
  * media: dvb_frontend: Add unlocked_ioctl in dvb_frontend.c
      drivers/media/dvb-core/dvb_frontend.c
  * media: dvb_frontend: be sure to init dvb_frontend_handle_ioctl() return code
      drivers/media/dvb-core/dvb_frontend.c
  * media: dvb_frontend: dtv_property_process_set() cleanups
      drivers/media/dvb-core/dvb_frontend.c
  * media: dvb_frontend: fix return values for FE_SET_PROPERTY
      drivers/media/dvb-core/dvb_frontend.c
      include/uapi/linux/dvb/frontend.h
  * media: dvb_frontend: better document the -EPERM condition
      drivers/media/dvb-core/dvb_frontend.c
  * media: dvb_frontend: get rid of property cache's state
      drivers/media/dvb-core/dvb_frontend.c
      drivers/media/dvb-core/dvb_frontend.h
  * media: dvb_frontend: cleanup ioctl handling logic
      drivers/media/dvb-core/dvb_frontend.c
  * media: dvb_frontend: cleanup dvb_frontend_ioctl_properties()
      drivers/media/dvb-core/dvb_frontend.c
  * media: dvb_frontend: get rid of set_property() callback
      drivers/media/dvb-core/dvb_frontend.c
      drivers/media/dvb-core/dvb_frontend.h
    media: friio-fe: get rid of set_property()
    media: stv6110: get rid of a srate dead code
    media: stv0288: get rid of set_property boilerplate
  * media: dvb_frontend: get rid of get_property() callback
      drivers/media/dvb-core/dvb_frontend.c
      drivers/media/dvb-core/dvb_frontend.h
  * media: dvb/frontend.h: document the uAPI file
      include/uapi/linux/dvb/frontend.h
  * media: dvb/frontend.h: move out a private internal structure
      drivers/media/dvb-core/dvb_frontend.c
      include/uapi/linux/dvb/frontend.h
  * media: dvb_frontend: initialize variable s with FE_NONE instead of 0
      drivers/media/dvb-core/dvb_frontend.c
  * net: core: device_rename: Use rwsem instead of a seqcount
      net/core/dev.c
  * sched/rt, net: Use CONFIG_PREEMPTION.patch
      net/core/dev.c
    e1000e: Do not wake up the system via WOL if device wakeup is disabled
  * kretprobe: Prevent triggering kretprobe from within kprobe_flush_task
      include/linux/kprobes.h
    x86/kprobes: Avoid kretprobe recursion bug
    powerpc/kprobes: Fixes for kprobe_lookup_name() on BE
    kprobes: Fix to protect kick_kprobe_optimizer() by kprobe_mutex
  * crypto: algboss - don't wait during notifier callback
      crypto/algboss.c
    drm/i915: Whitelist context-local timestamp in the gen9 cmdparser
    s390: fix syscall_get_error for compat processes
  * block: nr_sects_write(): Disable preemption on seqcount write
      include/linux/genhd.h
    x86/boot/compressed: Relax sed symbol type regex for LLVM ld.lld
  * drm/dp_mst: Increase ACT retry timeout to 3s
      drivers/gpu/drm/drm_dp_mst_topology.c
  * ext4: fix partial cluster initialization when splitting extent
      fs/ext4/extents.c
  * selinux: fix double free
      security/selinux/ss/services.c
    drm/qxl: Use correct notify port address when creating cursor ring
  * drm/dp_mst: Reformat drm_dp_check_act_status() a bit
      drivers/gpu/drm/drm_dp_mst_topology.c
  * drm: encoder_slave: fix refcouting error for modules
      drivers/gpu/drm/drm_encoder_slave.c
    libata: Use per port sync for detach
  * block: Fix use-after-free in blkdev_get()
      fs/block_dev.c
    bcache: fix potential deadlock problem in btree_gc_coalesce
    perf report: Fix NULL pointer dereference in hists__fprintf_nr_sample_events()
    usb/ehci-platform: Set PM runtime as active on resume
  * usb/xhci-plat: Set PM runtime as active on resume
      drivers/usb/host/xhci-plat.c
    scsi: acornscsi: Fix an error handling path in acornscsi_probe()
    selftests/net: in timestamping, strncpy needs to preserve null byte
    selftests/vm/pkeys: fix alloc_random_pkey() to make it really random
  * elfnote: mark all .note sections SHF_ALLOC
      include/linux/elfnote.h
  * include/linux/bitops.h: avoid clang shift-count-overflow warnings
      include/linux/bitops.h
  * lib/zlib: remove outdated and incorrect pre-increment optimization
      lib/zlib_inflate/inffast.c
    crypto: omap-sham - add proper load balancing support for multicore
    pinctrl: imxl: Fix an error handling path in 'imx1_pinctrl_core_probe()'
    scsi: iscsi: Fix reference count leak in iscsi_boot_create_kobj
    gfs2: Allow lock_nolock mount to specify jid=X
    openrisc: Fix issue with argument clobbering for clone/fork
    ASoC: fsl_asrc_dma: Fix dma_chan leak when config DMA channel failed
    extcon: adc-jack: Fix an error handling path in 'adc_jack_probe()'
    NFSv4.1 fix rpc_call_done assignment for BIND_CONN_TO_SESSION
    net: sunrpc: Fix off-by-one issues in 'rpc_ntop6'
    clk: bcm2835: Fix return type of bcm2835_register_gate
  * usb: gadget: Fix issue with config_ep_by_speed function
      drivers/usb/gadget/composite.c
      include/linux/usb/composite.h
    usb: gadget: fix potential double-free in m66592_probe.
    usb: gadget: lpc32xx_udc: don't dereference ep pointer before null check
    USB: gadget: udc: s3c2410_udc: Remove pointless NULL check in s3c2410_udc_nuke
    usb: dwc2: gadget: move gadget resume after the core is in L0 state
    watchdog: da9062: No need to ping manually before setting timeout
    IB/cma: Fix ports memory leak in cma_configfs
    PCI/PTM: Inherit Switch Downstream Port PTM settings from Upstream Port
    powerpc/64s/pgtable: fix an undefined behaviour
    clk: samsung: exynos5433: Add IGNORE_UNUSED flag to sclk_i2s1
    tty: n_gsm: Fix bogus i++ in gsm_data_kick
    USB: host: ehci-mxc: Add error handling in ehci_mxc_drv_probe()
    drm/msm/mdp5: Fix mdp5_init error path for failed mdp5_kms allocation
    usb/ohci-platform: Fix a warning when hibernating
    vfio-pci: Mask cap zero
    powerpc/ps3: Fix kexec shutdown hang
    powerpc/pseries/ras: Fix FWNMI_VALID off by one
    tty: n_gsm: Fix waking up upper tty layer when room available
    tty: n_gsm: Fix SOF skipping
    clk: ti: composite: fix memory leak
    dlm: remove BUG() before panic()
    scsi: mpt3sas: Fix double free warnings
    power: supply: smb347-charger: IRQSTAT_D is volatile
    power: supply: lp8788: Fix an error handling path in 'lp8788_charger_probe()'
    PCI/ASPM: Allow ASPM on links to PCIe-to-PCI/PCI-X Bridges
    PCI: rcar: Fix incorrect programming of OB windows
  * drivers: base: Fix NULL pointer exception in __platform_driver_probe() if a driver developer is foolish
      drivers/base/platform.c
    serial: amba-pl011: Make sure we initialize the port.lock spinlock
    i2c: pxa: fix i2c_pxa_scream_blue_murder() debug output
    staging: sm750fb: add missing case while setting FB_VISUAL
    tty: hvc: Fix data abort due to race in hvc_open
    s390/qdio: put thinint indicator after early error
  * ALSA: usb-audio: Improve frames size computation
      sound/usb/card.h
      sound/usb/endpoint.c
      sound/usb/endpoint.h
      sound/usb/pcm.c
    scsi: ibmvscsi: Don't send host info in adapter info MAD after LPM
    scsi: sr: Fix sr_probe() missing deallocate of device minor
  * mksysmap: Fix the mismatch of '.L' symbols in System.map
      scripts/mksysmap
    yam: fix possible memory leak in yam_init_driver
    powerpc/crashkernel: Take "mem=" option into account
    nfsd: Fix svc_xprt refcnt leak when setup callback client failed
    powerpc/perf/hv-24x7: Fix inconsistent output values incase multiple hv-24x7 events run
    clk: clk-flexgen: fix clock-critical handling
    scsi: lpfc: Fix lpfc_nodelist leak when processing unsolicited event
    mfd: wm8994: Fix driver operation if loaded as modules
    vfio/pci: fix memory leaks in alloc_perm_bits()
    ps3disk: use the default segment boundary
    PCI: aardvark: Don't blindly enable ASPM L0s and don't write to read-only register
    usblp: poison URBs upon disconnect
    i2c: pxa: clear all master action bits in i2c_pxa_stop_message()
    iio: bmp280: fix compensation of humidity
    scsi: qla2xxx: Fix issue with adapter's stopping state
    ALSA: isa/wavefront: prevent out of bounds write in ioctl
    ARM: integrator: Add some Kconfig selections
    backlight: lp855x: Ensure regulators are disabled on probe failure
    clk: qcom: msm8916: Fix the address location of pll->config_reg
    iio: pressure: bmp280: Tolerate IRQ before registering
    i2c: piix4: Detect secondary SMBus controller on AMD AM4 chipsets
    clk: sunxi: Fix incorrect usage of round_down()
  * power: supply: bq24257_charger: Replace depends on REGMAP_I2C with select
      drivers/power/supply/Kconfig

Change-Id: I9fdac4691b013061a19d375293b7049b999830d0
Signed-off-by: lucaswei <lucaswei@google.com>
2020-08-11 20:25:36 +08:00

729 lines
18 KiB
C

/*
* Register map access API - debugfs
*
* Copyright 2011 Wolfson Microelectronics plc
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/list.h>
#include "internal.h"
struct regmap_debugfs_node {
struct regmap *map;
const char *name;
struct list_head link;
};
static struct dentry *regmap_debugfs_root;
static LIST_HEAD(regmap_debugfs_early_list);
static DEFINE_MUTEX(regmap_debugfs_early_lock);
/* Calculate the length of a fixed format */
static size_t regmap_calc_reg_len(int max_val)
{
return snprintf(NULL, 0, "%x", max_val);
}
static ssize_t regmap_name_read_file(struct file *file,
char __user *user_buf, size_t count,
loff_t *ppos)
{
struct regmap *map = file->private_data;
int ret;
char *buf;
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!buf)
return -ENOMEM;
ret = snprintf(buf, PAGE_SIZE, "%s\n", map->dev->driver->name);
if (ret < 0) {
kfree(buf);
return ret;
}
ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
kfree(buf);
return ret;
}
static const struct file_operations regmap_name_fops = {
.open = simple_open,
.read = regmap_name_read_file,
.llseek = default_llseek,
};
static void regmap_debugfs_free_dump_cache(struct regmap *map)
{
struct regmap_debugfs_off_cache *c;
while (!list_empty(&map->debugfs_off_cache)) {
c = list_first_entry(&map->debugfs_off_cache,
struct regmap_debugfs_off_cache,
list);
list_del(&c->list);
kfree(c);
}
}
static bool regmap_printable(struct regmap *map, unsigned int reg)
{
if (regmap_precious(map, reg))
return false;
if (!regmap_readable(map, reg) && !regmap_cached(map, reg))
return false;
return true;
}
/*
* Work out where the start offset maps into register numbers, bearing
* in mind that we suppress hidden registers.
*/
static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
unsigned int base,
loff_t from,
loff_t *pos)
{
struct regmap_debugfs_off_cache *c = NULL;
loff_t p = 0;
unsigned int i, ret;
unsigned int fpos_offset;
unsigned int reg_offset;
/* Suppress the cache if we're using a subrange */
if (base)
return base;
/*
* If we don't have a cache build one so we don't have to do a
* linear scan each time.
*/
mutex_lock(&map->cache_lock);
i = base;
if (list_empty(&map->debugfs_off_cache)) {
for (; i <= map->max_register; i += map->reg_stride) {
/* Skip unprinted registers, closing off cache entry */
if (!regmap_printable(map, i)) {
if (c) {
c->max = p - 1;
c->max_reg = i - map->reg_stride;
list_add_tail(&c->list,
&map->debugfs_off_cache);
c = NULL;
}
continue;
}
/* No cache entry? Start a new one */
if (!c) {
c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c) {
regmap_debugfs_free_dump_cache(map);
mutex_unlock(&map->cache_lock);
return base;
}
c->min = p;
c->base_reg = i;
}
p += map->debugfs_tot_len;
}
}
/* Close the last entry off if we didn't scan beyond it */
if (c) {
c->max = p - 1;
c->max_reg = i - map->reg_stride;
list_add_tail(&c->list,
&map->debugfs_off_cache);
}
/*
* This should never happen; we return above if we fail to
* allocate and we should never be in this code if there are
* no registers at all.
*/
WARN_ON(list_empty(&map->debugfs_off_cache));
ret = base;
/* Find the relevant block:offset */
list_for_each_entry(c, &map->debugfs_off_cache, list) {
if (from >= c->min && from <= c->max) {
fpos_offset = from - c->min;
reg_offset = fpos_offset / map->debugfs_tot_len;
*pos = c->min + (reg_offset * map->debugfs_tot_len);
mutex_unlock(&map->cache_lock);
return c->base_reg + (reg_offset * map->reg_stride);
}
*pos = c->max;
ret = c->max_reg;
}
mutex_unlock(&map->cache_lock);
return ret;
}
static inline void regmap_calc_tot_len(struct regmap *map,
void *buf, size_t count)
{
/* Calculate the length of a fixed format */
if (!map->debugfs_tot_len) {
map->debugfs_reg_len = regmap_calc_reg_len(map->max_register),
map->debugfs_val_len = 2 * map->format.val_bytes;
map->debugfs_tot_len = map->debugfs_reg_len +
map->debugfs_val_len + 3; /* : \n */
}
}
static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from,
unsigned int to, char __user *user_buf,
size_t count, loff_t *ppos)
{
size_t buf_pos = 0;
loff_t p = *ppos;
ssize_t ret;
int i;
char *buf;
unsigned int val, start_reg;
if (*ppos < 0 || !count)
return -EINVAL;
if (count > (PAGE_SIZE << (MAX_ORDER - 1)))
count = PAGE_SIZE << (MAX_ORDER - 1);
buf = kmalloc(count, GFP_KERNEL);
if (!buf)
return -ENOMEM;
regmap_calc_tot_len(map, buf, count);
/* Work out which register we're starting at */
start_reg = regmap_debugfs_get_dump_start(map, from, *ppos, &p);
for (i = start_reg; i <= to; i += map->reg_stride) {
if (!regmap_readable(map, i) && !regmap_cached(map, i))
continue;
if (regmap_precious(map, i))
continue;
/* If we're in the region the user is trying to read */
if (p >= *ppos) {
/* ...but not beyond it */
if (buf_pos + map->debugfs_tot_len > count)
break;
/* Format the register */
snprintf(buf + buf_pos, count - buf_pos, "%.*x: ",
map->debugfs_reg_len, i - from);
buf_pos += map->debugfs_reg_len + 2;
/* Format the value, write all X if we can't read */
ret = regmap_read(map, i, &val);
if (ret == 0)
snprintf(buf + buf_pos, count - buf_pos,
"%.*x", map->debugfs_val_len, val);
else
memset(buf + buf_pos, 'X',
map->debugfs_val_len);
buf_pos += 2 * map->format.val_bytes;
buf[buf_pos++] = '\n';
}
p += map->debugfs_tot_len;
}
ret = buf_pos;
if (copy_to_user(user_buf, buf, buf_pos)) {
ret = -EFAULT;
goto out;
}
*ppos += buf_pos;
out:
kfree(buf);
return ret;
}
static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct regmap *map = file->private_data;
return regmap_read_debugfs(map, 0, map->max_register, user_buf,
count, ppos);
}
#ifdef CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS
/*
* This can be dangerous especially when we have clients such as
* PMICs, therefore don't provide any real compile time configuration option
* for this feature, people who want to use this will need to modify
* the source code directly.
*/
static ssize_t regmap_map_write_file(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
char buf[32];
size_t buf_size;
char *start = buf;
unsigned long reg, value;
struct regmap *map = file->private_data;
int ret;
buf_size = min(count, (sizeof(buf)-1));
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
buf[buf_size] = 0;
while (*start == ' ')
start++;
reg = simple_strtoul(start, &start, 16);
while (*start == ' ')
start++;
if (kstrtoul(start, 16, &value))
return -EINVAL;
/* Userspace has been fiddling around behind the kernel's back */
add_taint(TAINT_USER, LOCKDEP_STILL_OK);
ret = regmap_write(map, reg, value);
if (ret < 0)
return ret;
return buf_size;
}
#else
#define regmap_map_write_file NULL
#endif
static const struct file_operations regmap_map_fops = {
.open = simple_open,
.read = regmap_map_read_file,
.write = regmap_map_write_file,
.llseek = default_llseek,
};
static ssize_t regmap_data_read_file(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct regmap *map = file->private_data;
int new_count;
regmap_calc_tot_len(map, NULL, 0);
new_count = map->dump_count * map->debugfs_tot_len;
if (new_count > count)
new_count = count;
if (*ppos == 0)
*ppos = map->dump_address * map->debugfs_tot_len;
else if (*ppos >= map->dump_address * map->debugfs_tot_len
+ map->dump_count * map->debugfs_tot_len)
return 0;
return regmap_read_debugfs(map, 0, map->max_register, user_buf,
new_count, ppos);
}
#ifdef CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS
static ssize_t regmap_data_write_file(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
char buf[32];
size_t buf_size;
char *start = buf;
unsigned long value;
struct regmap *map = file->private_data;
int ret;
buf_size = min(count, (sizeof(buf)-1));
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
buf[buf_size] = 0;
while (*start == ' ')
start++;
if (kstrtoul(start, 16, &value))
return -EINVAL;
/* Userspace has been fiddling around behind the kernel's back */
add_taint(TAINT_USER, LOCKDEP_STILL_OK);
ret = regmap_write(map, map->dump_address, value);
if (ret < 0)
return ret;
return buf_size;
}
#else
#define regmap_data_write_file NULL
#endif
static const struct file_operations regmap_data_fops = {
.open = simple_open,
.read = regmap_data_read_file,
.write = regmap_data_write_file,
.llseek = default_llseek,
};
static ssize_t regmap_range_read_file(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct regmap_range_node *range = file->private_data;
struct regmap *map = range->map;
return regmap_read_debugfs(map, range->range_min, range->range_max,
user_buf, count, ppos);
}
static const struct file_operations regmap_range_fops = {
.open = simple_open,
.read = regmap_range_read_file,
.llseek = default_llseek,
};
static ssize_t regmap_reg_ranges_read_file(struct file *file,
char __user *user_buf, size_t count,
loff_t *ppos)
{
struct regmap *map = file->private_data;
struct regmap_debugfs_off_cache *c;
loff_t p = 0;
size_t buf_pos = 0;
char *buf;
char *entry;
int ret;
unsigned entry_len;
if (*ppos < 0 || !count)
return -EINVAL;
if (count > (PAGE_SIZE << (MAX_ORDER - 1)))
count = PAGE_SIZE << (MAX_ORDER - 1);
buf = kmalloc(count, GFP_KERNEL);
if (!buf)
return -ENOMEM;
entry = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!entry) {
kfree(buf);
return -ENOMEM;
}
/* While we are at it, build the register dump cache
* now so the read() operation on the `registers' file
* can benefit from using the cache. We do not care
* about the file position information that is contained
* in the cache, just about the actual register blocks */
regmap_calc_tot_len(map, buf, count);
regmap_debugfs_get_dump_start(map, 0, *ppos, &p);
/* Reset file pointer as the fixed-format of the `registers'
* file is not compatible with the `range' file */
p = 0;
mutex_lock(&map->cache_lock);
list_for_each_entry(c, &map->debugfs_off_cache, list) {
entry_len = snprintf(entry, PAGE_SIZE, "%x-%x\n",
c->base_reg, c->max_reg);
if (p >= *ppos) {
if (buf_pos + entry_len > count)
break;
memcpy(buf + buf_pos, entry, entry_len);
buf_pos += entry_len;
}
p += entry_len;
}
mutex_unlock(&map->cache_lock);
kfree(entry);
ret = buf_pos;
if (copy_to_user(user_buf, buf, buf_pos)) {
ret = -EFAULT;
goto out_buf;
}
*ppos += buf_pos;
out_buf:
kfree(buf);
return ret;
}
static const struct file_operations regmap_reg_ranges_fops = {
.open = simple_open,
.read = regmap_reg_ranges_read_file,
.llseek = default_llseek,
};
static int regmap_access_show(struct seq_file *s, void *ignored)
{
struct regmap *map = s->private;
int i, reg_len;
reg_len = regmap_calc_reg_len(map->max_register);
for (i = 0; i <= map->max_register; i += map->reg_stride) {
/* Ignore registers which are neither readable nor writable */
if (!regmap_readable(map, i) && !regmap_writeable(map, i))
continue;
/* Format the register */
seq_printf(s, "%.*x: %c %c %c %c\n", reg_len, i,
regmap_readable(map, i) ? 'y' : 'n',
regmap_writeable(map, i) ? 'y' : 'n',
regmap_volatile(map, i) ? 'y' : 'n',
regmap_precious(map, i) ? 'y' : 'n');
}
return 0;
}
static int access_open(struct inode *inode, struct file *file)
{
return single_open(file, regmap_access_show, inode->i_private);
}
static const struct file_operations regmap_access_fops = {
.open = access_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static ssize_t regmap_cache_only_write_file(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct regmap *map = container_of(file->private_data,
struct regmap, cache_only);
ssize_t result;
bool was_enabled, require_sync = false;
int err;
map->lock(map->lock_arg);
was_enabled = map->cache_only;
result = debugfs_write_file_bool(file, user_buf, count, ppos);
if (result < 0) {
map->unlock(map->lock_arg);
return result;
}
if (map->cache_only && !was_enabled) {
dev_warn(map->dev, "debugfs cache_only=Y forced\n");
add_taint(TAINT_USER, LOCKDEP_STILL_OK);
} else if (!map->cache_only && was_enabled) {
dev_warn(map->dev, "debugfs cache_only=N forced: syncing cache\n");
require_sync = true;
}
map->unlock(map->lock_arg);
if (require_sync) {
err = regcache_sync(map);
if (err)
dev_err(map->dev, "Failed to sync cache %d\n", err);
}
return result;
}
static const struct file_operations regmap_cache_only_fops = {
.open = simple_open,
.read = debugfs_read_file_bool,
.write = regmap_cache_only_write_file,
};
static ssize_t regmap_cache_bypass_write_file(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct regmap *map = container_of(file->private_data,
struct regmap, cache_bypass);
ssize_t result;
bool was_enabled;
map->lock(map->lock_arg);
was_enabled = map->cache_bypass;
result = debugfs_write_file_bool(file, user_buf, count, ppos);
if (result < 0)
goto out;
if (map->cache_bypass && !was_enabled) {
dev_warn(map->dev, "debugfs cache_bypass=Y forced\n");
add_taint(TAINT_USER, LOCKDEP_STILL_OK);
} else if (!map->cache_bypass && was_enabled) {
dev_warn(map->dev, "debugfs cache_bypass=N forced\n");
}
out:
map->unlock(map->lock_arg);
return result;
}
static const struct file_operations regmap_cache_bypass_fops = {
.open = simple_open,
.read = debugfs_read_file_bool,
.write = regmap_cache_bypass_write_file,
};
void regmap_debugfs_init(struct regmap *map, const char *name)
{
struct rb_node *next;
struct regmap_range_node *range_node;
const char *devname = "dummy";
/* If we don't have the debugfs root yet, postpone init */
if (!regmap_debugfs_root) {
struct regmap_debugfs_node *node;
node = kzalloc(sizeof(*node), GFP_KERNEL);
if (!node)
return;
node->map = map;
node->name = name;
mutex_lock(&regmap_debugfs_early_lock);
list_add(&node->link, &regmap_debugfs_early_list);
mutex_unlock(&regmap_debugfs_early_lock);
return;
}
INIT_LIST_HEAD(&map->debugfs_off_cache);
mutex_init(&map->cache_lock);
if (map->dev)
devname = dev_name(map->dev);
if (name) {
map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s",
devname, name);
name = map->debugfs_name;
} else {
name = devname;
}
map->debugfs = debugfs_create_dir(name, regmap_debugfs_root);
if (!map->debugfs) {
dev_warn(map->dev, "Failed to create debugfs directory\n");
return;
}
debugfs_create_file("name", 0400, map->debugfs,
map, &regmap_name_fops);
debugfs_create_file("range", 0400, map->debugfs,
map, &regmap_reg_ranges_fops);
if (map->max_register || regmap_readable(map, 0)) {
umode_t registers_mode;
#ifdef CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS
registers_mode = 0600;
#else
registers_mode = 0400;
#endif
debugfs_create_file("registers", registers_mode, map->debugfs,
map, &regmap_map_fops);
debugfs_create_x32("address", 0600, map->debugfs,
&map->dump_address);
map->dump_count = 1;
debugfs_create_u32("count", 0600, map->debugfs,
&map->dump_count);
debugfs_create_file("data", registers_mode, map->debugfs,
map, &regmap_data_fops);
debugfs_create_file("access", 0400, map->debugfs,
map, &regmap_access_fops);
}
if (map->cache_type) {
debugfs_create_file("cache_only", 0600, map->debugfs,
&map->cache_only, &regmap_cache_only_fops);
debugfs_create_bool("cache_dirty", 0400, map->debugfs,
&map->cache_dirty);
debugfs_create_file("cache_bypass", 0600, map->debugfs,
&map->cache_bypass,
&regmap_cache_bypass_fops);
}
next = rb_first(&map->range_tree);
while (next) {
range_node = rb_entry(next, struct regmap_range_node, node);
if (range_node->name)
debugfs_create_file(range_node->name, 0400,
map->debugfs, range_node,
&regmap_range_fops);
next = rb_next(&range_node->node);
}
if (map->cache_ops && map->cache_ops->debugfs_init)
map->cache_ops->debugfs_init(map);
}
void regmap_debugfs_exit(struct regmap *map)
{
if (map->debugfs) {
debugfs_remove_recursive(map->debugfs);
mutex_lock(&map->cache_lock);
regmap_debugfs_free_dump_cache(map);
mutex_unlock(&map->cache_lock);
kfree(map->debugfs_name);
} else {
struct regmap_debugfs_node *node, *tmp;
mutex_lock(&regmap_debugfs_early_lock);
list_for_each_entry_safe(node, tmp, &regmap_debugfs_early_list,
link) {
if (node->map == map) {
list_del(&node->link);
kfree(node);
}
}
mutex_unlock(&regmap_debugfs_early_lock);
}
}
void regmap_debugfs_initcall(void)
{
struct regmap_debugfs_node *node, *tmp;
regmap_debugfs_root = debugfs_create_dir("regmap", NULL);
if (!regmap_debugfs_root) {
pr_warn("regmap: Failed to create debugfs root\n");
return;
}
mutex_lock(&regmap_debugfs_early_lock);
list_for_each_entry_safe(node, tmp, &regmap_debugfs_early_list, link) {
regmap_debugfs_init(node->map, node->name);
list_del(&node->link);
kfree(node);
}
mutex_unlock(&regmap_debugfs_early_lock);
}