Linux Power Management development
 help / color / mirror / Atom feed
* [PATCH] power: supply: isp1704: remove redundant assignment to variable ret
From: Colin King @ 2019-07-05  9:36 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, linux-pm
  Cc: kernel-janitors, linux-kernel

From: Colin Ian King <colin.king@canonical.com>

The variable ret is being assigned with a value that is never
read and it is being updated later with a new value. The
assignment is redundant and can be removed.

Addresses-Coverity: ("Unused value")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
 drivers/power/supply/isp1704_charger.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/power/supply/isp1704_charger.c b/drivers/power/supply/isp1704_charger.c
index b48cb7aba97b..4812ac1ff2df 100644
--- a/drivers/power/supply/isp1704_charger.c
+++ b/drivers/power/supply/isp1704_charger.c
@@ -342,7 +342,7 @@ static inline int isp1704_test_ulpi(struct isp1704_charger *isp)
 	int vendor;
 	int product;
 	int i;
-	int ret = -ENODEV;
+	int ret;
 
 	/* Test ULPI interface */
 	ret = isp1704_write(isp, ULPI_SCRATCH, 0xaa);
-- 
2.20.1


^ permalink raw reply related

* Re: linux-next boot error: WARNING in corrupted
From: Rafael J. Wysocki @ 2019-07-05  9:23 UTC (permalink / raw)
  To: syzbot, Viresh Kumar
  Cc: gregkh, len.brown, linux-kernel, linux-pm, pavel, syzkaller-bugs
In-Reply-To: <0000000000005bf6c3058cde49a7@google.com>

On Thursday, July 4, 2019 7:27:04 PM CEST syzbot wrote:
> Hello,
> 
> syzbot found the following crash on:
> 
> HEAD commit:    16c474c9 Add linux-next specific files for 20190704
> git tree:       linux-next
> console output: https://syzkaller.appspot.com/x/log.txt?x=17f8b463a00000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=983f02aae1ef31b6
> dashboard link: https://syzkaller.appspot.com/bug?extid=de771ae9390dffed7266
> compiler:       gcc (GCC) 9.0.0 20181231 (experimental)
> 
> Unfortunately, I don't have any reproducer for this crash yet.
> 
> IMPORTANT: if you fix the bug, please add the following tag to the commit:
> Reported-by: syzbot+de771ae9390dffed7266@syzkaller.appspotmail.com
> 
> smpboot: CPU0: Intel(R) Xeon(R) CPU @ 2.30GHz (family: 0x6, model: 0x3f,  
> stepping: 0x0)
> Performance Events: unsupported p6 CPU model 63 no PMU driver, software  
> events only.
> rcu: Hierarchical SRCU implementation.
> NMI watchdog: Perf NMI watchdog permanently disabled
> smp: Bringing up secondary CPUs ...
> x86: Booting SMP configuration:
> .... node  #0, CPUs:      #1
> MDS CPU bug present and SMT on, data leak possible. See  
> https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html for  
> more details.
> smp: Brought up 2 nodes, 2 CPUs
> smpboot: Max logical packages: 1
> smpboot: Total of 2 processors activated (9200.00 BogoMIPS)
> devtmpfs: initialized
> clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns:  
> 19112604462750000 ns
> futex hash table entries: 512 (order: 4, 65536 bytes, vmalloc)
> xor: automatically using best checksumming function   avx
> PM: RTC time: 12:27:33, date: 2019-07-04
> NET: Registered protocol family 16
> audit: initializing netlink subsys (disabled)
> cpuidle: using governor menu
> ACPI: bus type PCI registered
> dca service started, version 1.12.1
> PCI: Using configuration type 1 for base access
> WARNING: workqueue cpumask: online intersect > possible intersect
> HugeTLB registered 1.00 GiB page size, pre-allocated 0 pages
> HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
> cryptd: max_cpu_qlen set to 1000
> raid6: avx2x4   gen() 12091 MB/s
> raid6: avx2x4   xor()  6705 MB/s
> raid6: avx2x2   gen()  7359 MB/s
> raid6: avx2x2   xor()  3820 MB/s
> raid6: avx2x1   gen()  3746 MB/s
> raid6: avx2x1   xor()  2047 MB/s
> raid6: sse2x4   gen()  6209 MB/s
> raid6: sse2x4   xor()  3539 MB/s
> raid6: sse2x2   gen()  3607 MB/s
> raid6: sse2x2   xor()  2014 MB/s
> raid6: sse2x1   gen()  1877 MB/s
> raid6: sse2x1   xor()  1038 MB/s
> raid6: using algorithm avx2x4 gen() 12091 MB/s
> raid6: .... xor() 6705 MB/s, rmw enabled
> raid6: using avx2x2 recovery algorithm
> ACPI: Added _OSI(Module Device)
> ACPI: Added _OSI(Processor Device)
> ACPI: Added _OSI(3.0 _SCP Extensions)
> ACPI: Added _OSI(Processor Aggregator Device)
> ACPI: Added _OSI(Linux-Dell-Video)
> ACPI: Added _OSI(Linux-Lenovo-NV-HDMI-Audio)
> ACPI: Added _OSI(Linux-HPI-Hybrid-Graphics)
> ACPI: 2 ACPI AML tables successfully acquired and loaded
> ACPI: Interpreter enabled
> ACPI: (supports S0 S3 S4 S5)
> ACPI: Using IOAPIC for interrupt routing
> PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and  
> report a bug
> ACPI: Enabled 16 GPEs in block 00 to 0F
> ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
> acpi PNP0A03:00: _OSC: OS supports [ASPM ClockPM Segments MSI HPX-Type3]
> acpi PNP0A03:00: fail to add MMCONFIG information, can't access extended  
> PCI configuration space under this bridge.
> PCI host bridge to bus 0000:00
> pci_bus 0000:00: root bus resource [io  0x0000-0x0cf7 window]
> pci_bus 0000:00: root bus resource [io  0x0d00-0xffff window]
> pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff window]
> pci_bus 0000:00: root bus resource [mem 0xc0000000-0xfebfffff window]
> pci_bus 0000:00: root bus resource [bus 00-ff]
> pci 0000:00:00.0: [8086:1237] type 00 class 0x060000
> pci 0000:00:01.0: [8086:7110] type 00 class 0x060100
> pci 0000:00:01.3: [8086:7113] type 00 class 0x068000
> pci 0000:00:01.3: quirk: [io  0xb000-0xb03f] claimed by PIIX4 ACPI
> pci 0000:00:03.0: [1af4:1004] type 00 class 0x000000
> pci 0000:00:03.0: reg 0x10: [io  0xc000-0xc03f]
> pci 0000:00:03.0: reg 0x14: [mem 0xfebfe000-0xfebfe07f]
> pci 0000:00:04.0: [1af4:1000] type 00 class 0x020000
> pci 0000:00:04.0: reg 0x10: [io  0xc040-0xc07f]
> pci 0000:00:04.0: reg 0x14: [mem 0xfebff000-0xfebff07f]
> ACPI: PCI Interrupt Link [LNKA] (IRQs 5 *10 11)
> ACPI: PCI Interrupt Link [LNKB] (IRQs 5 *10 11)
> ACPI: PCI Interrupt Link [LNKC] (IRQs 5 10 *11)
> ACPI: PCI Interrupt Link [LNKD] (IRQs 5 10 *11)
> ACPI: PCI Interrupt Link [LNKS] (IRQs *9)
> vgaarb: loaded
> SCSI subsystem initialized
> ACPI: bus type USB registered
> usbcore: registered new interface driver usbfs
> usbcore: registered new interface driver hub
> usbcore: registered new device driver usb
> mc: Linux media interface: v0.10
> videodev: Linux video capture interface: v2.00
> pps_core: LinuxPPS API ver. 1 registered
> pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti  
> <giometti@linux.it>
> PTP clock support registered
> EDAC MC: Ver: 3.0.0
> Advanced Linux Sound Architecture Driver Initialized.
> PCI: Using ACPI for IRQ routing
> Bluetooth: Core ver 2.22
> NET: Registered protocol family 31
> Bluetooth: HCI device and connection manager initialized
> Bluetooth: HCI socket layer initialized
> Bluetooth: L2CAP socket layer initialized
> Bluetooth: SCO socket layer initialized
> NET: Registered protocol family 8
> NET: Registered protocol family 20
> NetLabel: Initializing
> NetLabel:  domain hash size = 128
> NetLabel:  protocols = UNLABELED CIPSOv4 CALIPSO
> NetLabel:  unlabeled traffic allowed by default
> nfc: nfc_init: NFC Core ver 0.1
> NET: Registered protocol family 39
> clocksource: Switched to clocksource kvm-clock
> VFS: Disk quotas dquot_6.6.0
> VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
> FS-Cache: Loaded
> *** VALIDATE hugetlbfs ***
> CacheFiles: Loaded
> TOMOYO: 2.6.0
> Mandatory Access Control activated.
> AppArmor: AppArmor Filesystem Enabled
> pnp: PnP ACPI init
> pnp: PnP ACPI: found 7 devices
> thermal_sys: Registered thermal governor 'step_wise'
> thermal_sys: Registered thermal governor 'user_space'
> clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns:  
> 2085701024 ns
> pci_bus 0000:00: resource 4 [io  0x0000-0x0cf7 window]
> pci_bus 0000:00: resource 5 [io  0x0d00-0xffff window]
> pci_bus 0000:00: resource 6 [mem 0x000a0000-0x000bffff window]
> pci_bus 0000:00: resource 7 [mem 0xc0000000-0xfebfffff window]
> NET: Registered protocol family 2
> tcp_listen_portaddr_hash hash table entries: 4096 (order: 6, 294912 bytes,  
> vmalloc)
> TCP established hash table entries: 65536 (order: 7, 524288 bytes, vmalloc)
> TCP bind hash table entries: 65536 (order: 10, 4194304 bytes, vmalloc)
> TCP: Hash tables configured (established 65536 bind 65536)
> UDP hash table entries: 4096 (order: 7, 655360 bytes, vmalloc)
> UDP-Lite hash table entries: 4096 (order: 7, 655360 bytes, vmalloc)
> NET: Registered protocol family 1
> RPC: Registered named UNIX socket transport module.
> RPC: Registered udp transport module.
> RPC: Registered tcp transport module.
> RPC: Registered tcp NFSv4.1 backchannel transport module.
> NET: Registered protocol family 44
> pci 0000:00:00.0: Limiting direct PCI/PCI transfers
> PCI: CLS 0 bytes, default 64
> PCI-DMA: Using software bounce buffering for IO (SWIOTLB)
> software IO TLB: mapped [mem 0xaa800000-0xae800000] (64MB)
> RAPL PMU: API unit is 2^-32 Joules, 0 fixed counters, 10737418240 ms ovfl  
> timer
> kvm: already loaded the other module
> clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x212735223b2,  
> max_idle_ns: 440795277976 ns
> clocksource: Switched to clocksource tsc
> mce: Machine check injector initialized
> check: Scanning for low memory corruption every 60 seconds
> Initialise system trusted keyrings
> workingset: timestamp_bits=40 max_order=21 bucket_order=0
> zbud: loaded
> DLM installed
> squashfs: version 4.0 (2009/01/31) Phillip Lougher
> FS-Cache: Netfs 'nfs' registered for caching
> NFS: Registering the id_resolver key type
> Key type id_resolver registered
> Key type id_legacy registered
> nfs4filelayout_init: NFSv4 File Layout Driver Registering...
> Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
> ntfs: driver 2.1.32 [Flags: R/W].
> fuse: init (API version 7.31)
> JFS: nTxBlock = 8192, nTxLock = 65536
> SGI XFS with ACLs, security attributes, realtime, no debug enabled
> 9p: Installing v9fs 9p2000 file system support
> FS-Cache: Netfs '9p' registered for caching
> gfs2: GFS2 installed
> FS-Cache: Netfs 'ceph' registered for caching
> ceph: loaded (mds proto 32)
> NET: Registered protocol family 38
> async_tx: api initialized (async)
> Key type asymmetric registered
> Asymmetric key parser 'x509' registered
> Asymmetric key parser 'pkcs8' registered
> Key type pkcs7_test registered
> Asymmetric key parser 'tpm_parser' registered
> Block layer SCSI generic (bsg) driver version 0.4 loaded (major 246)
> io scheduler mq-deadline registered
> io scheduler kyber registered
> io scheduler bfq registered
> input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
> ACPI: Power Button [PWRF]
> input: Sleep Button as /devices/LNXSYSTM:00/LNXSLPBN:00/input/input1
> ACPI: Sleep Button [SLPF]
> ioatdma: Intel(R) QuickData Technology Driver 5.00
> PCI Interrupt Link [LNKC] enabled at IRQ 11
> virtio-pci 0000:00:03.0: virtio_pci: leaving for legacy driver
> PCI Interrupt Link [LNKD] enabled at IRQ 10
> virtio-pci 0000:00:04.0: virtio_pci: leaving for legacy driver
> HDLC line discipline maxframe=4096
> N_HDLC line discipline registered.
> Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
> 00:03: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
> 00:04: ttyS1 at I/O 0x2f8 (irq = 3, base_baud = 115200) is a 16550A
> 00:05: ttyS2 at I/O 0x3e8 (irq = 6, base_baud = 115200) is a 16550A
> 00:06: ttyS3 at I/O 0x2e8 (irq = 7, base_baud = 115200) is a 16550A
> Non-volatile memory driver v1.3
> Linux agpgart interface v0.103
> [drm] Initialized vgem 1.0.0 20120112 for vgem on minor 0
> [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
> [drm] Driver supports precise vblank timestamp query.
> [drm] Initialized vkms 1.0.0 20180514 for vkms on minor 1
> usbcore: registered new interface driver udl
> brd: module loaded
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> loop: module loaded
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> debugfs: File 'sched' already present!
> zram: Added device: zram0
> debugfs: File 'sched' already present!
> null: module loaded
> nfcsim 0.2 initialized
> Loading iSCSI transport class v2.0-870.
> scsi host0: Virtio SCSI HBA
> st: Version 20160209, fixed bufsize 32768, s/g segs 256
> slram: not enough parameters.
> ftl_cs: FTL header not found.
> debugfs: File 'sched' already present!
> Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)
> eql: Equalizer2002: Simon Janes (simon@ncm.com) and David S. Miller  
> (davem@redhat.com)
> MACsec IEEE 802.1AE
> tun: Universal TUN/TAP device driver, 1.6
> vcan: Virtual CAN interface driver
> vxcan: Virtual CAN Tunnel driver
> slcan: serial line CAN interface driver
> slcan: 10 dynamic interface channels.
> CAN device driver interface
> enic: Cisco VIC Ethernet NIC Driver, ver 2.3.0.53
> e100: Intel(R) PRO/100 Network Driver, 3.5.24-k2-NAPI
> e100: Copyright(c) 1999-2006 Intel Corporation
> e1000: Intel(R) PRO/1000 Network Driver - version 7.3.21-k8-NAPI
> e1000: Copyright (c) 1999-2006 Intel Corporation.
> e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
> e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
> mkiss: AX.25 Multikiss, Hans Albas PE1AYX
> AX.25: 6pack driver, Revision: 0.3.0
> AX.25: bpqether driver version 004
> PPP generic driver version 2.4.2
> PPP BSD Compression module registered
> PPP Deflate Compression module registered
> PPP MPPE Compression module registered
> NET: Registered protocol family 24
> PPTP driver version 0.8.5
> SLIP: version 0.8.4-NET3.019-NEWTTY (dynamic channels, max=256) (6 bit  
> encapsulation enabled).
> CSLIP: code copyright 1989 Regents of the University of California.
> SLIP linefill/keepalive option.
> hdlc: HDLC support module revision 1.22
> x25_asy: X.25 async: version 0.00 ALPHA (dynamic channels, max=256)
> DLCI driver v0.35, 4 Jan 1997, mike.mclagan@linux.org.
> LAPB Ethernet driver version 0.02
> usbcore: registered new interface driver rndis_wlan
> mac80211_hwsim: initializing netlink
> mac802154_hwsim mac802154_hwsim: Added 2 mac802154 hwsim hardware radios
> VMware vmxnet3 virtual NIC driver - version 1.4.17.0-k-NAPI
> pegasus: v0.9.3 (2013/04/25), Pegasus/Pegasus II USB Ethernet driver
> usbcore: registered new interface driver pegasus
> usbcore: registered new interface driver rtl8150
> usbcore: registered new interface driver r8152
> usbcore: registered new interface driver asix
> usbcore: registered new interface driver ax88179_178a
> usbcore: registered new interface driver cdc_ether
> usbcore: registered new interface driver dm9601
> usbcore: registered new interface driver smsc75xx
> usbcore: registered new interface driver smsc95xx
> usbcore: registered new interface driver net1080
> usbcore: registered new interface driver rndis_host
> usbcore: registered new interface driver cdc_subset
> usbcore: registered new interface driver zaurus
> usbcore: registered new interface driver MOSCHIP usb-ethernet driver
> usbcore: registered new interface driver cdc_ncm
> usbcore: registered new interface driver cdc_mbim
> VFIO - User Level meta-driver version: 0.3
> aoe: AoE v85 initialised.
> ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
> ehci-pci: EHCI PCI platform driver
> ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
> ohci-pci: OHCI PCI platform driver
> uhci_hcd: USB Universal Host Controller Interface driver
> usbcore: registered new interface driver cdc_acm
> cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
> usbcore: registered new interface driver usblp
> usbcore: registered new interface driver cdc_wdm
> usbcore: registered new interface driver uas
> usbcore: registered new interface driver usb-storage
> usbcore: registered new interface driver ums-realtek
> usbcore: registered new interface driver usbserial_generic
> usbserial: USB Serial support registered for generic
> usbcore: registered new interface driver ch341
> usbserial: USB Serial support registered for ch341-uart
> usbcore: registered new interface driver cp210x
> usbserial: USB Serial support registered for cp210x
> usbcore: registered new interface driver ftdi_sio
> usbserial: USB Serial support registered for FTDI USB Serial Device
> usbcore: registered new interface driver keyspan
> usbserial: USB Serial support registered for Keyspan - (without firmware)
> usbserial: USB Serial support registered for Keyspan 1 port adapter
> usbserial: USB Serial support registered for Keyspan 2 port adapter
> usbserial: USB Serial support registered for Keyspan 4 port adapter
> usbcore: registered new interface driver option
> usbserial: USB Serial support registered for GSM modem (1-port)
> usbcore: registered new interface driver oti6858
> usbserial: USB Serial support registered for oti6858
> usbcore: registered new interface driver pl2303
> usbserial: USB Serial support registered for pl2303
> usbcore: registered new interface driver qcserial
> usbserial: USB Serial support registered for Qualcomm USB modem
> usbcore: registered new interface driver sierra
> usbserial: USB Serial support registered for Sierra USB modem
> usbcore: registered new interface driver usb_serial_simple
> usbserial: USB Serial support registered for carelink
> usbserial: USB Serial support registered for zio
> usbserial: USB Serial support registered for funsoft
> usbserial: USB Serial support registered for flashloader
> usbserial: USB Serial support registered for google
> usbserial: USB Serial support registered for libtransistor
> usbserial: USB Serial support registered for vivopay
> usbserial: USB Serial support registered for moto_modem
> usbserial: USB Serial support registered for motorola_tetra
> usbserial: USB Serial support registered for novatel_gps
> usbserial: USB Serial support registered for hp4x
> usbserial: USB Serial support registered for suunto
> usbserial: USB Serial support registered for siemens_mpi
> udc-core: couldn't find an available UDC - added [g_multi] to list of  
> pending drivers
> vhci_hcd vhci_hcd.0: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.0: new USB bus registered, assigned bus number 1
> vhci_hcd: created sysfs vhci_hcd.0
> usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb1: Product: USB/IP Virtual Host Controller
> usb usb1: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb1: SerialNumber: vhci_hcd.0
> hub 1-0:1.0: USB hub found
> hub 1-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.0: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.0: new USB bus registered, assigned bus number 2
> usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
> usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb2: Product: USB/IP Virtual Host Controller
> usb usb2: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb2: SerialNumber: vhci_hcd.0
> hub 2-0:1.0: USB hub found
> hub 2-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.1: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.1: new USB bus registered, assigned bus number 3
> usb usb3: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb3: Product: USB/IP Virtual Host Controller
> usb usb3: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb3: SerialNumber: vhci_hcd.1
> hub 3-0:1.0: USB hub found
> hub 3-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.1: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.1: new USB bus registered, assigned bus number 4
> usb usb4: We don't know the algorithms for LPM for this host, disabling LPM.
> usb usb4: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb4: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb4: Product: USB/IP Virtual Host Controller
> usb usb4: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb4: SerialNumber: vhci_hcd.1
> hub 4-0:1.0: USB hub found
> hub 4-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.2: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.2: new USB bus registered, assigned bus number 5
> usb usb5: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb5: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb5: Product: USB/IP Virtual Host Controller
> usb usb5: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb5: SerialNumber: vhci_hcd.2
> hub 5-0:1.0: USB hub found
> hub 5-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.2: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.2: new USB bus registered, assigned bus number 6
> usb usb6: We don't know the algorithms for LPM for this host, disabling LPM.
> usb usb6: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb6: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb6: Product: USB/IP Virtual Host Controller
> usb usb6: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb6: SerialNumber: vhci_hcd.2
> hub 6-0:1.0: USB hub found
> hub 6-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.3: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.3: new USB bus registered, assigned bus number 7
> usb usb7: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb7: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb7: Product: USB/IP Virtual Host Controller
> usb usb7: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb7: SerialNumber: vhci_hcd.3
> hub 7-0:1.0: USB hub found
> hub 7-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.3: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.3: new USB bus registered, assigned bus number 8
> usb usb8: We don't know the algorithms for LPM for this host, disabling LPM.
> usb usb8: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb8: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb8: Product: USB/IP Virtual Host Controller
> usb usb8: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb8: SerialNumber: vhci_hcd.3
> hub 8-0:1.0: USB hub found
> hub 8-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.4: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.4: new USB bus registered, assigned bus number 9
> usb usb9: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb9: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb9: Product: USB/IP Virtual Host Controller
> usb usb9: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb9: SerialNumber: vhci_hcd.4
> hub 9-0:1.0: USB hub found
> hub 9-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.4: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.4: new USB bus registered, assigned bus number 10
> usb usb10: We don't know the algorithms for LPM for this host, disabling  
> LPM.
> usb usb10: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb10: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb10: Product: USB/IP Virtual Host Controller
> usb usb10: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb10: SerialNumber: vhci_hcd.4
> hub 10-0:1.0: USB hub found
> hub 10-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.5: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.5: new USB bus registered, assigned bus number 11
> usb usb11: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb11: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb11: Product: USB/IP Virtual Host Controller
> usb usb11: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb11: SerialNumber: vhci_hcd.5
> hub 11-0:1.0: USB hub found
> hub 11-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.5: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.5: new USB bus registered, assigned bus number 12
> usb usb12: We don't know the algorithms for LPM for this host, disabling  
> LPM.
> usb usb12: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb12: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb12: Product: USB/IP Virtual Host Controller
> usb usb12: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb12: SerialNumber: vhci_hcd.5
> hub 12-0:1.0: USB hub found
> hub 12-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.6: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.6: new USB bus registered, assigned bus number 13
> usb usb13: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb13: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb13: Product: USB/IP Virtual Host Controller
> usb usb13: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb13: SerialNumber: vhci_hcd.6
> hub 13-0:1.0: USB hub found
> hub 13-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.6: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.6: new USB bus registered, assigned bus number 14
> usb usb14: We don't know the algorithms for LPM for this host, disabling  
> LPM.
> usb usb14: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb14: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb14: Product: USB/IP Virtual Host Controller
> usb usb14: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb14: SerialNumber: vhci_hcd.6
> hub 14-0:1.0: USB hub found
> hub 14-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.7: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.7: new USB bus registered, assigned bus number 15
> usb usb15: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb15: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb15: Product: USB/IP Virtual Host Controller
> usb usb15: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb15: SerialNumber: vhci_hcd.7
> hub 15-0:1.0: USB hub found
> hub 15-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.7: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.7: new USB bus registered, assigned bus number 16
> usb usb16: We don't know the algorithms for LPM for this host, disabling  
> LPM.
> usb usb16: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb16: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb16: Product: USB/IP Virtual Host Controller
> usb usb16: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb16: SerialNumber: vhci_hcd.7
> hub 16-0:1.0: USB hub found
> hub 16-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.8: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.8: new USB bus registered, assigned bus number 17
> usb usb17: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb17: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb17: Product: USB/IP Virtual Host Controller
> usb usb17: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb17: SerialNumber: vhci_hcd.8
> hub 17-0:1.0: USB hub found
> hub 17-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.8: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.8: new USB bus registered, assigned bus number 18
> usb usb18: We don't know the algorithms for LPM for this host, disabling  
> LPM.
> usb usb18: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb18: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb18: Product: USB/IP Virtual Host Controller
> usb usb18: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb18: SerialNumber: vhci_hcd.8
> hub 18-0:1.0: USB hub found
> hub 18-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.9: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.9: new USB bus registered, assigned bus number 19
> usb usb19: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb19: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb19: Product: USB/IP Virtual Host Controller
> usb usb19: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb19: SerialNumber: vhci_hcd.9
> hub 19-0:1.0: USB hub found
> hub 19-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.9: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.9: new USB bus registered, assigned bus number 20
> usb usb20: We don't know the algorithms for LPM for this host, disabling  
> LPM.
> usb usb20: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb20: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb20: Product: USB/IP Virtual Host Controller
> usb usb20: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb20: SerialNumber: vhci_hcd.9
> hub 20-0:1.0: USB hub found
> hub 20-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.10: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.10: new USB bus registered, assigned bus number 21
> usb usb21: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb21: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb21: Product: USB/IP Virtual Host Controller
> usb usb21: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb21: SerialNumber: vhci_hcd.10
> hub 21-0:1.0: USB hub found
> hub 21-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.10: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.10: new USB bus registered, assigned bus number 22
> usb usb22: We don't know the algorithms for LPM for this host, disabling  
> LPM.
> usb usb22: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb22: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb22: Product: USB/IP Virtual Host Controller
> usb usb22: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb22: SerialNumber: vhci_hcd.10
> hub 22-0:1.0: USB hub found
> hub 22-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.11: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.11: new USB bus registered, assigned bus number 23
> usb usb23: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb23: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb23: Product: USB/IP Virtual Host Controller
> usb usb23: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb23: SerialNumber: vhci_hcd.11
> hub 23-0:1.0: USB hub found
> hub 23-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.11: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.11: new USB bus registered, assigned bus number 24
> usb usb24: We don't know the algorithms for LPM for this host, disabling  
> LPM.
> usb usb24: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb24: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb24: Product: USB/IP Virtual Host Controller
> usb usb24: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb24: SerialNumber: vhci_hcd.11
> hub 24-0:1.0: USB hub found
> hub 24-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.12: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.12: new USB bus registered, assigned bus number 25
> usb usb25: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb25: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb25: Product: USB/IP Virtual Host Controller
> usb usb25: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb25: SerialNumber: vhci_hcd.12
> hub 25-0:1.0: USB hub found
> hub 25-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.12: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.12: new USB bus registered, assigned bus number 26
> usb usb26: We don't know the algorithms for LPM for this host, disabling  
> LPM.
> usb usb26: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb26: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb26: Product: USB/IP Virtual Host Controller
> usb usb26: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb26: SerialNumber: vhci_hcd.12
> hub 26-0:1.0: USB hub found
> hub 26-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.13: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.13: new USB bus registered, assigned bus number 27
> usb usb27: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb27: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb27: Product: USB/IP Virtual Host Controller
> usb usb27: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb27: SerialNumber: vhci_hcd.13
> hub 27-0:1.0: USB hub found
> hub 27-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.13: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.13: new USB bus registered, assigned bus number 28
> usb usb28: We don't know the algorithms for LPM for this host, disabling  
> LPM.
> usb usb28: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb28: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb28: Product: USB/IP Virtual Host Controller
> usb usb28: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb28: SerialNumber: vhci_hcd.13
> hub 28-0:1.0: USB hub found
> hub 28-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.14: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.14: new USB bus registered, assigned bus number 29
> usb usb29: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb29: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb29: Product: USB/IP Virtual Host Controller
> usb usb29: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb29: SerialNumber: vhci_hcd.14
> hub 29-0:1.0: USB hub found
> hub 29-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.14: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.14: new USB bus registered, assigned bus number 30
> usb usb30: We don't know the algorithms for LPM for this host, disabling  
> LPM.
> usb usb30: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb30: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb30: Product: USB/IP Virtual Host Controller
> usb usb30: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb30: SerialNumber: vhci_hcd.14
> hub 30-0:1.0: USB hub found
> hub 30-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.15: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.15: new USB bus registered, assigned bus number 31
> usb usb31: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
> 5.02
> usb usb31: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb31: Product: USB/IP Virtual Host Controller
> usb usb31: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb31: SerialNumber: vhci_hcd.15
> hub 31-0:1.0: USB hub found
> hub 31-0:1.0: 8 ports detected
> vhci_hcd vhci_hcd.15: USB/IP Virtual Host Controller
> vhci_hcd vhci_hcd.15: new USB bus registered, assigned bus number 32
> usb usb32: We don't know the algorithms for LPM for this host, disabling  
> LPM.
> usb usb32: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
> 5.02
> usb usb32: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb32: Product: USB/IP Virtual Host Controller
> usb usb32: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
> usb usb32: SerialNumber: vhci_hcd.15
> hub 32-0:1.0: USB hub found
> hub 32-0:1.0: 8 ports detected
> usbcore: registered new device driver usbip-host
> using random self ethernet address
> using random host ethernet address
> Mass Storage Function, version: 2009/09/11
> LUN: removable file: (no medium)
> no file given for LUN0
> g_multi usbip-vudc.0: failed to start g_multi: -22
> usbip-vudc: probe of usbip-vudc.0 failed with error -22
> i8042: PNP: PS/2 Controller [PNP0303:KBD,PNP0f13:MOU] at 0x60,0x64 irq 1,12
> i8042: Warning: Keylock active
> serio: i8042 KBD port at 0x60,0x64 irq 1
> serio: i8042 AUX port at 0x60,0x64 irq 12
> mousedev: PS/2 mouse device common for all mice
> rtc_cmos 00:00: RTC can wake from S4
> rtc_cmos 00:00: registered as rtc0
> rtc_cmos 00:00: alarms up to one day, 114 bytes nvram
> i2c /dev entries driver
> piix4_smbus 0000:00:01.3: SMBus base address uninitialized - upgrade BIOS  
> or use force_addr=0xaddr
> i2c-parport-light: adapter type unspecified
> usbcore: registered new interface driver RobotFuzz Open Source InterFace,  
> OSIF
> usbcore: registered new interface driver i2c-tiny-usb
> IR NEC protocol handler initialized
> IR RC5(x/sz) protocol handler initialized
> IR RC6 protocol handler initialized
> IR JVC protocol handler initialized
> IR Sony protocol handler initialized
> IR SANYO protocol handler initialized
> IR Sharp protocol handler initialized
> IR MCE Keyboard/mouse protocol handler initialized
> IR XMP protocol handler initialized
> vimc vimc.0: bound vimc-sensor.0.auto (ops vimc_sen_comp_ops)
> vimc vimc.0: bound vimc-sensor.1.auto (ops vimc_sen_comp_ops)
> vimc vimc.0: bound vimc-debayer.2.auto (ops vimc_deb_comp_ops)
> vimc vimc.0: bound vimc-debayer.3.auto (ops vimc_deb_comp_ops)
> vimc vimc.0: bound vimc-capture.4.auto (ops vimc_cap_comp_ops)
> vimc vimc.0: bound vimc-capture.5.auto (ops vimc_cap_comp_ops)
> vimc vimc.0: bound vimc-sensor.6.auto (ops vimc_sen_comp_ops)
> vimc vimc.0: bound vimc-scaler.7.auto (ops vimc_sca_comp_ops)
> vimc vimc.0: bound vimc-capture.8.auto (ops vimc_cap_comp_ops)
> vivid-000: using single planar format API
> vivid-000: CEC adapter cec0 registered for HDMI input 0
> vivid-000: V4L2 capture device registered as video3
> vivid-000: CEC adapter cec1 registered for HDMI output 0
> vivid-000: V4L2 output device registered as video4
> vivid-000: V4L2 capture device registered as vbi0, supports raw and sliced  
> VBI
> vivid-000: V4L2 output device registered as vbi1, supports raw and sliced  
> VBI
> vivid-000: V4L2 capture device registered as swradio0
> vivid-000: V4L2 receiver device registered as radio0
> vivid-000: V4L2 transmitter device registered as radio1
> vivid-001: using multiplanar format API
> vivid-001: CEC adapter cec2 registered for HDMI input 0
> vivid-001: V4L2 capture device registered as video5
> vivid-001: CEC adapter cec3 registered for HDMI output 0
> vivid-001: V4L2 output device registered as video6
> vivid-001: V4L2 capture device registered as vbi2, supports raw and sliced  
> VBI
> vivid-001: V4L2 output device registered as vbi3, supports raw and sliced  
> VBI
> vivid-001: V4L2 capture device registered as swradio1
> vivid-001: V4L2 receiver device registered as radio2
> vivid-001: V4L2 transmitter device registered as radio3
> vivid-002: using single planar format API
> vivid-002: CEC adapter cec4 registered for HDMI input 0
> vivid-002: V4L2 capture device registered as video7
> vivid-002: CEC adapter cec5 registered for HDMI output 0
> vivid-002: V4L2 output device registered as video8
> vivid-002: V4L2 capture device registered as vbi4, supports raw and sliced  
> VBI
> vivid-002: V4L2 output device registered as vbi5, supports raw and sliced  
> VBI
> vivid-002: V4L2 capture device registered as swradio2
> vivid-002: V4L2 receiver device registered as radio4
> vivid-002: V4L2 transmitter device registered as radio5
> vivid-003: using multiplanar format API
> vivid-003: CEC adapter cec6 registered for HDMI input 0
> vivid-003: V4L2 capture device registered as video9
> vivid-003: CEC adapter cec7 registered for HDMI output 0
> vivid-003: V4L2 output device registered as video10
> vivid-003: V4L2 capture device registered as vbi6, supports raw and sliced  
> VBI
> vivid-003: V4L2 output device registered as vbi7, supports raw and sliced  
> VBI
> vivid-003: V4L2 capture device registered as swradio3
> vivid-003: V4L2 receiver device registered as radio6
> vivid-003: V4L2 transmitter device registered as radio7
> vivid-004: using single planar format API
> vivid-004: CEC adapter cec8 registered for HDMI input 0
> vivid-004: V4L2 capture device registered as video11
> vivid-004: CEC adapter cec9 registered for HDMI output 0
> vivid-004: V4L2 output device registered as video12
> vivid-004: V4L2 capture device registered as vbi8, supports raw and sliced  
> VBI
> vivid-004: V4L2 output device registered as vbi9, supports raw and sliced  
> VBI
> vivid-004: V4L2 capture device registered as swradio4
> vivid-004: V4L2 receiver device registered as radio8
> vivid-004: V4L2 transmitter device registered as radio9
> vivid-005: using multiplanar format API
> vivid-005: CEC adapter cec10 registered for HDMI input 0
> vivid-005: V4L2 capture device registered as video13
> vivid-005: CEC adapter cec11 registered for HDMI output 0
> vivid-005: V4L2 output device registered as video14
> vivid-005: V4L2 capture device registered as vbi10, supports raw and sliced  
> VBI
> vivid-005: V4L2 output device registered as vbi11, supports raw and sliced  
> VBI
> vivid-005: V4L2 capture device registered as swradio5
> vivid-005: V4L2 receiver device registered as radio10
> vivid-005: V4L2 transmitter device registered as radio11
> vivid-006: using single planar format API
> vivid-006: CEC adapter cec12 registered for HDMI input 0
> vivid-006: V4L2 capture device registered as video15
> vivid-006: CEC adapter cec13 registered for HDMI output 0
> vivid-006: V4L2 output device registered as video16
> vivid-006: V4L2 capture device registered as vbi12, supports raw and sliced  
> VBI
> vivid-006: V4L2 output device registered as vbi13, supports raw and sliced  
> VBI
> vivid-006: V4L2 capture device registered as swradio6
> vivid-006: V4L2 receiver device registered as radio12
> vivid-006: V4L2 transmitter device registered as radio13
> vivid-007: using multiplanar format API
> vivid-007: CEC adapter cec14 registered for HDMI input 0
> vivid-007: V4L2 capture device registered as video17
> vivid-007: CEC adapter cec15 registered for HDMI output 0
> vivid-007: V4L2 output device registered as video18
> vivid-007: V4L2 capture device registered as vbi14, supports raw and sliced  
> VBI
> vivid-007: V4L2 output device registered as vbi15, supports raw and sliced  
> VBI
> vivid-007: V4L2 capture device registered as swradio7
> vivid-007: V4L2 receiver device registered as radio14
> vivid-007: V4L2 transmitter device registered as radio15
> vivid-008: using single planar format API
> vivid-008: CEC adapter cec16 registered for HDMI input 0
> vivid-008: V4L2 capture device registered as video19
> vivid-008: CEC adapter cec17 registered for HDMI output 0
> vivid-008: V4L2 output device registered as video20
> vivid-008: V4L2 capture device registered as vbi16, supports raw and sliced  
> VBI
> vivid-008: V4L2 output device registered as vbi17, supports raw and sliced  
> VBI
> vivid-008: V4L2 capture device registered as swradio8
> vivid-008: V4L2 receiver device registered as radio16
> vivid-008: V4L2 transmitter device registered as radio17
> vivid-009: using multiplanar format API
> vivid-009: CEC adapter cec18 registered for HDMI input 0
> vivid-009: V4L2 capture device registered as video21
> vivid-009: CEC adapter cec19 registered for HDMI output 0
> vivid-009: V4L2 output device registered as video22
> vivid-009: V4L2 capture device registered as vbi18, supports raw and sliced  
> VBI
> vivid-009: V4L2 output device registered as vbi19, supports raw and sliced  
> VBI
> vivid-009: V4L2 capture device registered as swradio9
> vivid-009: V4L2 receiver device registered as radio18
> vivid-009: V4L2 transmitter device registered as radio19
> vivid-010: using single planar format API
> vivid-010: CEC adapter cec20 registered for HDMI input 0
> vivid-010: V4L2 capture device registered as video23
> vivid-010: CEC adapter cec21 registered for HDMI output 0
> vivid-010: V4L2 output device registered as video24
> vivid-010: V4L2 capture device registered as vbi20, supports raw and sliced  
> VBI
> vivid-010: V4L2 output device registered as vbi21, supports raw and sliced  
> VBI
> vivid-010: V4L2 capture device registered as swradio10
> vivid-010: V4L2 receiver device registered as radio20
> vivid-010: V4L2 transmitter device registered as radio21
> vivid-011: using multiplanar format API
> vivid-011: CEC adapter cec22 registered for HDMI input 0
> vivid-011: V4L2 capture device registered as video25
> vivid-011: CEC adapter cec23 registered for HDMI output 0
> vivid-011: V4L2 output device registered as video26
> vivid-011: V4L2 capture device registered as vbi22, supports raw and sliced  
> VBI
> vivid-011: V4L2 output device registered as vbi23, supports raw and sliced  
> VBI
> vivid-011: V4L2 capture device registered as swradio11
> vivid-011: V4L2 receiver device registered as radio22
> vivid-011: V4L2 transmitter device registered as radio23
> vivid-012: using single planar format API
> vivid-012: CEC adapter cec24 registered for HDMI input 0
> vivid-012: V4L2 capture device registered as video27
> vivid-012: CEC adapter cec25 registered for HDMI output 0
> vivid-012: V4L2 output device registered as video28
> vivid-012: V4L2 capture device registered as vbi24, supports raw and sliced  
> VBI
> vivid-012: V4L2 output device registered as vbi25, supports raw and sliced  
> VBI
> vivid-012: V4L2 capture device registered as swradio12
> vivid-012: V4L2 receiver device registered as radio24
> vivid-012: V4L2 transmitter device registered as radio25
> vivid-013: using multiplanar format API
> vivid-013: CEC adapter cec26 registered for HDMI input 0
> vivid-013: V4L2 capture device registered as video29
> vivid-013: CEC adapter cec27 registered for HDMI output 0
> vivid-013: V4L2 output device registered as video30
> vivid-013: V4L2 capture device registered as vbi26, supports raw and sliced  
> VBI
> vivid-013: V4L2 output device registered as vbi27, supports raw and sliced  
> VBI
> vivid-013: V4L2 capture device registered as swradio13
> vivid-013: V4L2 receiver device registered as radio26
> vivid-013: V4L2 transmitter device registered as radio27
> vivid-014: using single planar format API
> vivid-014: CEC adapter cec28 registered for HDMI input 0
> vivid-014: V4L2 capture device registered as video31
> vivid-014: CEC adapter cec29 registered for HDMI output 0
> vivid-014: V4L2 output device registered as video32
> vivid-014: V4L2 capture device registered as vbi28, supports raw and sliced  
> VBI
> vivid-014: V4L2 output device registered as vbi29, supports raw and sliced  
> VBI
> vivid-014: V4L2 capture device registered as swradio14
> vivid-014: V4L2 receiver device registered as radio28
> vivid-014: V4L2 transmitter device registered as radio29
> vivid-015: using multiplanar format API
> vivid-015: CEC adapter cec30 registered for HDMI input 0
> vivid-015: V4L2 capture device registered as video33
> vivid-015: CEC adapter cec31 registered for HDMI output 0
> vivid-015: V4L2 output device registered as video34
> vivid-015: V4L2 capture device registered as vbi30, supports raw and sliced  
> VBI
> vivid-015: V4L2 output device registered as vbi31, supports raw and sliced  
> VBI
> vivid-015: V4L2 capture device registered as swradio15
> vivid-015: V4L2 receiver device registered as radio30
> vivid-015: V4L2 transmitter device registered as radio31
> vim2m vim2m.0: Device registered as /dev/video35
> vicodec vicodec.0: Device 'stateful-encoder' registered as /dev/video36
> vicodec vicodec.0: Device 'stateful-decoder' registered as /dev/video37
> vicodec vicodec.0: Device 'stateless-decoder' registered as /dev/video38
> usbcore: registered new interface driver uvcvideo
> USB Video Class driver (1.1.1)
> gspca_main: v2.14.0 registered
> iTCO_wdt: Intel TCO WatchDog Timer Driver v1.11
> iTCO_vendor_support: vendor-support=0
> device-mapper: uevent: version 1.0.3
> device-mapper: ioctl: 4.40.0-ioctl (2019-01-18) initialised:  
> dm-devel@redhat.com
> device-mapper: multipath round-robin: version 1.2.0 loaded
> device-mapper: multipath queue-length: version 0.2.0 loaded
> device-mapper: multipath service-time: version 0.3.0 loaded
> device-mapper: raid: Loading target version 1.14.0
> Bluetooth: HCI UART driver ver 2.3
> Bluetooth: HCI UART protocol H4 registered
> Bluetooth: HCI UART protocol BCSP registered
> Bluetooth: HCI UART protocol LL registered
> Bluetooth: HCI UART protocol Three-wire (H5) registered
> Bluetooth: HCI UART protocol QCA registered
> Bluetooth: HCI UART protocol AG6XX registered
> Bluetooth: HCI UART protocol Marvell registered
> usbcore: registered new interface driver bfusb
> usbcore: registered new interface driver btusb
> CAPI 2.0 started up with major 68 (middleware)
> Modular ISDN core version 1.1.29
> NET: Registered protocol family 34
> DSP module 2.0
> mISDN_dsp: DSP clocks every 80 samples. This equals 1 jiffies.
> mISDN: Layer-1-over-IP driver Rev. 2.00
> 0 virtual devices registered
> intel_pstate: CPU model not supported
> usnic_verbs: Cisco VIC (USNIC) Verbs Driver v1.0.3 (December 19, 2013)
> usnic_verbs:usnic_uiom_init:566:
> IOMMU required but not present or enabled.  USNIC QPs will not function w/o  
> enabling IOMMU
> usnic_verbs:usnic_ib_init:661:
> Unable to initialize umem with err -1
> iscsi: registered transport (iser)
> OPA Virtual Network Driver - v1.0
> hidraw: raw HID events driver (C) Jiri Kosina
> usbcore: registered new interface driver usbhid
> usbhid: USB HID core driver
> NET: Registered protocol family 40
> ashmem: initialized
> erofs: initializing erofs 1.0pre1
> erofs: successfully to initialize erofs
> usbcore: registered new interface driver snd-usb-audio
> drop_monitor: Initializing network drop monitor service
> NET: Registered protocol family 26
> GACT probability on
> Mirror/redirect action on
> Simple TC action Loaded
> netem: version 1.3
> u32 classifier
>      Performance counters on
>      input device check on
>      Actions configured
> nf_conntrack_irc: failed to register helpers
> nf_conntrack_sane: failed to register helpers
> nf_conntrack_sip: failed to register helpers
> xt_time: kernel timezone is -0000
> IPVS: Registered protocols (TCP, UDP, SCTP, AH, ESP)
> IPVS: Connection hash table configured (size=4096, memory=64Kbytes)
> IPVS: ipvs loaded.
> IPVS: [rr] scheduler registered.
> IPVS: [wrr] scheduler registered.
> IPVS: [lc] scheduler registered.
> IPVS: [wlc] scheduler registered.
> IPVS: [fo] scheduler registered.
> IPVS: [ovf] scheduler registered.
> IPVS: [lblc] scheduler registered.
> IPVS: [lblcr] scheduler registered.
> IPVS: [dh] scheduler registered.
> IPVS: [sh] scheduler registered.
> IPVS: [mh] scheduler registered.
> IPVS: [sed] scheduler registered.
> IPVS: [nq] scheduler registered.
> IPVS: ftp: loaded support on port[0] = 21
> IPVS: [sip] pe registered.
> ipip: IPv4 and MPLS over IPv4 tunneling driver
> gre: GRE over IPv4 demultiplexor driver
> ip_gre: GRE over IPv4 tunneling driver
> IPv4 over IPsec tunneling driver
> ipt_CLUSTERIP: ClusterIP Version 0.8 loaded successfully
> Initializing XFRM netlink socket
> IPsec XFRM device driver
> NET: Registered protocol family 10
> Segment Routing with IPv6
> mip6: Mobile IPv6
> sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
> ip6_gre: GRE over IPv6 tunneling driver
> NET: Registered protocol family 17
> NET: Registered protocol family 15
> Bridge firewalling registered
> NET: Registered protocol family 9
> X25: Linux Version 0.2
> NET: Registered protocol family 6
> NET: Registered protocol family 11
> NET: Registered protocol family 3
> can: controller area network core (rev 20170425 abi 9)
> NET: Registered protocol family 29
> can: raw protocol (rev 20170425)
> can: broadcast manager protocol (rev 20170425 t)
> can: netlink gateway (rev 20170425) max_hops=1
> Bluetooth: RFCOMM TTY layer initialized
> Bluetooth: RFCOMM socket layer initialized
> Bluetooth: RFCOMM ver 1.11
> Bluetooth: BNEP (Ethernet Emulation) ver 1.3
> Bluetooth: BNEP filters: protocol multicast
> Bluetooth: BNEP socket layer initialized
> Bluetooth: CMTP (CAPI Emulation) ver 1.0
> Bluetooth: CMTP socket layer initialized
> Bluetooth: HIDP (Human Interface Emulation) ver 1.2
> Bluetooth: HIDP socket layer initialized
> RPC: Registered rdma transport module.
> RPC: Registered rdma backchannel transport module.
> NET: Registered protocol family 33
> Key type rxrpc registered
> Key type rxrpc_s registered
> NET: Registered protocol family 41
> lec:lane_module_init: lec.c: initialized
> mpoa:atm_mpoa_init: mpc.c: initialized
> l2tp_core: L2TP core driver, V2.0
> l2tp_ppp: PPPoL2TP kernel driver, V2.0
> l2tp_ip: L2TP IP encapsulation support (L2TPv3)
> l2tp_netlink: L2TP netlink interface
> l2tp_eth: L2TP ethernet pseudowire support (L2TPv3)
> l2tp_ip6: L2TP IP encapsulation support for IPv6 (L2TPv3)
> 8021q: 802.1Q VLAN Support v1.8
> DCCP: Activated CCID 2 (TCP-like)
> DCCP: Activated CCID 3 (TCP-Friendly Rate Control)
> sctp: Hash tables configured (bind 64/64)
> NET: Registered protocol family 21
> Registered RDS/infiniband transport
> Registered RDS/tcp transport
> tipc: Activated (version 2.0.0)
> NET: Registered protocol family 30
> tipc: Started in single node mode
> NET: Registered protocol family 43
> 9pnet: Installing 9P2000 support
> NET: Registered protocol family 37
> NET: Registered protocol family 36
> Key type dns_resolver registered
> Key type ceph registered
> libceph: loaded (mon/osd proto 15/24)
> batman_adv: B.A.T.M.A.N. advanced 2019.3 (compatibility version 15) loaded
> openvswitch: Open vSwitch switching datapath
> mpls_gso: MPLS GSO support
> AVX2 version of gcm_enc/dec engaged.
> AES CTR mode by8 optimization enabled
> sched_clock: Marking stable (11023009686, 22427228)->(11169299490,  
> -123862576)
> registered taskstats version 1
> Loading compiled-in X.509 certificates
> zswap: loaded using pool lzo/zbud
> Btrfs loaded, crc32c=crc32c-intel
> Key type big_key registered
> Key type encrypted registered
> AppArmor: AppArmor sha1 policy hashing enabled
> ima: No TPM chip found, activating TPM-bypass!
> ima: Allocated hash algorithm: sha256
> No architecture policies found
> evm: Initialising EVM extended attributes:
> evm: security.selinux
> evm: security.SMACK64
> evm: security.SMACK64EXEC
> evm: security.SMACK64TRANSMUTE
> evm: security.SMACK64MMAP
> evm: security.apparmor
> evm: security.ima
> evm: security.capability
> evm: HMAC attrs: 0x1
> PM:   Magic number: 11:503:480
> usb usb18-port1: hash matches
> usb usb17-port2: hash matches
> bdi 31:0: hash matches
> printk: console [netcon0] enabled
> netconsole: network logging started
> gtp: GTP module loaded (pdp ctx size 104 bytes)
> ------------[ cut here ]------------
> __dev_pm_qos_remove_request() called for unknown object
> WARNING: CPU: 1 PID: 1 at drivers/base/power/qos.c:486  
> __dev_pm_qos_remove_request+0x3d3/0x4d0 drivers/base/power/qos.c:486

Viresh, any chance to look at this?

I'm a bit concerned about the freq QoS series at this point, may defer pushing it.




^ permalink raw reply

* Re: [PATCH V2 00/13] intel_rapl: RAPL abstraction and MMIO RAPL support
From: Rafael J. Wysocki @ 2019-07-05  8:57 UTC (permalink / raw)
  To: Zhang Rui; +Cc: Rafael J. Wysocki, Linux PM, Pandruvada, Srinivas
In-Reply-To: <1562258085-3165-1-git-send-email-rui.zhang@intel.com>

On Thu, Jul 4, 2019 at 6:34 PM Zhang Rui <rui.zhang@intel.com> wrote:
>
> Besideis MSR interface, RAPL can also be controlled via the MMIO interface,
> by accessing the MCHBar registers exposed by the processor thermal device.
>
> Currently, we only have RAPL MSR interface in Linux kernel, this brings
> problems on some platforms that BIOS performs a low power limits via the
> MMIO interface by default. This results in poor system performance,
> and there is no way for us to change the MMIO MSR setting in Linux.
>
> To fix this, RAPL MMIO interface support is introduced in this patch set.
>
> Patch 1/13 to patch 11/13 abstract the RAPL code, and move all the shared
> code into a separate file, intel_rapl_common.c, so that it can be used
> by both MSR and MMIO interfaces.
> Patch 12/13 introduced RAPL support via MMIO registers, exposed by the
> processor thermal devices.
> Patch 13/13 fixes a module autoloading issue found later.
>
> The patch series has been tested on Dell XPS 9360, a SKL platform.
>
> Note that this patch series are based on the -tip tree, which contains the
> latest RAPL changes for multi-die support.
>
> Changes in V2:
>    - add kerneldoc for struct rapl_if_priv.
>    - use intel_rapl_msr.c for RAPL MSR I/F driver, instead of intel_rapl.c.
>    - changelog and coding style update.

What tree is the series against?

It doesn't apply either on top of my powercap branch or on top of
5.2-rc7 for me.

^ permalink raw reply

* Re: [PATCH 5/6] clk: imx8mq: Remove CLK_IS_CRITICAL flag for IMX8MQ_CLK_TMU_ROOT
From: Abel Vesa @ 2019-07-05  7:01 UTC (permalink / raw)
  To: Anson Huang
  Cc: rui.zhang@intel.com, edubezval@gmail.com,
	daniel.lezcano@linaro.org, robh+dt@kernel.org,
	mark.rutland@arm.com, shawnguo@kernel.org, s.hauer@pengutronix.de,
	kernel@pengutronix.de, festevam@gmail.com,
	mturquette@baylibre.com, sboyd@kernel.org, l.stach@pengutronix.de,
	andrew.smirnov@gmail.com, angus@akkea.ca, ccaione@baylibre.com,
	agx@sigxcpu.org, Leonard Crestez, linux-pm@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org,
	dl-linux-imx
In-Reply-To: <20190705045612.27665-5-Anson.Huang@nxp.com>

On 19-07-05 12:56:11, Anson.Huang@nxp.com wrote:
> From: Anson Huang <Anson.Huang@nxp.com>
> 
> IMX8MQ_CLK_TMU_ROOT is ONLY used for thermal module, the driver
> should manage this clock, so no need to have CLK_IS_CRITICAL flag
> set.
> 
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>

Reviewed-by: Abel Vesa <abel.vesa@nxp.com>

> ---
>  drivers/clk/imx/clk-imx8mq.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
> index d407a07..91de69a 100644
> --- a/drivers/clk/imx/clk-imx8mq.c
> +++ b/drivers/clk/imx/clk-imx8mq.c
> @@ -539,7 +539,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
>  	clks[IMX8MQ_CLK_DISP_AXI_ROOT]  = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
>  	clks[IMX8MQ_CLK_DISP_APB_ROOT]  = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
>  	clks[IMX8MQ_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
> -	clks[IMX8MQ_CLK_TMU_ROOT] = imx_clk_gate4_flags("tmu_root_clk", "ipg_root", base + 0x4620, 0, CLK_IS_CRITICAL);
> +	clks[IMX8MQ_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
>  	clks[IMX8MQ_CLK_VPU_DEC_ROOT] = imx_clk_gate2_flags("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
>  	clks[IMX8MQ_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
>  	clks[IMX8MQ_CLK_CSI2_ROOT] = imx_clk_gate4("csi2_root_clk", "csi2_core", base + 0x4660, 0);
> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH 5/6] clk: imx8mq: Remove CLK_IS_CRITICAL flag for IMX8MQ_CLK_TMU_ROOT
From: Anson.Huang @ 2019-07-05  4:56 UTC (permalink / raw)
  To: rui.zhang, edubezval, daniel.lezcano, robh+dt, mark.rutland,
	shawnguo, s.hauer, kernel, festevam, mturquette, sboyd, l.stach,
	abel.vesa, andrew.smirnov, angus, ccaione, agx, leonard.crestez,
	linux-pm, devicetree, linux-kernel, linux-arm-kernel, linux-clk
  Cc: Linux-imx
In-Reply-To: <20190705045612.27665-1-Anson.Huang@nxp.com>

From: Anson Huang <Anson.Huang@nxp.com>

IMX8MQ_CLK_TMU_ROOT is ONLY used for thermal module, the driver
should manage this clock, so no need to have CLK_IS_CRITICAL flag
set.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 drivers/clk/imx/clk-imx8mq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
index d407a07..91de69a 100644
--- a/drivers/clk/imx/clk-imx8mq.c
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -539,7 +539,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
 	clks[IMX8MQ_CLK_DISP_AXI_ROOT]  = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
 	clks[IMX8MQ_CLK_DISP_APB_ROOT]  = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
 	clks[IMX8MQ_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
-	clks[IMX8MQ_CLK_TMU_ROOT] = imx_clk_gate4_flags("tmu_root_clk", "ipg_root", base + 0x4620, 0, CLK_IS_CRITICAL);
+	clks[IMX8MQ_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
 	clks[IMX8MQ_CLK_VPU_DEC_ROOT] = imx_clk_gate2_flags("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
 	clks[IMX8MQ_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
 	clks[IMX8MQ_CLK_CSI2_ROOT] = imx_clk_gate4("csi2_root_clk", "csi2_core", base + 0x4660, 0);
-- 
2.7.4


^ permalink raw reply related

* [PATCH 6/6] arm64: dts: imx8mq: Add clock for TMU node
From: Anson.Huang @ 2019-07-05  4:56 UTC (permalink / raw)
  To: rui.zhang, edubezval, daniel.lezcano, robh+dt, mark.rutland,
	shawnguo, s.hauer, kernel, festevam, mturquette, sboyd, l.stach,
	abel.vesa, andrew.smirnov, angus, ccaione, agx, leonard.crestez,
	linux-pm, devicetree, linux-kernel, linux-arm-kernel, linux-clk
  Cc: Linux-imx
In-Reply-To: <20190705045612.27665-1-Anson.Huang@nxp.com>

From: Anson Huang <Anson.Huang@nxp.com>

i.MX8MQ has clock gate for TMU module, add clock info to TMU
node for clock management.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index c61e968..edfc1aa 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -348,6 +348,7 @@
 				compatible = "fsl,imx8mq-tmu";
 				reg = <0x30260000 0x10000>;
 				interrupt = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_TMU_ROOT>;
 				little-endian;
 				fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x70061>;
 				fsl,tmu-calibration = <0x00000000 0x00000023
-- 
2.7.4


^ permalink raw reply related

* [PATCH 1/6] thermal: qoriq: Use devm_platform_ioremap_resource() instead of of_iomap()
From: Anson.Huang @ 2019-07-05  4:56 UTC (permalink / raw)
  To: rui.zhang, edubezval, daniel.lezcano, robh+dt, mark.rutland,
	shawnguo, s.hauer, kernel, festevam, mturquette, sboyd, l.stach,
	abel.vesa, andrew.smirnov, angus, ccaione, agx, leonard.crestez,
	linux-pm, devicetree, linux-kernel, linux-arm-kernel, linux-clk
  Cc: Linux-imx

From: Anson Huang <Anson.Huang@nxp.com>

Use devm_platform_ioremap_resource() instead of of_iomap() to
save the iounmap() call in error handle path;

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 drivers/thermal/qoriq_thermal.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
index 7b36493..c7c7de2 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -202,32 +202,27 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
 
 	data->little_endian = of_property_read_bool(np, "little-endian");
 
-	data->regs = of_iomap(np, 0);
-	if (!data->regs) {
+	data->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(data->regs)) {
 		dev_err(&pdev->dev, "Failed to get memory region\n");
-		ret = -ENODEV;
-		goto err_iomap;
+		return PTR_ERR(data->regs);
 	}
 
 	qoriq_tmu_init_device(data);	/* TMU initialization */
 
 	ret = qoriq_tmu_calibration(pdev);	/* TMU calibration */
 	if (ret < 0)
-		goto err_tmu;
+		goto err;
 
 	ret = qoriq_tmu_register_tmu_zone(pdev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to register sensors\n");
-		ret = -ENODEV;
-		goto err_iomap;
+		goto err;
 	}
 
 	return 0;
 
-err_tmu:
-	iounmap(data->regs);
-
-err_iomap:
+err:
 	platform_set_drvdata(pdev, NULL);
 
 	return ret;
@@ -240,7 +235,6 @@ static int qoriq_tmu_remove(struct platform_device *pdev)
 	/* Disable monitoring */
 	tmu_write(data, TMR_DISABLE, &data->regs->tmr);
 
-	iounmap(data->regs);
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;
-- 
2.7.4


^ permalink raw reply related

* [PATCH 2/6] thermal: qoriq: Use __maybe_unused instead of #if CONFIG_PM_SLEEP
From: Anson.Huang @ 2019-07-05  4:56 UTC (permalink / raw)
  To: rui.zhang, edubezval, daniel.lezcano, robh+dt, mark.rutland,
	shawnguo, s.hauer, kernel, festevam, mturquette, sboyd, l.stach,
	abel.vesa, andrew.smirnov, angus, ccaione, agx, leonard.crestez,
	linux-pm, devicetree, linux-kernel, linux-arm-kernel, linux-clk
  Cc: Linux-imx
In-Reply-To: <20190705045612.27665-1-Anson.Huang@nxp.com>

From: Anson Huang <Anson.Huang@nxp.com>

Use __maybe_unused for power management related functions
instead of #if CONFIG_PM_SLEEP to simply the code.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 drivers/thermal/qoriq_thermal.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
index c7c7de2..2b2f79b 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -240,8 +240,7 @@ static int qoriq_tmu_remove(struct platform_device *pdev)
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int qoriq_tmu_suspend(struct device *dev)
+static int __maybe_unused qoriq_tmu_suspend(struct device *dev)
 {
 	u32 tmr;
 	struct qoriq_tmu_data *data = dev_get_drvdata(dev);
@@ -254,7 +253,7 @@ static int qoriq_tmu_suspend(struct device *dev)
 	return 0;
 }
 
-static int qoriq_tmu_resume(struct device *dev)
+static int __maybe_unused qoriq_tmu_resume(struct device *dev)
 {
 	u32 tmr;
 	struct qoriq_tmu_data *data = dev_get_drvdata(dev);
@@ -266,7 +265,6 @@ static int qoriq_tmu_resume(struct device *dev)
 
 	return 0;
 }
-#endif
 
 static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops,
 			 qoriq_tmu_suspend, qoriq_tmu_resume);
-- 
2.7.4


^ permalink raw reply related

* [PATCH 4/6] thermal: qoriq: Add clock operations
From: Anson.Huang @ 2019-07-05  4:56 UTC (permalink / raw)
  To: rui.zhang, edubezval, daniel.lezcano, robh+dt, mark.rutland,
	shawnguo, s.hauer, kernel, festevam, mturquette, sboyd, l.stach,
	abel.vesa, andrew.smirnov, angus, ccaione, agx, leonard.crestez,
	linux-pm, devicetree, linux-kernel, linux-arm-kernel, linux-clk
  Cc: Linux-imx
In-Reply-To: <20190705045612.27665-1-Anson.Huang@nxp.com>

From: Anson Huang <Anson.Huang@nxp.com>

Some platforms like i.MX8MQ has clock control for this module,
need to add clock operations to make sure the driver is working
properly.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 drivers/thermal/qoriq_thermal.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
index 2b2f79b..0813c1b 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -2,6 +2,7 @@
 //
 // Copyright 2016 Freescale Semiconductor, Inc.
 
+#include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
@@ -72,6 +73,7 @@ struct qoriq_sensor {
 
 struct qoriq_tmu_data {
 	struct qoriq_tmu_regs __iomem *regs;
+	struct clk *clk;
 	bool little_endian;
 	struct qoriq_sensor	*sensor[SITES_MAX];
 };
@@ -208,6 +210,19 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
 		return PTR_ERR(data->regs);
 	}
 
+	data->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(data->clk)) {
+		if (PTR_ERR(data->clk) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		data->clk = NULL;
+	}
+
+	ret = clk_prepare_enable(data->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to enable clock\n");
+		return ret;
+	}
+
 	qoriq_tmu_init_device(data);	/* TMU initialization */
 
 	ret = qoriq_tmu_calibration(pdev);	/* TMU calibration */
@@ -235,6 +250,8 @@ static int qoriq_tmu_remove(struct platform_device *pdev)
 	/* Disable monitoring */
 	tmu_write(data, TMR_DISABLE, &data->regs->tmr);
 
+	clk_disable_unprepare(data->clk);
+
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;
@@ -250,14 +267,21 @@ static int __maybe_unused qoriq_tmu_suspend(struct device *dev)
 	tmr &= ~TMR_ME;
 	tmu_write(data, tmr, &data->regs->tmr);
 
+	clk_disable_unprepare(data->clk);
+
 	return 0;
 }
 
 static int __maybe_unused qoriq_tmu_resume(struct device *dev)
 {
 	u32 tmr;
+	int ret;
 	struct qoriq_tmu_data *data = dev_get_drvdata(dev);
 
+	ret = clk_prepare_enable(data->clk);
+	if (ret)
+		return ret;
+
 	/* Enable monitoring */
 	tmr = tmu_read(data, &data->regs->tmr);
 	tmr |= TMR_ME;
-- 
2.7.4


^ permalink raw reply related

* [PATCH 3/6] dt-bindings: thermal: qoriq: Add optional clocks property
From: Anson.Huang @ 2019-07-05  4:56 UTC (permalink / raw)
  To: rui.zhang, edubezval, daniel.lezcano, robh+dt, mark.rutland,
	shawnguo, s.hauer, kernel, festevam, mturquette, sboyd, l.stach,
	abel.vesa, andrew.smirnov, angus, ccaione, agx, leonard.crestez,
	linux-pm, devicetree, linux-kernel, linux-arm-kernel, linux-clk
  Cc: Linux-imx
In-Reply-To: <20190705045612.27665-1-Anson.Huang@nxp.com>

From: Anson Huang <Anson.Huang@nxp.com>

Some platforms have clock control for TMU, add optional
clocks property to the binding doc.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 Documentation/devicetree/bindings/thermal/qoriq-thermal.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt b/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
index 04cbb90..28f2cba 100644
--- a/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
@@ -23,6 +23,7 @@ Required properties:
 Optional property:
 - little-endian : If present, the TMU registers are little endian. If absent,
 	the default is big endian.
+- clocks : the clock for clocking the TMU silicon.
 
 Example:
 
-- 
2.7.4


^ permalink raw reply related

* Re: suspend broken in next-20190704 on Thinkpad X60
From: Rafael J. Wysocki @ 2019-07-04 22:59 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Rafael J. Wysocki, Linux-pm mailing list, kernel list,
	Stephen Rothwell
In-Reply-To: <20190704192020.GA3771@amd>

On Thu, Jul 4, 2019 at 9:20 PM Pavel Machek <pavel@ucw.cz> wrote:
>
> Hi!
>
> Suspend is broken in next-20190704 on Thinkpad X60.

Broken in what way?  Any details?

> It very very probably worked ok in 20190701.

Well, please try the linux-next branch from linux-pm.git
(git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git)
alone and see if that fails.

^ permalink raw reply

* Re: Thermal microconference proposal @ LPC
From: Pandruvada, Srinivas @ 2019-07-04 20:45 UTC (permalink / raw)
  To: amit.kucheria@linaro.org
  Cc: Zhang, Rui, edubezval@gmail.com, daniel.lezcano@linaro.org,
	linux-pm@vger.kernel.org
In-Reply-To: <CAP245DV==fQDzyE=jxq9qNNP-DG54Pd6=nqAu99nCwfNjs9ePw@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1696 bytes --]

Hi Amit,

On Thu, 2019-07-04 at 08:20 +0530, Amit Kucheria wrote:
> Hi Srinivas,
> 
> On Thu, Jul 4, 2019 at 2:15 AM Pandruvada, Srinivas
> <srinivas.pandruvada@intel.com> wrote:
> > 
> > Hi Amit,
> > On Mon, 2019-06-24 at 19:22 +0530, Amit Kucheria wrote:
> > > Hi all,
> > > 
> > > We've proposed a thermal microconf at LPC again this year. I've
> > > bcc'ed
> > > a few people who were interested last year. We already have the
> > > following topics listed for the proposal but could certainly use
> > > more
> > > topics especially from the non-mobile Linux community.
> > > 
> > 
> > 
> > Thermal/Power mitigation on high powered laptops
> > 
> > Some of the high powered laptops released with KabyLake and later
> > generations of processors can reach more than 50W with some busy
> > workloads like kernel compilation. This results in CPU temperature
> > to
> > quickly reach close to the critical temperature. To avoid this
> > OEM’s
> > have used a very conservative power limits  by default. But this
> > results in a bad performance on Linux laptops compared to other
> > operating systems. We have implemented a solution for Linux to
> > mitigate
> > this. This quick presentation will show the approach Linux users
> > particularly kernel developers can use to get a very high
> > performance
> > from these laptops.
> > 
> > This should be a quick 5-10 min talk.
> 
> Thanks for the submission. Is this supposed to be a discussion or
> only
> a presentation?
One slide to show power/thermal graph.

Thanks,
Srinivas

> 
> In any case, Rafael and Eduardo are now triaging the list of talks as
> MC leads.
> 
> Regards,
> Amit

[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 3290 bytes --]

^ permalink raw reply

* Re: [PATCH v2 3/7] rtc: mt6397: improvements of rtc driver
From: Alexandre Belloni @ 2019-07-04 20:43 UTC (permalink / raw)
  To: Frank Wunderlich
  Cc: Lee Jones, Rob Herring, Mark Rutland, Matthias Brugger, Sean Wang,
	Sebastian Reichel, Alessandro Zummo, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, linux-pm, linux-rtc, Eddie Huang,
	Thomas Gleixner, Richard Fontana, Allison Randal,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Rob Herring, Linus Walleij, Nicolas Ferre, Paul E . McKenney,
	Josef Friedl
In-Reply-To: <20190703164822.17924-4-frank-w@public-files.de>

On 03/07/2019 18:48:18+0200, Frank Wunderlich wrote:
> @@ -271,14 +268,11 @@ static int mtk_rtc_probe(struct platform_device *pdev)
> 
>  	platform_set_drvdata(pdev, rtc);
> 
> -	rtc->rtc_dev = devm_rtc_allocate_device(rtc->dev);
> -	if (IS_ERR(rtc->rtc_dev))
> -		return PTR_ERR(rtc->rtc_dev);
> +	ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
> +					mtk_rtc_irq_handler_thread,
> +					IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
> +					"mt6397-rtc", rtc);
> 

This change may lead to a crash and the allocation was intentionally
placed before the irq request.

> -	ret = request_threaded_irq(rtc->irq, NULL,
> -				   mtk_rtc_irq_handler_thread,
> -				   IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
> -				   "mt6397-rtc", rtc);
>  	if (ret) {
>  		dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
>  			rtc->irq, ret);
> @@ -287,6 +281,10 @@ static int mtk_rtc_probe(struct platform_device *pdev)
> 
>  	device_init_wakeup(&pdev->dev, 1);
> 
> +	rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
> +	if (IS_ERR(rtc->rtc_dev))
> +		return PTR_ERR(rtc->rtc_dev);
> +
>  	rtc->rtc_dev->ops = &mtk_rtc_ops;
> 
>  	ret = rtc_register_device(rtc->rtc_dev);
> @@ -302,15 +300,6 @@ static int mtk_rtc_probe(struct platform_device *pdev)
>  	return ret;
>  }
> 
> -static int mtk_rtc_remove(struct platform_device *pdev)
> -{
> -	struct mt6397_rtc *rtc = platform_get_drvdata(pdev);
> -
> -	free_irq(rtc->irq, rtc);
> -
> -	return 0;
> -}
> -
>  #ifdef CONFIG_PM_SLEEP
>  static int mt6397_rtc_suspend(struct device *dev)
>  {
> @@ -337,6 +326,7 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend,
>  			mt6397_rtc_resume);
> 
>  static const struct of_device_id mt6397_rtc_of_match[] = {
> +	{ .compatible = "mediatek,mt6323-rtc", },

Unrelated change, this is not an improvement and must be accompanied by
a documentation change.

>  	{ .compatible = "mediatek,mt6397-rtc", },
>  	{ }
>  };
> @@ -349,7 +339,6 @@ static struct platform_driver mtk_rtc_driver = {
>  		.pm = &mt6397_pm_ops,
>  	},
>  	.probe	= mtk_rtc_probe,
> -	.remove = mtk_rtc_remove,
>  };
> 
>  module_platform_driver(mtk_rtc_driver);
> --
> 2.17.1
> 

-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* suspend broken in next-20190704 on Thinkpad X60
From: Pavel Machek @ 2019-07-04 19:20 UTC (permalink / raw)
  To: Rafael J. Wysocki, Linux-pm mailing list, kernel list, sfr

[-- Attachment #1: Type: text/plain, Size: 251 bytes --]

Hi!

Suspend is broken in next-20190704 on Thinkpad X60. It very very
probably worked ok in 20190701.



-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply

* Re: [PATCH v2 1/7] docs: dt-bindings: add poweroff
From: Alexandre Belloni @ 2019-07-04 18:54 UTC (permalink / raw)
  To: Frank Wunderlich
  Cc: Lee Jones, Rob Herring, Mark Rutland, Matthias Brugger, Sean Wang,
	Sebastian Reichel, Alessandro Zummo, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, linux-pm, linux-rtc, Eddie Huang,
	Thomas Gleixner, Richard Fontana, Allison Randal,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Rob Herring, Linus Walleij, Nicolas Ferre, Paul E . McKenney,
	Josef Friedl
In-Reply-To: <20190703164822.17924-2-frank-w@public-files.de>

Please use a better subject line.

On 03/07/2019 18:48:16+0200, Frank Wunderlich wrote:
> From: Josef Friedl <josef.friedl@speed.at>
> 
> add documentation for pmic, rtc and power/reset devicetree bindings
> 
> Suggested-by: Frank Wunderlich <frank-w@public-files.de>
> Signed-off-by: Josef Friedl <josef.friedl@speed.at>
> Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
> ---
>  .../devicetree/bindings/mfd/mt6397.txt        | 10 ++++++-
>  .../bindings/power/reset/mt6323-poweroff.txt  | 20 +++++++++++++
>  .../devicetree/bindings/rtc/rtc-mt6397.txt    | 29 +++++++++++++++++++

This file is unrelated to the patch, it should be separated.

>  3 files changed, 58 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt
>  create mode 100644 Documentation/devicetree/bindings/rtc/rtc-mt6397.txt
> 
> diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
> index 0ebd08af777d..44acb9827716 100644
> --- a/Documentation/devicetree/bindings/mfd/mt6397.txt
> +++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
> @@ -8,6 +8,7 @@ MT6397/MT6323 is a multifunction device with the following sub modules:
>  - Clock
>  - LED
>  - Keys
> +- Power controller
> 
>  It is interfaced to host controller using SPI interface by a proprietary hardware
>  called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap.
> @@ -22,8 +23,10 @@ compatible: "mediatek,mt6397" or "mediatek,mt6323"
>  Optional subnodes:
> 
>  - rtc
> -	Required properties:
> +	Required properties: Should be one of follows
> +		- compatible: "mediatek,mt6323-rtc"
>  		- compatible: "mediatek,mt6397-rtc"
> +	For details, see Documentation/devicetree/bindings/rtc/rtc-mt6397.txt
>  - regulators
>  	Required properties:
>  		- compatible: "mediatek,mt6397-regulator"
> @@ -46,6 +49,11 @@ Optional subnodes:
>  		- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
>  	see Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
> 
> +- power-controller
> +	Required properties:
> +		- compatible: "mediatek,mt6323-pwrc"
> +	For details, see Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt
> +
>  Example:
>  	pwrap: pwrap@1000f000 {
>  		compatible = "mediatek,mt8135-pwrap";
> diff --git a/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt b/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt
> new file mode 100644
> index 000000000000..933f0c48e887
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt
> @@ -0,0 +1,20 @@
> +Device Tree Bindings for Power Controller on MediaTek PMIC
> +
> +The power controller which could be found on PMIC is responsible for externally
> +powering off or on the remote MediaTek SoC through the circuit BBPU.
> +
> +Required properties:
> +- compatible: Should be one of follows
> +       "mediatek,mt6323-pwrc": for MT6323 PMIC
> +
> +Example:
> +
> +       pmic {
> +               compatible = "mediatek,mt6323";
> +
> +               ...
> +
> +               power-controller {
> +                       compatible = "mediatek,mt6323-pwrc";
> +               };
> +       }
> diff --git a/Documentation/devicetree/bindings/rtc/rtc-mt6397.txt b/Documentation/devicetree/bindings/rtc/rtc-mt6397.txt
> new file mode 100644
> index 000000000000..ebd1cf80dcc8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/rtc/rtc-mt6397.txt
> @@ -0,0 +1,29 @@
> +Device-Tree bindings for MediaTek PMIC based RTC
> +
> +MediaTek PMIC based RTC is an independent function of MediaTek PMIC that works
> +as a type of multi-function device (MFD). The RTC can be configured and set up
> +with PMIC wrapper bus which is a common resource shared with the other
> +functions found on the same PMIC.
> +
> +For MediaTek PMIC MFD bindings, see:
> +Documentation/devicetree/bindings/mfd/mt6397.txt
> +
> +For MediaTek PMIC wrapper bus bindings, see:
> +Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
> +
> +Required properties:
> +- compatible: Should be one of follows
> +       "mediatek,mt6323-rtc": for MT6323 PMIC
> +       "mediatek,mt6397-rtc": for MT6397 PMIC
> +
> +Example:
> +
> +       pmic {
> +               compatible = "mediatek,mt6323";
> +
> +               ...
> +
> +               rtc {
> +                       compatible = "mediatek,mt6323-rtc";
> +               };
> +       };
> --
> 2.17.1
> 

-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* linux-next boot error: WARNING in corrupted
From: syzbot @ 2019-07-04 17:27 UTC (permalink / raw)
  To: gregkh, len.brown, linux-kernel, linux-pm, pavel, rjw,
	syzkaller-bugs

Hello,

syzbot found the following crash on:

HEAD commit:    16c474c9 Add linux-next specific files for 20190704
git tree:       linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=17f8b463a00000
kernel config:  https://syzkaller.appspot.com/x/.config?x=983f02aae1ef31b6
dashboard link: https://syzkaller.appspot.com/bug?extid=de771ae9390dffed7266
compiler:       gcc (GCC) 9.0.0 20181231 (experimental)

Unfortunately, I don't have any reproducer for this crash yet.

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+de771ae9390dffed7266@syzkaller.appspotmail.com

smpboot: CPU0: Intel(R) Xeon(R) CPU @ 2.30GHz (family: 0x6, model: 0x3f,  
stepping: 0x0)
Performance Events: unsupported p6 CPU model 63 no PMU driver, software  
events only.
rcu: Hierarchical SRCU implementation.
NMI watchdog: Perf NMI watchdog permanently disabled
smp: Bringing up secondary CPUs ...
x86: Booting SMP configuration:
.... node  #0, CPUs:      #1
MDS CPU bug present and SMT on, data leak possible. See  
https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html for  
more details.
smp: Brought up 2 nodes, 2 CPUs
smpboot: Max logical packages: 1
smpboot: Total of 2 processors activated (9200.00 BogoMIPS)
devtmpfs: initialized
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns:  
19112604462750000 ns
futex hash table entries: 512 (order: 4, 65536 bytes, vmalloc)
xor: automatically using best checksumming function   avx
PM: RTC time: 12:27:33, date: 2019-07-04
NET: Registered protocol family 16
audit: initializing netlink subsys (disabled)
cpuidle: using governor menu
ACPI: bus type PCI registered
dca service started, version 1.12.1
PCI: Using configuration type 1 for base access
WARNING: workqueue cpumask: online intersect > possible intersect
HugeTLB registered 1.00 GiB page size, pre-allocated 0 pages
HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
cryptd: max_cpu_qlen set to 1000
raid6: avx2x4   gen() 12091 MB/s
raid6: avx2x4   xor()  6705 MB/s
raid6: avx2x2   gen()  7359 MB/s
raid6: avx2x2   xor()  3820 MB/s
raid6: avx2x1   gen()  3746 MB/s
raid6: avx2x1   xor()  2047 MB/s
raid6: sse2x4   gen()  6209 MB/s
raid6: sse2x4   xor()  3539 MB/s
raid6: sse2x2   gen()  3607 MB/s
raid6: sse2x2   xor()  2014 MB/s
raid6: sse2x1   gen()  1877 MB/s
raid6: sse2x1   xor()  1038 MB/s
raid6: using algorithm avx2x4 gen() 12091 MB/s
raid6: .... xor() 6705 MB/s, rmw enabled
raid6: using avx2x2 recovery algorithm
ACPI: Added _OSI(Module Device)
ACPI: Added _OSI(Processor Device)
ACPI: Added _OSI(3.0 _SCP Extensions)
ACPI: Added _OSI(Processor Aggregator Device)
ACPI: Added _OSI(Linux-Dell-Video)
ACPI: Added _OSI(Linux-Lenovo-NV-HDMI-Audio)
ACPI: Added _OSI(Linux-HPI-Hybrid-Graphics)
ACPI: 2 ACPI AML tables successfully acquired and loaded
ACPI: Interpreter enabled
ACPI: (supports S0 S3 S4 S5)
ACPI: Using IOAPIC for interrupt routing
PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and  
report a bug
ACPI: Enabled 16 GPEs in block 00 to 0F
ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
acpi PNP0A03:00: _OSC: OS supports [ASPM ClockPM Segments MSI HPX-Type3]
acpi PNP0A03:00: fail to add MMCONFIG information, can't access extended  
PCI configuration space under this bridge.
PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [io  0x0000-0x0cf7 window]
pci_bus 0000:00: root bus resource [io  0x0d00-0xffff window]
pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff window]
pci_bus 0000:00: root bus resource [mem 0xc0000000-0xfebfffff window]
pci_bus 0000:00: root bus resource [bus 00-ff]
pci 0000:00:00.0: [8086:1237] type 00 class 0x060000
pci 0000:00:01.0: [8086:7110] type 00 class 0x060100
pci 0000:00:01.3: [8086:7113] type 00 class 0x068000
pci 0000:00:01.3: quirk: [io  0xb000-0xb03f] claimed by PIIX4 ACPI
pci 0000:00:03.0: [1af4:1004] type 00 class 0x000000
pci 0000:00:03.0: reg 0x10: [io  0xc000-0xc03f]
pci 0000:00:03.0: reg 0x14: [mem 0xfebfe000-0xfebfe07f]
pci 0000:00:04.0: [1af4:1000] type 00 class 0x020000
pci 0000:00:04.0: reg 0x10: [io  0xc040-0xc07f]
pci 0000:00:04.0: reg 0x14: [mem 0xfebff000-0xfebff07f]
ACPI: PCI Interrupt Link [LNKA] (IRQs 5 *10 11)
ACPI: PCI Interrupt Link [LNKB] (IRQs 5 *10 11)
ACPI: PCI Interrupt Link [LNKC] (IRQs 5 10 *11)
ACPI: PCI Interrupt Link [LNKD] (IRQs 5 10 *11)
ACPI: PCI Interrupt Link [LNKS] (IRQs *9)
vgaarb: loaded
SCSI subsystem initialized
ACPI: bus type USB registered
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
mc: Linux media interface: v0.10
videodev: Linux video capture interface: v2.00
pps_core: LinuxPPS API ver. 1 registered
pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti  
<giometti@linux.it>
PTP clock support registered
EDAC MC: Ver: 3.0.0
Advanced Linux Sound Architecture Driver Initialized.
PCI: Using ACPI for IRQ routing
Bluetooth: Core ver 2.22
NET: Registered protocol family 31
Bluetooth: HCI device and connection manager initialized
Bluetooth: HCI socket layer initialized
Bluetooth: L2CAP socket layer initialized
Bluetooth: SCO socket layer initialized
NET: Registered protocol family 8
NET: Registered protocol family 20
NetLabel: Initializing
NetLabel:  domain hash size = 128
NetLabel:  protocols = UNLABELED CIPSOv4 CALIPSO
NetLabel:  unlabeled traffic allowed by default
nfc: nfc_init: NFC Core ver 0.1
NET: Registered protocol family 39
clocksource: Switched to clocksource kvm-clock
VFS: Disk quotas dquot_6.6.0
VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
FS-Cache: Loaded
*** VALIDATE hugetlbfs ***
CacheFiles: Loaded
TOMOYO: 2.6.0
Mandatory Access Control activated.
AppArmor: AppArmor Filesystem Enabled
pnp: PnP ACPI init
pnp: PnP ACPI: found 7 devices
thermal_sys: Registered thermal governor 'step_wise'
thermal_sys: Registered thermal governor 'user_space'
clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns:  
2085701024 ns
pci_bus 0000:00: resource 4 [io  0x0000-0x0cf7 window]
pci_bus 0000:00: resource 5 [io  0x0d00-0xffff window]
pci_bus 0000:00: resource 6 [mem 0x000a0000-0x000bffff window]
pci_bus 0000:00: resource 7 [mem 0xc0000000-0xfebfffff window]
NET: Registered protocol family 2
tcp_listen_portaddr_hash hash table entries: 4096 (order: 6, 294912 bytes,  
vmalloc)
TCP established hash table entries: 65536 (order: 7, 524288 bytes, vmalloc)
TCP bind hash table entries: 65536 (order: 10, 4194304 bytes, vmalloc)
TCP: Hash tables configured (established 65536 bind 65536)
UDP hash table entries: 4096 (order: 7, 655360 bytes, vmalloc)
UDP-Lite hash table entries: 4096 (order: 7, 655360 bytes, vmalloc)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
NET: Registered protocol family 44
pci 0000:00:00.0: Limiting direct PCI/PCI transfers
PCI: CLS 0 bytes, default 64
PCI-DMA: Using software bounce buffering for IO (SWIOTLB)
software IO TLB: mapped [mem 0xaa800000-0xae800000] (64MB)
RAPL PMU: API unit is 2^-32 Joules, 0 fixed counters, 10737418240 ms ovfl  
timer
kvm: already loaded the other module
clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x212735223b2,  
max_idle_ns: 440795277976 ns
clocksource: Switched to clocksource tsc
mce: Machine check injector initialized
check: Scanning for low memory corruption every 60 seconds
Initialise system trusted keyrings
workingset: timestamp_bits=40 max_order=21 bucket_order=0
zbud: loaded
DLM installed
squashfs: version 4.0 (2009/01/31) Phillip Lougher
FS-Cache: Netfs 'nfs' registered for caching
NFS: Registering the id_resolver key type
Key type id_resolver registered
Key type id_legacy registered
nfs4filelayout_init: NFSv4 File Layout Driver Registering...
Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
ntfs: driver 2.1.32 [Flags: R/W].
fuse: init (API version 7.31)
JFS: nTxBlock = 8192, nTxLock = 65536
SGI XFS with ACLs, security attributes, realtime, no debug enabled
9p: Installing v9fs 9p2000 file system support
FS-Cache: Netfs '9p' registered for caching
gfs2: GFS2 installed
FS-Cache: Netfs 'ceph' registered for caching
ceph: loaded (mds proto 32)
NET: Registered protocol family 38
async_tx: api initialized (async)
Key type asymmetric registered
Asymmetric key parser 'x509' registered
Asymmetric key parser 'pkcs8' registered
Key type pkcs7_test registered
Asymmetric key parser 'tpm_parser' registered
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 246)
io scheduler mq-deadline registered
io scheduler kyber registered
io scheduler bfq registered
input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
ACPI: Power Button [PWRF]
input: Sleep Button as /devices/LNXSYSTM:00/LNXSLPBN:00/input/input1
ACPI: Sleep Button [SLPF]
ioatdma: Intel(R) QuickData Technology Driver 5.00
PCI Interrupt Link [LNKC] enabled at IRQ 11
virtio-pci 0000:00:03.0: virtio_pci: leaving for legacy driver
PCI Interrupt Link [LNKD] enabled at IRQ 10
virtio-pci 0000:00:04.0: virtio_pci: leaving for legacy driver
HDLC line discipline maxframe=4096
N_HDLC line discipline registered.
Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
00:03: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
00:04: ttyS1 at I/O 0x2f8 (irq = 3, base_baud = 115200) is a 16550A
00:05: ttyS2 at I/O 0x3e8 (irq = 6, base_baud = 115200) is a 16550A
00:06: ttyS3 at I/O 0x2e8 (irq = 7, base_baud = 115200) is a 16550A
Non-volatile memory driver v1.3
Linux agpgart interface v0.103
[drm] Initialized vgem 1.0.0 20120112 for vgem on minor 0
[drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[drm] Driver supports precise vblank timestamp query.
[drm] Initialized vkms 1.0.0 20180514 for vkms on minor 1
usbcore: registered new interface driver udl
brd: module loaded
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
loop: module loaded
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
debugfs: File 'sched' already present!
zram: Added device: zram0
debugfs: File 'sched' already present!
null: module loaded
nfcsim 0.2 initialized
Loading iSCSI transport class v2.0-870.
scsi host0: Virtio SCSI HBA
st: Version 20160209, fixed bufsize 32768, s/g segs 256
slram: not enough parameters.
ftl_cs: FTL header not found.
debugfs: File 'sched' already present!
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)
eql: Equalizer2002: Simon Janes (simon@ncm.com) and David S. Miller  
(davem@redhat.com)
MACsec IEEE 802.1AE
tun: Universal TUN/TAP device driver, 1.6
vcan: Virtual CAN interface driver
vxcan: Virtual CAN Tunnel driver
slcan: serial line CAN interface driver
slcan: 10 dynamic interface channels.
CAN device driver interface
enic: Cisco VIC Ethernet NIC Driver, ver 2.3.0.53
e100: Intel(R) PRO/100 Network Driver, 3.5.24-k2-NAPI
e100: Copyright(c) 1999-2006 Intel Corporation
e1000: Intel(R) PRO/1000 Network Driver - version 7.3.21-k8-NAPI
e1000: Copyright (c) 1999-2006 Intel Corporation.
e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
mkiss: AX.25 Multikiss, Hans Albas PE1AYX
AX.25: 6pack driver, Revision: 0.3.0
AX.25: bpqether driver version 004
PPP generic driver version 2.4.2
PPP BSD Compression module registered
PPP Deflate Compression module registered
PPP MPPE Compression module registered
NET: Registered protocol family 24
PPTP driver version 0.8.5
SLIP: version 0.8.4-NET3.019-NEWTTY (dynamic channels, max=256) (6 bit  
encapsulation enabled).
CSLIP: code copyright 1989 Regents of the University of California.
SLIP linefill/keepalive option.
hdlc: HDLC support module revision 1.22
x25_asy: X.25 async: version 0.00 ALPHA (dynamic channels, max=256)
DLCI driver v0.35, 4 Jan 1997, mike.mclagan@linux.org.
LAPB Ethernet driver version 0.02
usbcore: registered new interface driver rndis_wlan
mac80211_hwsim: initializing netlink
mac802154_hwsim mac802154_hwsim: Added 2 mac802154 hwsim hardware radios
VMware vmxnet3 virtual NIC driver - version 1.4.17.0-k-NAPI
pegasus: v0.9.3 (2013/04/25), Pegasus/Pegasus II USB Ethernet driver
usbcore: registered new interface driver pegasus
usbcore: registered new interface driver rtl8150
usbcore: registered new interface driver r8152
usbcore: registered new interface driver asix
usbcore: registered new interface driver ax88179_178a
usbcore: registered new interface driver cdc_ether
usbcore: registered new interface driver dm9601
usbcore: registered new interface driver smsc75xx
usbcore: registered new interface driver smsc95xx
usbcore: registered new interface driver net1080
usbcore: registered new interface driver rndis_host
usbcore: registered new interface driver cdc_subset
usbcore: registered new interface driver zaurus
usbcore: registered new interface driver MOSCHIP usb-ethernet driver
usbcore: registered new interface driver cdc_ncm
usbcore: registered new interface driver cdc_mbim
VFIO - User Level meta-driver version: 0.3
aoe: AoE v85 initialised.
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-pci: EHCI PCI platform driver
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ohci-pci: OHCI PCI platform driver
uhci_hcd: USB Universal Host Controller Interface driver
usbcore: registered new interface driver cdc_acm
cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
usbcore: registered new interface driver usblp
usbcore: registered new interface driver cdc_wdm
usbcore: registered new interface driver uas
usbcore: registered new interface driver usb-storage
usbcore: registered new interface driver ums-realtek
usbcore: registered new interface driver usbserial_generic
usbserial: USB Serial support registered for generic
usbcore: registered new interface driver ch341
usbserial: USB Serial support registered for ch341-uart
usbcore: registered new interface driver cp210x
usbserial: USB Serial support registered for cp210x
usbcore: registered new interface driver ftdi_sio
usbserial: USB Serial support registered for FTDI USB Serial Device
usbcore: registered new interface driver keyspan
usbserial: USB Serial support registered for Keyspan - (without firmware)
usbserial: USB Serial support registered for Keyspan 1 port adapter
usbserial: USB Serial support registered for Keyspan 2 port adapter
usbserial: USB Serial support registered for Keyspan 4 port adapter
usbcore: registered new interface driver option
usbserial: USB Serial support registered for GSM modem (1-port)
usbcore: registered new interface driver oti6858
usbserial: USB Serial support registered for oti6858
usbcore: registered new interface driver pl2303
usbserial: USB Serial support registered for pl2303
usbcore: registered new interface driver qcserial
usbserial: USB Serial support registered for Qualcomm USB modem
usbcore: registered new interface driver sierra
usbserial: USB Serial support registered for Sierra USB modem
usbcore: registered new interface driver usb_serial_simple
usbserial: USB Serial support registered for carelink
usbserial: USB Serial support registered for zio
usbserial: USB Serial support registered for funsoft
usbserial: USB Serial support registered for flashloader
usbserial: USB Serial support registered for google
usbserial: USB Serial support registered for libtransistor
usbserial: USB Serial support registered for vivopay
usbserial: USB Serial support registered for moto_modem
usbserial: USB Serial support registered for motorola_tetra
usbserial: USB Serial support registered for novatel_gps
usbserial: USB Serial support registered for hp4x
usbserial: USB Serial support registered for suunto
usbserial: USB Serial support registered for siemens_mpi
udc-core: couldn't find an available UDC - added [g_multi] to list of  
pending drivers
vhci_hcd vhci_hcd.0: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.0: new USB bus registered, assigned bus number 1
vhci_hcd: created sysfs vhci_hcd.0
usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb1: Product: USB/IP Virtual Host Controller
usb usb1: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb1: SerialNumber: vhci_hcd.0
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.0: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.0: new USB bus registered, assigned bus number 2
usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb2: Product: USB/IP Virtual Host Controller
usb usb2: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb2: SerialNumber: vhci_hcd.0
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.1: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.1: new USB bus registered, assigned bus number 3
usb usb3: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb3: Product: USB/IP Virtual Host Controller
usb usb3: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb3: SerialNumber: vhci_hcd.1
hub 3-0:1.0: USB hub found
hub 3-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.1: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.1: new USB bus registered, assigned bus number 4
usb usb4: We don't know the algorithms for LPM for this host, disabling LPM.
usb usb4: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb4: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb4: Product: USB/IP Virtual Host Controller
usb usb4: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb4: SerialNumber: vhci_hcd.1
hub 4-0:1.0: USB hub found
hub 4-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.2: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.2: new USB bus registered, assigned bus number 5
usb usb5: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb5: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb5: Product: USB/IP Virtual Host Controller
usb usb5: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb5: SerialNumber: vhci_hcd.2
hub 5-0:1.0: USB hub found
hub 5-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.2: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.2: new USB bus registered, assigned bus number 6
usb usb6: We don't know the algorithms for LPM for this host, disabling LPM.
usb usb6: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb6: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb6: Product: USB/IP Virtual Host Controller
usb usb6: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb6: SerialNumber: vhci_hcd.2
hub 6-0:1.0: USB hub found
hub 6-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.3: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.3: new USB bus registered, assigned bus number 7
usb usb7: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb7: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb7: Product: USB/IP Virtual Host Controller
usb usb7: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb7: SerialNumber: vhci_hcd.3
hub 7-0:1.0: USB hub found
hub 7-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.3: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.3: new USB bus registered, assigned bus number 8
usb usb8: We don't know the algorithms for LPM for this host, disabling LPM.
usb usb8: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb8: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb8: Product: USB/IP Virtual Host Controller
usb usb8: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb8: SerialNumber: vhci_hcd.3
hub 8-0:1.0: USB hub found
hub 8-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.4: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.4: new USB bus registered, assigned bus number 9
usb usb9: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb9: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb9: Product: USB/IP Virtual Host Controller
usb usb9: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb9: SerialNumber: vhci_hcd.4
hub 9-0:1.0: USB hub found
hub 9-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.4: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.4: new USB bus registered, assigned bus number 10
usb usb10: We don't know the algorithms for LPM for this host, disabling  
LPM.
usb usb10: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb10: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb10: Product: USB/IP Virtual Host Controller
usb usb10: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb10: SerialNumber: vhci_hcd.4
hub 10-0:1.0: USB hub found
hub 10-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.5: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.5: new USB bus registered, assigned bus number 11
usb usb11: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb11: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb11: Product: USB/IP Virtual Host Controller
usb usb11: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb11: SerialNumber: vhci_hcd.5
hub 11-0:1.0: USB hub found
hub 11-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.5: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.5: new USB bus registered, assigned bus number 12
usb usb12: We don't know the algorithms for LPM for this host, disabling  
LPM.
usb usb12: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb12: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb12: Product: USB/IP Virtual Host Controller
usb usb12: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb12: SerialNumber: vhci_hcd.5
hub 12-0:1.0: USB hub found
hub 12-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.6: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.6: new USB bus registered, assigned bus number 13
usb usb13: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb13: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb13: Product: USB/IP Virtual Host Controller
usb usb13: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb13: SerialNumber: vhci_hcd.6
hub 13-0:1.0: USB hub found
hub 13-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.6: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.6: new USB bus registered, assigned bus number 14
usb usb14: We don't know the algorithms for LPM for this host, disabling  
LPM.
usb usb14: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb14: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb14: Product: USB/IP Virtual Host Controller
usb usb14: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb14: SerialNumber: vhci_hcd.6
hub 14-0:1.0: USB hub found
hub 14-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.7: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.7: new USB bus registered, assigned bus number 15
usb usb15: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb15: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb15: Product: USB/IP Virtual Host Controller
usb usb15: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb15: SerialNumber: vhci_hcd.7
hub 15-0:1.0: USB hub found
hub 15-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.7: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.7: new USB bus registered, assigned bus number 16
usb usb16: We don't know the algorithms for LPM for this host, disabling  
LPM.
usb usb16: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb16: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb16: Product: USB/IP Virtual Host Controller
usb usb16: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb16: SerialNumber: vhci_hcd.7
hub 16-0:1.0: USB hub found
hub 16-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.8: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.8: new USB bus registered, assigned bus number 17
usb usb17: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb17: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb17: Product: USB/IP Virtual Host Controller
usb usb17: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb17: SerialNumber: vhci_hcd.8
hub 17-0:1.0: USB hub found
hub 17-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.8: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.8: new USB bus registered, assigned bus number 18
usb usb18: We don't know the algorithms for LPM for this host, disabling  
LPM.
usb usb18: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb18: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb18: Product: USB/IP Virtual Host Controller
usb usb18: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb18: SerialNumber: vhci_hcd.8
hub 18-0:1.0: USB hub found
hub 18-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.9: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.9: new USB bus registered, assigned bus number 19
usb usb19: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb19: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb19: Product: USB/IP Virtual Host Controller
usb usb19: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb19: SerialNumber: vhci_hcd.9
hub 19-0:1.0: USB hub found
hub 19-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.9: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.9: new USB bus registered, assigned bus number 20
usb usb20: We don't know the algorithms for LPM for this host, disabling  
LPM.
usb usb20: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb20: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb20: Product: USB/IP Virtual Host Controller
usb usb20: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb20: SerialNumber: vhci_hcd.9
hub 20-0:1.0: USB hub found
hub 20-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.10: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.10: new USB bus registered, assigned bus number 21
usb usb21: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb21: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb21: Product: USB/IP Virtual Host Controller
usb usb21: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb21: SerialNumber: vhci_hcd.10
hub 21-0:1.0: USB hub found
hub 21-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.10: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.10: new USB bus registered, assigned bus number 22
usb usb22: We don't know the algorithms for LPM for this host, disabling  
LPM.
usb usb22: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb22: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb22: Product: USB/IP Virtual Host Controller
usb usb22: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb22: SerialNumber: vhci_hcd.10
hub 22-0:1.0: USB hub found
hub 22-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.11: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.11: new USB bus registered, assigned bus number 23
usb usb23: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb23: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb23: Product: USB/IP Virtual Host Controller
usb usb23: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb23: SerialNumber: vhci_hcd.11
hub 23-0:1.0: USB hub found
hub 23-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.11: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.11: new USB bus registered, assigned bus number 24
usb usb24: We don't know the algorithms for LPM for this host, disabling  
LPM.
usb usb24: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb24: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb24: Product: USB/IP Virtual Host Controller
usb usb24: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb24: SerialNumber: vhci_hcd.11
hub 24-0:1.0: USB hub found
hub 24-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.12: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.12: new USB bus registered, assigned bus number 25
usb usb25: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb25: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb25: Product: USB/IP Virtual Host Controller
usb usb25: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb25: SerialNumber: vhci_hcd.12
hub 25-0:1.0: USB hub found
hub 25-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.12: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.12: new USB bus registered, assigned bus number 26
usb usb26: We don't know the algorithms for LPM for this host, disabling  
LPM.
usb usb26: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb26: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb26: Product: USB/IP Virtual Host Controller
usb usb26: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb26: SerialNumber: vhci_hcd.12
hub 26-0:1.0: USB hub found
hub 26-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.13: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.13: new USB bus registered, assigned bus number 27
usb usb27: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb27: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb27: Product: USB/IP Virtual Host Controller
usb usb27: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb27: SerialNumber: vhci_hcd.13
hub 27-0:1.0: USB hub found
hub 27-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.13: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.13: new USB bus registered, assigned bus number 28
usb usb28: We don't know the algorithms for LPM for this host, disabling  
LPM.
usb usb28: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb28: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb28: Product: USB/IP Virtual Host Controller
usb usb28: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb28: SerialNumber: vhci_hcd.13
hub 28-0:1.0: USB hub found
hub 28-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.14: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.14: new USB bus registered, assigned bus number 29
usb usb29: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb29: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb29: Product: USB/IP Virtual Host Controller
usb usb29: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb29: SerialNumber: vhci_hcd.14
hub 29-0:1.0: USB hub found
hub 29-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.14: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.14: new USB bus registered, assigned bus number 30
usb usb30: We don't know the algorithms for LPM for this host, disabling  
LPM.
usb usb30: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb30: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb30: Product: USB/IP Virtual Host Controller
usb usb30: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb30: SerialNumber: vhci_hcd.14
hub 30-0:1.0: USB hub found
hub 30-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.15: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.15: new USB bus registered, assigned bus number 31
usb usb31: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice=  
5.02
usb usb31: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb31: Product: USB/IP Virtual Host Controller
usb usb31: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb31: SerialNumber: vhci_hcd.15
hub 31-0:1.0: USB hub found
hub 31-0:1.0: 8 ports detected
vhci_hcd vhci_hcd.15: USB/IP Virtual Host Controller
vhci_hcd vhci_hcd.15: new USB bus registered, assigned bus number 32
usb usb32: We don't know the algorithms for LPM for this host, disabling  
LPM.
usb usb32: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice=  
5.02
usb usb32: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb32: Product: USB/IP Virtual Host Controller
usb usb32: Manufacturer: Linux 5.2.0-rc7-next-20190704 vhci_hcd
usb usb32: SerialNumber: vhci_hcd.15
hub 32-0:1.0: USB hub found
hub 32-0:1.0: 8 ports detected
usbcore: registered new device driver usbip-host
using random self ethernet address
using random host ethernet address
Mass Storage Function, version: 2009/09/11
LUN: removable file: (no medium)
no file given for LUN0
g_multi usbip-vudc.0: failed to start g_multi: -22
usbip-vudc: probe of usbip-vudc.0 failed with error -22
i8042: PNP: PS/2 Controller [PNP0303:KBD,PNP0f13:MOU] at 0x60,0x64 irq 1,12
i8042: Warning: Keylock active
serio: i8042 KBD port at 0x60,0x64 irq 1
serio: i8042 AUX port at 0x60,0x64 irq 12
mousedev: PS/2 mouse device common for all mice
rtc_cmos 00:00: RTC can wake from S4
rtc_cmos 00:00: registered as rtc0
rtc_cmos 00:00: alarms up to one day, 114 bytes nvram
i2c /dev entries driver
piix4_smbus 0000:00:01.3: SMBus base address uninitialized - upgrade BIOS  
or use force_addr=0xaddr
i2c-parport-light: adapter type unspecified
usbcore: registered new interface driver RobotFuzz Open Source InterFace,  
OSIF
usbcore: registered new interface driver i2c-tiny-usb
IR NEC protocol handler initialized
IR RC5(x/sz) protocol handler initialized
IR RC6 protocol handler initialized
IR JVC protocol handler initialized
IR Sony protocol handler initialized
IR SANYO protocol handler initialized
IR Sharp protocol handler initialized
IR MCE Keyboard/mouse protocol handler initialized
IR XMP protocol handler initialized
vimc vimc.0: bound vimc-sensor.0.auto (ops vimc_sen_comp_ops)
vimc vimc.0: bound vimc-sensor.1.auto (ops vimc_sen_comp_ops)
vimc vimc.0: bound vimc-debayer.2.auto (ops vimc_deb_comp_ops)
vimc vimc.0: bound vimc-debayer.3.auto (ops vimc_deb_comp_ops)
vimc vimc.0: bound vimc-capture.4.auto (ops vimc_cap_comp_ops)
vimc vimc.0: bound vimc-capture.5.auto (ops vimc_cap_comp_ops)
vimc vimc.0: bound vimc-sensor.6.auto (ops vimc_sen_comp_ops)
vimc vimc.0: bound vimc-scaler.7.auto (ops vimc_sca_comp_ops)
vimc vimc.0: bound vimc-capture.8.auto (ops vimc_cap_comp_ops)
vivid-000: using single planar format API
vivid-000: CEC adapter cec0 registered for HDMI input 0
vivid-000: V4L2 capture device registered as video3
vivid-000: CEC adapter cec1 registered for HDMI output 0
vivid-000: V4L2 output device registered as video4
vivid-000: V4L2 capture device registered as vbi0, supports raw and sliced  
VBI
vivid-000: V4L2 output device registered as vbi1, supports raw and sliced  
VBI
vivid-000: V4L2 capture device registered as swradio0
vivid-000: V4L2 receiver device registered as radio0
vivid-000: V4L2 transmitter device registered as radio1
vivid-001: using multiplanar format API
vivid-001: CEC adapter cec2 registered for HDMI input 0
vivid-001: V4L2 capture device registered as video5
vivid-001: CEC adapter cec3 registered for HDMI output 0
vivid-001: V4L2 output device registered as video6
vivid-001: V4L2 capture device registered as vbi2, supports raw and sliced  
VBI
vivid-001: V4L2 output device registered as vbi3, supports raw and sliced  
VBI
vivid-001: V4L2 capture device registered as swradio1
vivid-001: V4L2 receiver device registered as radio2
vivid-001: V4L2 transmitter device registered as radio3
vivid-002: using single planar format API
vivid-002: CEC adapter cec4 registered for HDMI input 0
vivid-002: V4L2 capture device registered as video7
vivid-002: CEC adapter cec5 registered for HDMI output 0
vivid-002: V4L2 output device registered as video8
vivid-002: V4L2 capture device registered as vbi4, supports raw and sliced  
VBI
vivid-002: V4L2 output device registered as vbi5, supports raw and sliced  
VBI
vivid-002: V4L2 capture device registered as swradio2
vivid-002: V4L2 receiver device registered as radio4
vivid-002: V4L2 transmitter device registered as radio5
vivid-003: using multiplanar format API
vivid-003: CEC adapter cec6 registered for HDMI input 0
vivid-003: V4L2 capture device registered as video9
vivid-003: CEC adapter cec7 registered for HDMI output 0
vivid-003: V4L2 output device registered as video10
vivid-003: V4L2 capture device registered as vbi6, supports raw and sliced  
VBI
vivid-003: V4L2 output device registered as vbi7, supports raw and sliced  
VBI
vivid-003: V4L2 capture device registered as swradio3
vivid-003: V4L2 receiver device registered as radio6
vivid-003: V4L2 transmitter device registered as radio7
vivid-004: using single planar format API
vivid-004: CEC adapter cec8 registered for HDMI input 0
vivid-004: V4L2 capture device registered as video11
vivid-004: CEC adapter cec9 registered for HDMI output 0
vivid-004: V4L2 output device registered as video12
vivid-004: V4L2 capture device registered as vbi8, supports raw and sliced  
VBI
vivid-004: V4L2 output device registered as vbi9, supports raw and sliced  
VBI
vivid-004: V4L2 capture device registered as swradio4
vivid-004: V4L2 receiver device registered as radio8
vivid-004: V4L2 transmitter device registered as radio9
vivid-005: using multiplanar format API
vivid-005: CEC adapter cec10 registered for HDMI input 0
vivid-005: V4L2 capture device registered as video13
vivid-005: CEC adapter cec11 registered for HDMI output 0
vivid-005: V4L2 output device registered as video14
vivid-005: V4L2 capture device registered as vbi10, supports raw and sliced  
VBI
vivid-005: V4L2 output device registered as vbi11, supports raw and sliced  
VBI
vivid-005: V4L2 capture device registered as swradio5
vivid-005: V4L2 receiver device registered as radio10
vivid-005: V4L2 transmitter device registered as radio11
vivid-006: using single planar format API
vivid-006: CEC adapter cec12 registered for HDMI input 0
vivid-006: V4L2 capture device registered as video15
vivid-006: CEC adapter cec13 registered for HDMI output 0
vivid-006: V4L2 output device registered as video16
vivid-006: V4L2 capture device registered as vbi12, supports raw and sliced  
VBI
vivid-006: V4L2 output device registered as vbi13, supports raw and sliced  
VBI
vivid-006: V4L2 capture device registered as swradio6
vivid-006: V4L2 receiver device registered as radio12
vivid-006: V4L2 transmitter device registered as radio13
vivid-007: using multiplanar format API
vivid-007: CEC adapter cec14 registered for HDMI input 0
vivid-007: V4L2 capture device registered as video17
vivid-007: CEC adapter cec15 registered for HDMI output 0
vivid-007: V4L2 output device registered as video18
vivid-007: V4L2 capture device registered as vbi14, supports raw and sliced  
VBI
vivid-007: V4L2 output device registered as vbi15, supports raw and sliced  
VBI
vivid-007: V4L2 capture device registered as swradio7
vivid-007: V4L2 receiver device registered as radio14
vivid-007: V4L2 transmitter device registered as radio15
vivid-008: using single planar format API
vivid-008: CEC adapter cec16 registered for HDMI input 0
vivid-008: V4L2 capture device registered as video19
vivid-008: CEC adapter cec17 registered for HDMI output 0
vivid-008: V4L2 output device registered as video20
vivid-008: V4L2 capture device registered as vbi16, supports raw and sliced  
VBI
vivid-008: V4L2 output device registered as vbi17, supports raw and sliced  
VBI
vivid-008: V4L2 capture device registered as swradio8
vivid-008: V4L2 receiver device registered as radio16
vivid-008: V4L2 transmitter device registered as radio17
vivid-009: using multiplanar format API
vivid-009: CEC adapter cec18 registered for HDMI input 0
vivid-009: V4L2 capture device registered as video21
vivid-009: CEC adapter cec19 registered for HDMI output 0
vivid-009: V4L2 output device registered as video22
vivid-009: V4L2 capture device registered as vbi18, supports raw and sliced  
VBI
vivid-009: V4L2 output device registered as vbi19, supports raw and sliced  
VBI
vivid-009: V4L2 capture device registered as swradio9
vivid-009: V4L2 receiver device registered as radio18
vivid-009: V4L2 transmitter device registered as radio19
vivid-010: using single planar format API
vivid-010: CEC adapter cec20 registered for HDMI input 0
vivid-010: V4L2 capture device registered as video23
vivid-010: CEC adapter cec21 registered for HDMI output 0
vivid-010: V4L2 output device registered as video24
vivid-010: V4L2 capture device registered as vbi20, supports raw and sliced  
VBI
vivid-010: V4L2 output device registered as vbi21, supports raw and sliced  
VBI
vivid-010: V4L2 capture device registered as swradio10
vivid-010: V4L2 receiver device registered as radio20
vivid-010: V4L2 transmitter device registered as radio21
vivid-011: using multiplanar format API
vivid-011: CEC adapter cec22 registered for HDMI input 0
vivid-011: V4L2 capture device registered as video25
vivid-011: CEC adapter cec23 registered for HDMI output 0
vivid-011: V4L2 output device registered as video26
vivid-011: V4L2 capture device registered as vbi22, supports raw and sliced  
VBI
vivid-011: V4L2 output device registered as vbi23, supports raw and sliced  
VBI
vivid-011: V4L2 capture device registered as swradio11
vivid-011: V4L2 receiver device registered as radio22
vivid-011: V4L2 transmitter device registered as radio23
vivid-012: using single planar format API
vivid-012: CEC adapter cec24 registered for HDMI input 0
vivid-012: V4L2 capture device registered as video27
vivid-012: CEC adapter cec25 registered for HDMI output 0
vivid-012: V4L2 output device registered as video28
vivid-012: V4L2 capture device registered as vbi24, supports raw and sliced  
VBI
vivid-012: V4L2 output device registered as vbi25, supports raw and sliced  
VBI
vivid-012: V4L2 capture device registered as swradio12
vivid-012: V4L2 receiver device registered as radio24
vivid-012: V4L2 transmitter device registered as radio25
vivid-013: using multiplanar format API
vivid-013: CEC adapter cec26 registered for HDMI input 0
vivid-013: V4L2 capture device registered as video29
vivid-013: CEC adapter cec27 registered for HDMI output 0
vivid-013: V4L2 output device registered as video30
vivid-013: V4L2 capture device registered as vbi26, supports raw and sliced  
VBI
vivid-013: V4L2 output device registered as vbi27, supports raw and sliced  
VBI
vivid-013: V4L2 capture device registered as swradio13
vivid-013: V4L2 receiver device registered as radio26
vivid-013: V4L2 transmitter device registered as radio27
vivid-014: using single planar format API
vivid-014: CEC adapter cec28 registered for HDMI input 0
vivid-014: V4L2 capture device registered as video31
vivid-014: CEC adapter cec29 registered for HDMI output 0
vivid-014: V4L2 output device registered as video32
vivid-014: V4L2 capture device registered as vbi28, supports raw and sliced  
VBI
vivid-014: V4L2 output device registered as vbi29, supports raw and sliced  
VBI
vivid-014: V4L2 capture device registered as swradio14
vivid-014: V4L2 receiver device registered as radio28
vivid-014: V4L2 transmitter device registered as radio29
vivid-015: using multiplanar format API
vivid-015: CEC adapter cec30 registered for HDMI input 0
vivid-015: V4L2 capture device registered as video33
vivid-015: CEC adapter cec31 registered for HDMI output 0
vivid-015: V4L2 output device registered as video34
vivid-015: V4L2 capture device registered as vbi30, supports raw and sliced  
VBI
vivid-015: V4L2 output device registered as vbi31, supports raw and sliced  
VBI
vivid-015: V4L2 capture device registered as swradio15
vivid-015: V4L2 receiver device registered as radio30
vivid-015: V4L2 transmitter device registered as radio31
vim2m vim2m.0: Device registered as /dev/video35
vicodec vicodec.0: Device 'stateful-encoder' registered as /dev/video36
vicodec vicodec.0: Device 'stateful-decoder' registered as /dev/video37
vicodec vicodec.0: Device 'stateless-decoder' registered as /dev/video38
usbcore: registered new interface driver uvcvideo
USB Video Class driver (1.1.1)
gspca_main: v2.14.0 registered
iTCO_wdt: Intel TCO WatchDog Timer Driver v1.11
iTCO_vendor_support: vendor-support=0
device-mapper: uevent: version 1.0.3
device-mapper: ioctl: 4.40.0-ioctl (2019-01-18) initialised:  
dm-devel@redhat.com
device-mapper: multipath round-robin: version 1.2.0 loaded
device-mapper: multipath queue-length: version 0.2.0 loaded
device-mapper: multipath service-time: version 0.3.0 loaded
device-mapper: raid: Loading target version 1.14.0
Bluetooth: HCI UART driver ver 2.3
Bluetooth: HCI UART protocol H4 registered
Bluetooth: HCI UART protocol BCSP registered
Bluetooth: HCI UART protocol LL registered
Bluetooth: HCI UART protocol Three-wire (H5) registered
Bluetooth: HCI UART protocol QCA registered
Bluetooth: HCI UART protocol AG6XX registered
Bluetooth: HCI UART protocol Marvell registered
usbcore: registered new interface driver bfusb
usbcore: registered new interface driver btusb
CAPI 2.0 started up with major 68 (middleware)
Modular ISDN core version 1.1.29
NET: Registered protocol family 34
DSP module 2.0
mISDN_dsp: DSP clocks every 80 samples. This equals 1 jiffies.
mISDN: Layer-1-over-IP driver Rev. 2.00
0 virtual devices registered
intel_pstate: CPU model not supported
usnic_verbs: Cisco VIC (USNIC) Verbs Driver v1.0.3 (December 19, 2013)
usnic_verbs:usnic_uiom_init:566:
IOMMU required but not present or enabled.  USNIC QPs will not function w/o  
enabling IOMMU
usnic_verbs:usnic_ib_init:661:
Unable to initialize umem with err -1
iscsi: registered transport (iser)
OPA Virtual Network Driver - v1.0
hidraw: raw HID events driver (C) Jiri Kosina
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
NET: Registered protocol family 40
ashmem: initialized
erofs: initializing erofs 1.0pre1
erofs: successfully to initialize erofs
usbcore: registered new interface driver snd-usb-audio
drop_monitor: Initializing network drop monitor service
NET: Registered protocol family 26
GACT probability on
Mirror/redirect action on
Simple TC action Loaded
netem: version 1.3
u32 classifier
     Performance counters on
     input device check on
     Actions configured
nf_conntrack_irc: failed to register helpers
nf_conntrack_sane: failed to register helpers
nf_conntrack_sip: failed to register helpers
xt_time: kernel timezone is -0000
IPVS: Registered protocols (TCP, UDP, SCTP, AH, ESP)
IPVS: Connection hash table configured (size=4096, memory=64Kbytes)
IPVS: ipvs loaded.
IPVS: [rr] scheduler registered.
IPVS: [wrr] scheduler registered.
IPVS: [lc] scheduler registered.
IPVS: [wlc] scheduler registered.
IPVS: [fo] scheduler registered.
IPVS: [ovf] scheduler registered.
IPVS: [lblc] scheduler registered.
IPVS: [lblcr] scheduler registered.
IPVS: [dh] scheduler registered.
IPVS: [sh] scheduler registered.
IPVS: [mh] scheduler registered.
IPVS: [sed] scheduler registered.
IPVS: [nq] scheduler registered.
IPVS: ftp: loaded support on port[0] = 21
IPVS: [sip] pe registered.
ipip: IPv4 and MPLS over IPv4 tunneling driver
gre: GRE over IPv4 demultiplexor driver
ip_gre: GRE over IPv4 tunneling driver
IPv4 over IPsec tunneling driver
ipt_CLUSTERIP: ClusterIP Version 0.8 loaded successfully
Initializing XFRM netlink socket
IPsec XFRM device driver
NET: Registered protocol family 10
Segment Routing with IPv6
mip6: Mobile IPv6
sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
ip6_gre: GRE over IPv6 tunneling driver
NET: Registered protocol family 17
NET: Registered protocol family 15
Bridge firewalling registered
NET: Registered protocol family 9
X25: Linux Version 0.2
NET: Registered protocol family 6
NET: Registered protocol family 11
NET: Registered protocol family 3
can: controller area network core (rev 20170425 abi 9)
NET: Registered protocol family 29
can: raw protocol (rev 20170425)
can: broadcast manager protocol (rev 20170425 t)
can: netlink gateway (rev 20170425) max_hops=1
Bluetooth: RFCOMM TTY layer initialized
Bluetooth: RFCOMM socket layer initialized
Bluetooth: RFCOMM ver 1.11
Bluetooth: BNEP (Ethernet Emulation) ver 1.3
Bluetooth: BNEP filters: protocol multicast
Bluetooth: BNEP socket layer initialized
Bluetooth: CMTP (CAPI Emulation) ver 1.0
Bluetooth: CMTP socket layer initialized
Bluetooth: HIDP (Human Interface Emulation) ver 1.2
Bluetooth: HIDP socket layer initialized
RPC: Registered rdma transport module.
RPC: Registered rdma backchannel transport module.
NET: Registered protocol family 33
Key type rxrpc registered
Key type rxrpc_s registered
NET: Registered protocol family 41
lec:lane_module_init: lec.c: initialized
mpoa:atm_mpoa_init: mpc.c: initialized
l2tp_core: L2TP core driver, V2.0
l2tp_ppp: PPPoL2TP kernel driver, V2.0
l2tp_ip: L2TP IP encapsulation support (L2TPv3)
l2tp_netlink: L2TP netlink interface
l2tp_eth: L2TP ethernet pseudowire support (L2TPv3)
l2tp_ip6: L2TP IP encapsulation support for IPv6 (L2TPv3)
8021q: 802.1Q VLAN Support v1.8
DCCP: Activated CCID 2 (TCP-like)
DCCP: Activated CCID 3 (TCP-Friendly Rate Control)
sctp: Hash tables configured (bind 64/64)
NET: Registered protocol family 21
Registered RDS/infiniband transport
Registered RDS/tcp transport
tipc: Activated (version 2.0.0)
NET: Registered protocol family 30
tipc: Started in single node mode
NET: Registered protocol family 43
9pnet: Installing 9P2000 support
NET: Registered protocol family 37
NET: Registered protocol family 36
Key type dns_resolver registered
Key type ceph registered
libceph: loaded (mon/osd proto 15/24)
batman_adv: B.A.T.M.A.N. advanced 2019.3 (compatibility version 15) loaded
openvswitch: Open vSwitch switching datapath
mpls_gso: MPLS GSO support
AVX2 version of gcm_enc/dec engaged.
AES CTR mode by8 optimization enabled
sched_clock: Marking stable (11023009686, 22427228)->(11169299490,  
-123862576)
registered taskstats version 1
Loading compiled-in X.509 certificates
zswap: loaded using pool lzo/zbud
Btrfs loaded, crc32c=crc32c-intel
Key type big_key registered
Key type encrypted registered
AppArmor: AppArmor sha1 policy hashing enabled
ima: No TPM chip found, activating TPM-bypass!
ima: Allocated hash algorithm: sha256
No architecture policies found
evm: Initialising EVM extended attributes:
evm: security.selinux
evm: security.SMACK64
evm: security.SMACK64EXEC
evm: security.SMACK64TRANSMUTE
evm: security.SMACK64MMAP
evm: security.apparmor
evm: security.ima
evm: security.capability
evm: HMAC attrs: 0x1
PM:   Magic number: 11:503:480
usb usb18-port1: hash matches
usb usb17-port2: hash matches
bdi 31:0: hash matches
printk: console [netcon0] enabled
netconsole: network logging started
gtp: GTP module loaded (pdp ctx size 104 bytes)
------------[ cut here ]------------
__dev_pm_qos_remove_request() called for unknown object
WARNING: CPU: 1 PID: 1 at drivers/base/power/qos.c:486  
__dev_pm_qos_remove_request+0x3d3/0x4d0 drivers/base/power/qos.c:486


---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

^ permalink raw reply

* [PATCH V2 13/13] intel_rapl: Fix module autoloading issue
From: Zhang Rui @ 2019-07-04 16:34 UTC (permalink / raw)
  To: rjw; +Cc: linux-pm, srinivas.pandruvada, rui.zhang
In-Reply-To: <1562258085-3165-1-git-send-email-rui.zhang@intel.com>

intel_rapl driver used to have a list of cpuids, which is used to
1. check if the processor support RAPL MSRs
2. do some cpu model specific setting
3. module autoloading

Now, the cpu model specific setting are moved to intel_rapl_common.c as
part of the common code, because the setup is also needed by RAPL MMIO
interface on those platforms.
But removing the cpuid list from intel_rapl MSR interface driver results
in that the driver can not be loaded automatically.

Maintaining another copy of the cpuid list in intel_rapl_msr.c does not make
sense because it increases the complexity when enabling RAPL support on a
new cpu model.

Fix the problem by creating an "intel_rapl_msr" platform device in the
common code, and make RAPL MSR interface driver (intel_rapl_msr.c) probe the
platform device directly.

Reviewed-and-tested-by: Pandruvada, Srinivas <srinivas.pandruvada@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/powercap/intel_rapl_common.c | 45 ++++++++++++++++++++++--------------
 drivers/powercap/intel_rapl_msr.c    | 24 +++++++++++++++----
 2 files changed, 48 insertions(+), 21 deletions(-)

diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c
index b6e1d33..06dbc64 100644
--- a/drivers/powercap/intel_rapl_common.c
+++ b/drivers/powercap/intel_rapl_common.c
@@ -18,10 +18,11 @@
 #include <linux/cpu.h>
 #include <linux/powercap.h>
 #include <linux/suspend.h>
-#include <asm/iosf_mbi.h>
 #include <linux/intel_rapl.h>
-
 #include <linux/processor.h>
+#include <linux/platform_device.h>
+
+#include <asm/iosf_mbi.h>
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
 
@@ -136,8 +137,6 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
 static u64 rapl_unit_xlate(struct rapl_domain *rd,
 			   enum unit_type type, u64 value, int to_raw);
 static void package_power_limit_irq_save(struct rapl_package *rp);
-static int rapl_init_core(void);
-static void rapl_remove_core(void);
 
 static LIST_HEAD(rapl_packages);	/* guarded by CPU hotplug lock */
 
@@ -1262,8 +1261,6 @@ void rapl_remove_package(struct rapl_package *rp)
 	powercap_unregister_zone(rp->priv->control_type,
 				 &rd_package->power_zone);
 	list_del(&rp->plist);
-	if (list_empty(&rapl_packages))
-		rapl_remove_core();
 	kfree(rp);
 }
 EXPORT_SYMBOL_GPL(rapl_remove_package);
@@ -1292,10 +1289,6 @@ struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv)
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	int ret;
 
-	ret = rapl_init_core();
-	if (ret)
-		return ERR_PTR(ret);
-
 	rp = kzalloc(sizeof(struct rapl_package), GFP_KERNEL);
 	if (!rp)
 		return ERR_PTR(-ENOMEM);
@@ -1413,14 +1406,13 @@ static struct notifier_block rapl_pm_notifier = {
 	.notifier_call = rapl_pm_callback,
 };
 
-static int rapl_init_core(void)
+static struct platform_device *rapl_msr_platdev;
+
+static int __init rapl_init(void)
 {
 	const struct x86_cpu_id *id;
 	int ret;
 
-	if (rapl_defaults)
-		return 0;
-
 	id = x86_match_cpu(rapl_ids);
 	if (!id) {
 		pr_err("driver does not support CPU family %d model %d\n",
@@ -1432,16 +1424,35 @@ static int rapl_init_core(void)
 	rapl_defaults = (struct rapl_defaults *)id->driver_data;
 
 	ret = register_pm_notifier(&rapl_pm_notifier);
+	if (ret)
+		return ret;
 
-	return 0;
+	rapl_msr_platdev = platform_device_alloc("intel_rapl_msr", 0);
+	if (!rapl_msr_platdev) {
+		ret = -ENOMEM;
+		goto end;
+	}
+
+	ret = platform_device_add(rapl_msr_platdev);
+	if (ret)
+		platform_device_put(rapl_msr_platdev);
+
+end:
+	if (ret)
+		unregister_pm_notifier(&rapl_pm_notifier);
+
+	return ret;
 }
 
-static void rapl_remove_core(void)
+static void __exit rapl_exit(void)
 {
+	platform_device_unregister(rapl_msr_platdev);
 	unregister_pm_notifier(&rapl_pm_notifier);
-	rapl_defaults = NULL;
 }
 
+module_init(rapl_init);
+module_exit(rapl_exit);
+
 MODULE_DESCRIPTION("Intel Runtime Average Power Limit (RAPL) common code");
 MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c
index bc14a45..d548796 100644
--- a/drivers/powercap/intel_rapl_msr.c
+++ b/drivers/powercap/intel_rapl_msr.c
@@ -20,6 +20,7 @@
 #include <linux/suspend.h>
 #include <linux/intel_rapl.h>
 #include <linux/processor.h>
+#include <linux/platform_device.h>
 
 #include <asm/iosf_mbi.h>
 #include <asm/cpu_device_id.h>
@@ -122,7 +123,7 @@ static int rapl_msr_write_raw(int cpu, struct reg_action *ra)
 	return ra->err;
 }
 
-static int __init rapl_msr_init(void)
+static int rapl_msr_probe(struct platform_device *pdev)
 {
 	int ret;
 
@@ -152,15 +153,30 @@ static int __init rapl_msr_init(void)
 	return ret;
 }
 
-static void __exit rapl_msr_exit(void)
+static int rapl_msr_remove(struct platform_device *pdev)
 {
 	cpuhp_remove_state(rapl_msr_priv.pcap_rapl_online);
 	rapl_remove_platform_domain(&rapl_msr_priv);
 	powercap_unregister_control_type(rapl_msr_priv.control_type);
+	return 0;
 }
 
-module_init(rapl_msr_init);
-module_exit(rapl_msr_exit);
+static const struct platform_device_id rapl_msr_ids[] = {
+	{ .name = "intel_rapl_msr", },
+	{}
+};
+MODULE_DEVICE_TABLE(platform, rapl_msr_ids);
+
+static struct platform_driver intel_rapl_msr_driver = {
+	.probe = rapl_msr_probe,
+	.remove = rapl_msr_remove,
+	.id_table = rapl_msr_ids,
+	.driver = {
+		.name = "intel_rapl_msr",
+	},
+};
+
+module_platform_driver(intel_rapl_msr_driver);
 
 MODULE_DESCRIPTION("Driver for Intel RAPL (Running Average Power Limit) control via MSR interface");
 MODULE_AUTHOR("Zhang Rui <rui.zhang@intel.com>");
-- 
2.7.4


^ permalink raw reply related

* [PATCH V2 12/13] int340X/processor_thermal_device: add support for MMIO RAPL
From: Zhang Rui @ 2019-07-04 16:34 UTC (permalink / raw)
  To: rjw; +Cc: linux-pm, srinivas.pandruvada, rui.zhang
In-Reply-To: <1562258085-3165-1-git-send-email-rui.zhang@intel.com>

Introduce MMIO RAPL support as Intel processor_thermal device exposes the
capability to do RAPL control via MMIO registers.

Reviewed-and-tested-by: Pandruvada, Srinivas <srinivas.pandruvada@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/thermal/intel/int340x_thermal/Kconfig      |   6 +
 .../int340x_thermal/processor_thermal_device.c     | 173 ++++++++++++++++++++-
 2 files changed, 173 insertions(+), 6 deletions(-)

diff --git a/drivers/thermal/intel/int340x_thermal/Kconfig b/drivers/thermal/intel/int340x_thermal/Kconfig
index 5333e01..7979075 100644
--- a/drivers/thermal/intel/int340x_thermal/Kconfig
+++ b/drivers/thermal/intel/int340x_thermal/Kconfig
@@ -40,4 +40,10 @@ config INT3406_THERMAL
 	  brightness in order to address a thermal condition or to reduce
 	  power consumed by display device.
 
+config PROC_THERMAL_MMIO_RAPL
+	bool
+	depends on 64BIT
+	depends on POWERCAP
+	select INTEL_RAPL_CORE
+	default y
 endif
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
index 53c84fa..06c7ab3 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
@@ -11,6 +11,8 @@
 #include <linux/platform_device.h>
 #include <linux/acpi.h>
 #include <linux/thermal.h>
+#include <linux/cpuhotplug.h>
+#include <linux/intel_rapl.h>
 #include "int340x_thermal_zone.h"
 #include "../intel_soc_dts_iosf.h"
 
@@ -37,6 +39,8 @@
 /* GeminiLake thermal reporting device */
 #define PCI_DEVICE_ID_PROC_GLK_THERMAL	0x318C
 
+#define DRV_NAME "proc_thermal"
+
 struct power_config {
 	u32	index;
 	u32	min_uw;
@@ -52,6 +56,7 @@ struct proc_thermal_device {
 	struct power_config power_limits[2];
 	struct int34x_thermal_zone *int340x_zone;
 	struct intel_soc_dts_sensors *soc_dts;
+	void __iomem *mmio_base;
 };
 
 enum proc_thermal_emum_mode_type {
@@ -60,6 +65,12 @@ enum proc_thermal_emum_mode_type {
 	PROC_THERMAL_PLATFORM_DEV
 };
 
+struct rapl_mmio_regs {
+	u64 reg_unit;
+	u64 regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX];
+	int limits[RAPL_DOMAIN_MAX];
+};
+
 /*
  * We can have only one type of enumeration, PCI or Platform,
  * not both. So we don't need instance specific data.
@@ -367,8 +378,151 @@ static irqreturn_t proc_thermal_pci_msi_irq(int irq, void *devid)
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_PROC_THERMAL_MMIO_RAPL
+
+#define MCHBAR 0
+
+/* RAPL Support via MMIO interface */
+static struct rapl_if_priv rapl_mmio_priv;
+
+static int rapl_mmio_cpu_online(unsigned int cpu)
+{
+	struct rapl_package *rp;
+
+	/* mmio rapl supports package 0 only for now */
+	if (topology_physical_package_id(cpu))
+		return 0;
+
+	rp = rapl_find_package_domain(cpu, &rapl_mmio_priv);
+	if (!rp) {
+		rp = rapl_add_package(cpu, &rapl_mmio_priv);
+		if (IS_ERR(rp))
+			return PTR_ERR(rp);
+	}
+	cpumask_set_cpu(cpu, &rp->cpumask);
+	return 0;
+}
+
+static int rapl_mmio_cpu_down_prep(unsigned int cpu)
+{
+	struct rapl_package *rp;
+	int lead_cpu;
+
+	rp = rapl_find_package_domain(cpu, &rapl_mmio_priv);
+	if (!rp)
+		return 0;
+
+	cpumask_clear_cpu(cpu, &rp->cpumask);
+	lead_cpu = cpumask_first(&rp->cpumask);
+	if (lead_cpu >= nr_cpu_ids)
+		rapl_remove_package(rp);
+	else if (rp->lead_cpu == cpu)
+		rp->lead_cpu = lead_cpu;
+	return 0;
+}
+
+static int rapl_mmio_read_raw(int cpu, struct reg_action *ra)
+{
+	if (!ra->reg)
+		return -EINVAL;
+
+	ra->value = readq((void __iomem *)ra->reg);
+	ra->value &= ra->mask;
+	return 0;
+}
+
+static int rapl_mmio_write_raw(int cpu, struct reg_action *ra)
+{
+	u64 val;
+
+	if (!ra->reg)
+		return -EINVAL;
+
+	val = readq((void __iomem *)ra->reg);
+	val &= ~ra->mask;
+	val |= ra->value;
+	writeq(val, (void __iomem *)ra->reg);
+	return 0;
+}
+
+static int proc_thermal_rapl_add(struct pci_dev *pdev,
+				 struct proc_thermal_device *proc_priv,
+				 struct rapl_mmio_regs *rapl_regs)
+{
+	enum rapl_domain_reg_id reg;
+	enum rapl_domain_type domain;
+	int ret;
+
+	if (!rapl_regs)
+		return 0;
+
+	ret = pcim_iomap_regions(pdev, 1 << MCHBAR, DRV_NAME);
+	if (ret) {
+		dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
+		return -ENOMEM;
+	}
+
+	proc_priv->mmio_base = pcim_iomap_table(pdev)[MCHBAR];
+
+	for (domain = RAPL_DOMAIN_PACKAGE; domain < RAPL_DOMAIN_MAX; domain++) {
+		for (reg = RAPL_DOMAIN_REG_LIMIT; reg < RAPL_DOMAIN_REG_MAX; reg++)
+			if (rapl_regs->regs[domain][reg])
+				rapl_mmio_priv.regs[domain][reg] =
+						(u64)proc_priv->mmio_base +
+						rapl_regs->regs[domain][reg];
+		rapl_mmio_priv.limits[domain] = rapl_regs->limits[domain];
+	}
+	rapl_mmio_priv.reg_unit = (u64)proc_priv->mmio_base + rapl_regs->reg_unit;
+
+	rapl_mmio_priv.read_raw = rapl_mmio_read_raw;
+	rapl_mmio_priv.write_raw = rapl_mmio_write_raw;
+
+	rapl_mmio_priv.control_type = powercap_register_control_type(NULL, "intel-rapl-mmio", NULL);
+	if (IS_ERR(rapl_mmio_priv.control_type)) {
+		pr_debug("failed to register powercap control_type.\n");
+		return PTR_ERR(rapl_mmio_priv.control_type);
+	}
+
+	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powercap/rapl:online",
+				rapl_mmio_cpu_online, rapl_mmio_cpu_down_prep);
+	if (ret < 0) {
+		powercap_unregister_control_type(rapl_mmio_priv.control_type);
+		return ret;
+	}
+	rapl_mmio_priv.pcap_rapl_online = ret;
+
+	return 0;
+}
+
+static void proc_thermal_rapl_remove(void)
+{
+	cpuhp_remove_state(rapl_mmio_priv.pcap_rapl_online);
+	powercap_unregister_control_type(rapl_mmio_priv.control_type);
+}
+
+static const struct rapl_mmio_regs rapl_mmio_hsw = {
+	.reg_unit = 0x5938,
+	.regs[RAPL_DOMAIN_PACKAGE] = { 0x59a0, 0x593c, 0x58f0, 0, 0x5930},
+	.regs[RAPL_DOMAIN_DRAM] = { 0x58e0, 0x58e8, 0x58ec, 0, 0},
+	.limits[RAPL_DOMAIN_PACKAGE] = 2,
+	.limits[RAPL_DOMAIN_DRAM] = 2,
+};
+
+#else
+
+static int proc_thermal_rapl_add(struct pci_dev *pdev,
+				 struct proc_thermal_device *proc_priv,
+				 struct rapl_mmio_regs *rapl_regs)
+{
+	return 0;
+}
+static void proc_thermal_rapl_remove(void) {}
+static const struct rapl_mmio_regs rapl_mmio_hsw;
+
+#endif /* CONFIG_MMIO_RAPL */
+
 static int  proc_thermal_pci_probe(struct pci_dev *pdev,
-				   const struct pci_device_id *unused)
+				   const struct pci_device_id *id)
 {
 	struct proc_thermal_device *proc_priv;
 	int ret;
@@ -378,15 +532,21 @@ static int  proc_thermal_pci_probe(struct pci_dev *pdev,
 		return -ENODEV;
 	}
 
-	ret = pci_enable_device(pdev);
+	ret = pcim_enable_device(pdev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "error: could not enable device\n");
 		return ret;
 	}
 
 	ret = proc_thermal_add(&pdev->dev, &proc_priv);
+	if (ret)
+		return ret;
+
+	ret = proc_thermal_rapl_add(pdev, proc_priv,
+				(struct rapl_mmio_regs *)id->driver_data);
 	if (ret) {
-		pci_disable_device(pdev);
+		dev_err(&pdev->dev, "failed to add RAPL MMIO interface\n");
+		proc_thermal_remove(proc_priv);
 		return ret;
 	}
 
@@ -439,14 +599,15 @@ static void  proc_thermal_pci_remove(struct pci_dev *pdev)
 			pci_disable_msi(pdev);
 		}
 	}
+	proc_thermal_rapl_remove();
 	proc_thermal_remove(proc_priv);
-	pci_disable_device(pdev);
 }
 
 static const struct pci_device_id proc_thermal_pci_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BDW_THERMAL)},
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_HSB_THERMAL)},
-	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_SKL_THERMAL)},
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_SKL_THERMAL),
+		.driver_data = (kernel_ulong_t)&rapl_mmio_hsw, },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BSW_THERMAL)},
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXT0_THERMAL)},
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXT1_THERMAL)},
@@ -461,7 +622,7 @@ static const struct pci_device_id proc_thermal_pci_ids[] = {
 MODULE_DEVICE_TABLE(pci, proc_thermal_pci_ids);
 
 static struct pci_driver proc_thermal_pci_driver = {
-	.name		= "proc_thermal",
+	.name		= DRV_NAME,
 	.probe		= proc_thermal_pci_probe,
 	.remove		= proc_thermal_pci_remove,
 	.id_table	= proc_thermal_pci_ids,
-- 
2.7.4


^ permalink raw reply related

* [PATCH V2 11/13] intel_rapl: support two power limits for every RAPL domain
From: Zhang Rui @ 2019-07-04 16:34 UTC (permalink / raw)
  To: rjw; +Cc: linux-pm, srinivas.pandruvada, rui.zhang
In-Reply-To: <1562258085-3165-1-git-send-email-rui.zhang@intel.com>

RAPL MSR interface supports 2 power limits for package domain, and 1 power
limit for other domains, while RAPL MMIO interface supports 2 power limits
for both package and dram domains.
And when 2 power limits are supported, the FW_LOCK bit is in bit 63 of the
register, instead of bit 31.

Remove the assumption that only pakcage domain supports 2 power limits.
And allow the RAPL interface driver to specify the number of power limits
supported, for every single RAPL domain it owns..

Reviewed-and-tested-by: Pandruvada, Srinivas <srinivas.pandruvada@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/powercap/intel_rapl_common.c | 72 +++++++++++++-----------------------
 drivers/powercap/intel_rapl_msr.c    |  1 +
 include/linux/intel_rapl.h           |  2 +
 3 files changed, 28 insertions(+), 47 deletions(-)

diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c
index d648411..b6e1d33 100644
--- a/drivers/powercap/intel_rapl_common.c
+++ b/drivers/powercap/intel_rapl_common.c
@@ -38,8 +38,8 @@
 #define POWER_LIMIT2_MASK       (0x7FFFULL<<32)
 #define POWER_LIMIT2_ENABLE     BIT_ULL(47)
 #define POWER_LIMIT2_CLAMP      BIT_ULL(48)
-#define POWER_PACKAGE_LOCK      BIT_ULL(63)
-#define POWER_PP_LOCK           BIT(31)
+#define POWER_HIGH_LOCK         BIT_ULL(63)
+#define POWER_LOW_LOCK          BIT(31)
 
 #define TIME_WINDOW1_MASK       (0x7FULL<<17)
 #define TIME_WINDOW2_MASK       (0x7FULL<<49)
@@ -513,60 +513,38 @@ static const struct powercap_zone_constraint_ops constraint_ops = {
 /* called after domain detection and package level data are set */
 static void rapl_init_domains(struct rapl_package *rp)
 {
-	int i;
+	enum rapl_domain_type i;
+	enum rapl_domain_reg_id j;
 	struct rapl_domain *rd = rp->domains;
 
 	for (i = 0; i < RAPL_DOMAIN_MAX; i++) {
 		unsigned int mask = rp->domain_map & (1 << i);
 
-		rd->regs[RAPL_DOMAIN_REG_LIMIT] =
-		    rp->priv->regs[i][RAPL_DOMAIN_REG_LIMIT];
-		rd->regs[RAPL_DOMAIN_REG_STATUS] =
-		    rp->priv->regs[i][RAPL_DOMAIN_REG_STATUS];
-		rd->regs[RAPL_DOMAIN_REG_PERF] =
-		    rp->priv->regs[i][RAPL_DOMAIN_REG_PERF];
-		rd->regs[RAPL_DOMAIN_REG_POLICY] =
-		    rp->priv->regs[i][RAPL_DOMAIN_REG_POLICY];
-		rd->regs[RAPL_DOMAIN_REG_INFO] =
-		    rp->priv->regs[i][RAPL_DOMAIN_REG_INFO];
-
-		switch (mask) {
-		case BIT(RAPL_DOMAIN_PACKAGE):
-			rd->name = rapl_domain_names[RAPL_DOMAIN_PACKAGE];
-			rd->id = RAPL_DOMAIN_PACKAGE;
-			rd->rpl[0].prim_id = PL1_ENABLE;
-			rd->rpl[0].name = pl1_name;
+		if (!mask)
+			continue;
+
+		rd->rp = rp;
+		rd->name = rapl_domain_names[i];
+		rd->id = i;
+		rd->rpl[0].prim_id = PL1_ENABLE;
+		rd->rpl[0].name = pl1_name;
+		/* some domain may support two power limits */
+		if (rp->priv->limits[i] == 2) {
 			rd->rpl[1].prim_id = PL2_ENABLE;
 			rd->rpl[1].name = pl2_name;
-			break;
-		case BIT(RAPL_DOMAIN_PP0):
-			rd->name = rapl_domain_names[RAPL_DOMAIN_PP0];
-			rd->id = RAPL_DOMAIN_PP0;
-			rd->rpl[0].prim_id = PL1_ENABLE;
-			rd->rpl[0].name = pl1_name;
-			break;
-		case BIT(RAPL_DOMAIN_PP1):
-			rd->name = rapl_domain_names[RAPL_DOMAIN_PP1];
-			rd->id = RAPL_DOMAIN_PP1;
-			rd->rpl[0].prim_id = PL1_ENABLE;
-			rd->rpl[0].name = pl1_name;
-			break;
-		case BIT(RAPL_DOMAIN_DRAM):
-			rd->name = rapl_domain_names[RAPL_DOMAIN_DRAM];
-			rd->id = RAPL_DOMAIN_DRAM;
-			rd->rpl[0].prim_id = PL1_ENABLE;
-			rd->rpl[0].name = pl1_name;
+		}
+
+		for (j = 0; j < RAPL_DOMAIN_REG_MAX; j++)
+			rd->regs[j] = rp->priv->regs[i][j];
+
+		if (i == RAPL_DOMAIN_DRAM) {
 			rd->domain_energy_unit =
 			    rapl_defaults->dram_domain_energy_unit;
 			if (rd->domain_energy_unit)
 				pr_info("DRAM domain energy unit %dpj\n",
 					rd->domain_energy_unit);
-			break;
-		}
-		if (mask) {
-			rd->rp = rp;
-			rd++;
 		}
+		rd++;
 	}
 }
 
@@ -613,7 +591,7 @@ static struct rapl_primitive_info rpi[] = {
 			    RAPL_DOMAIN_REG_LIMIT, POWER_UNIT, 0),
 	PRIMITIVE_INFO_INIT(POWER_LIMIT2, POWER_LIMIT2_MASK, 32,
 			    RAPL_DOMAIN_REG_LIMIT, POWER_UNIT, 0),
-	PRIMITIVE_INFO_INIT(FW_LOCK, POWER_PP_LOCK, 31,
+	PRIMITIVE_INFO_INIT(FW_LOCK, POWER_LOW_LOCK, 31,
 			    RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
 	PRIMITIVE_INFO_INIT(PL1_ENABLE, POWER_LIMIT1_ENABLE, 15,
 			    RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
@@ -675,9 +653,9 @@ static int rapl_read_data_raw(struct rapl_domain *rd,
 
 	cpu = rd->rp->lead_cpu;
 
-	/* special-case package domain, which uses a different bit */
-	if (prim == FW_LOCK && rd->id == RAPL_DOMAIN_PACKAGE) {
-		rp->mask = POWER_PACKAGE_LOCK;
+	/* domain with 2 limits has different bit */
+	if (prim == FW_LOCK && rd->rp->priv->limits[rd->id] == 2) {
+		rp->mask = POWER_HIGH_LOCK;
 		rp->shift = 63;
 	}
 	/* non-hardware data are collected by the polling thread */
diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c
index 6cd8a8f..bc14a45 100644
--- a/drivers/powercap/intel_rapl_msr.c
+++ b/drivers/powercap/intel_rapl_msr.c
@@ -41,6 +41,7 @@ static struct rapl_if_priv rapl_msr_priv = {
 		MSR_DRAM_POWER_LIMIT, MSR_DRAM_ENERGY_STATUS, MSR_DRAM_PERF_STATUS, 0, MSR_DRAM_POWER_INFO },
 	.regs[RAPL_DOMAIN_PLATFORM] = {
 		MSR_PLATFORM_POWER_LIMIT, MSR_PLATFORM_ENERGY_STATUS, 0, 0, 0},
+	.limits[RAPL_DOMAIN_PACKAGE] = 2,
 };
 
 /* Handles CPU hotplug on multi-socket systems.
diff --git a/include/linux/intel_rapl.h b/include/linux/intel_rapl.h
index 649e199..0c179d9 100644
--- a/include/linux/intel_rapl.h
+++ b/include/linux/intel_rapl.h
@@ -104,6 +104,7 @@ struct reg_action {
  * @pcap_rapl_online:		CPU hotplug state for each RAPL interface.
  * @reg_unit:			Register for getting energy/power/time unit.
  * @regs:			Register sets for different RAPL Domains.
+ * @limits:			Number of power limits supported by each domain.
  * @read_raw:			Callback for reading RAPL interface specific
  *				registers.
  * @write_raw:			Callback for writing RAPL interface specific
@@ -115,6 +116,7 @@ struct rapl_if_priv {
 	enum cpuhp_state pcap_rapl_online;
 	u64 reg_unit;
 	u64 regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX];
+	int limits[RAPL_DOMAIN_MAX];
 	int (*read_raw)(int cpu, struct reg_action *ra);
 	int (*write_raw)(int cpu, struct reg_action *ra);
 };
-- 
2.7.4


^ permalink raw reply related

* [PATCH V2 09/13] intel_rapl: abstract RAPL common code
From: Zhang Rui @ 2019-07-04 16:34 UTC (permalink / raw)
  To: rjw; +Cc: linux-pm, srinivas.pandruvada, rui.zhang
In-Reply-To: <1562258085-3165-1-git-send-email-rui.zhang@intel.com>

Split intel_rapl.c to intel_rapl_common.c and intel_rapl_msr.c, where
intel_rapl_common.c contains the common code that can be used by both MSR
and MMIO interface.
intel_rapl_msr.c contains the implementation of RAPL MSR interface.

Reviewed-and-tested-by: Pandruvada, Srinivas <srinivas.pandruvada@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/powercap/Kconfig             |   11 +-
 drivers/powercap/Makefile            |    3 +-
 drivers/powercap/intel_rapl.c        | 1574 ----------------------------------
 drivers/powercap/intel_rapl_common.c | 1469 +++++++++++++++++++++++++++++++
 drivers/powercap/intel_rapl_msr.c    |  163 ++++
 include/linux/intel_rapl.h           |    7 +
 6 files changed, 1648 insertions(+), 1579 deletions(-)
 delete mode 100644 drivers/powercap/intel_rapl.c
 create mode 100644 drivers/powercap/intel_rapl_common.c
 create mode 100644 drivers/powercap/intel_rapl_msr.c

diff --git a/drivers/powercap/Kconfig b/drivers/powercap/Kconfig
index 42d3798..dc1c138 100644
--- a/drivers/powercap/Kconfig
+++ b/drivers/powercap/Kconfig
@@ -16,14 +16,17 @@ menuconfig POWERCAP
 
 if POWERCAP
 # Client driver configurations go here.
+config INTEL_RAPL_CORE
+	tristate
+
 config INTEL_RAPL
-	tristate "Intel RAPL Support"
+	tristate "Intel RAPL Support via MSR Interface"
 	depends on X86 && IOSF_MBI
-	default n
+	select INTEL_RAPL_CORE
 	---help---
 	  This enables support for the Intel Running Average Power Limit (RAPL)
-	  technology which allows power limits to be enforced and monitored on
-	  modern Intel processors (Sandy Bridge and later).
+	  technology via MSR interface, which allows power limits to be enforced
+	  and monitored on modern Intel processors (Sandy Bridge and later).
 
 	  In RAPL, the platform level settings are divided into domains for
 	  fine grained control. These domains include processor package, DRAM
diff --git a/drivers/powercap/Makefile b/drivers/powercap/Makefile
index 81c8cca..7255c94 100644
--- a/drivers/powercap/Makefile
+++ b/drivers/powercap/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_POWERCAP)	+= powercap_sys.o
-obj-$(CONFIG_INTEL_RAPL) += intel_rapl.o
+obj-$(CONFIG_INTEL_RAPL_CORE) += intel_rapl_common.o
+obj-$(CONFIG_INTEL_RAPL) += intel_rapl_msr.o
 obj-$(CONFIG_IDLE_INJECT) += idle_inject.o
diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c
deleted file mode 100644
index aa54c06..0000000
--- a/drivers/powercap/intel_rapl.c
+++ /dev/null
@@ -1,1574 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Intel Running Average Power Limit (RAPL) Driver
- * Copyright (c) 2013, Intel Corporation.
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/list.h>
-#include <linux/types.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/log2.h>
-#include <linux/bitmap.h>
-#include <linux/delay.h>
-#include <linux/sysfs.h>
-#include <linux/cpu.h>
-#include <linux/powercap.h>
-#include <linux/suspend.h>
-#include <linux/intel_rapl.h>
-
-#include <asm/iosf_mbi.h>
-#include <asm/processor.h>
-#include <asm/cpu_device_id.h>
-#include <asm/intel-family.h>
-
-/* Local defines */
-#define MSR_PLATFORM_POWER_LIMIT	0x0000065C
-
-/* bitmasks for RAPL MSRs, used by primitive access functions */
-#define ENERGY_STATUS_MASK      0xffffffff
-
-#define POWER_LIMIT1_MASK       0x7FFF
-#define POWER_LIMIT1_ENABLE     BIT(15)
-#define POWER_LIMIT1_CLAMP      BIT(16)
-
-#define POWER_LIMIT2_MASK       (0x7FFFULL<<32)
-#define POWER_LIMIT2_ENABLE     BIT_ULL(47)
-#define POWER_LIMIT2_CLAMP      BIT_ULL(48)
-#define POWER_PACKAGE_LOCK      BIT_ULL(63)
-#define POWER_PP_LOCK           BIT(31)
-
-#define TIME_WINDOW1_MASK       (0x7FULL<<17)
-#define TIME_WINDOW2_MASK       (0x7FULL<<49)
-
-#define POWER_UNIT_OFFSET	0
-#define POWER_UNIT_MASK		0x0F
-
-#define ENERGY_UNIT_OFFSET	0x08
-#define ENERGY_UNIT_MASK	0x1F00
-
-#define TIME_UNIT_OFFSET	0x10
-#define TIME_UNIT_MASK		0xF0000
-
-#define POWER_INFO_MAX_MASK     (0x7fffULL<<32)
-#define POWER_INFO_MIN_MASK     (0x7fffULL<<16)
-#define POWER_INFO_MAX_TIME_WIN_MASK     (0x3fULL<<48)
-#define POWER_INFO_THERMAL_SPEC_MASK     0x7fff
-
-#define PERF_STATUS_THROTTLE_TIME_MASK 0xffffffff
-#define PP_POLICY_MASK         0x1F
-
-/* Non HW constants */
-#define RAPL_PRIMITIVE_DERIVED       BIT(1) /* not from raw data */
-#define RAPL_PRIMITIVE_DUMMY         BIT(2)
-
-#define TIME_WINDOW_MAX_MSEC 40000
-#define TIME_WINDOW_MIN_MSEC 250
-#define ENERGY_UNIT_SCALE    1000 /* scale from driver unit to powercap unit */
-enum unit_type {
-	ARBITRARY_UNIT, /* no translation */
-	POWER_UNIT,
-	ENERGY_UNIT,
-	TIME_UNIT,
-};
-
-/* private data for RAPL MSR Interface */
-static struct rapl_if_priv rapl_msr_priv = {
-	.reg_unit = MSR_RAPL_POWER_UNIT,
-	.regs[RAPL_DOMAIN_PACKAGE] = {
-		MSR_PKG_POWER_LIMIT, MSR_PKG_ENERGY_STATUS, MSR_PKG_PERF_STATUS, 0, MSR_PKG_POWER_INFO },
-	.regs[RAPL_DOMAIN_PP0] = {
-		MSR_PP0_POWER_LIMIT, MSR_PP0_ENERGY_STATUS, 0, MSR_PP0_POLICY, 0 },
-	.regs[RAPL_DOMAIN_PP1] = {
-		MSR_PP1_POWER_LIMIT, MSR_PP1_ENERGY_STATUS, 0, MSR_PP1_POLICY, 0 },
-	.regs[RAPL_DOMAIN_DRAM] = {
-		MSR_DRAM_POWER_LIMIT, MSR_DRAM_ENERGY_STATUS, MSR_DRAM_PERF_STATUS, 0, MSR_DRAM_POWER_INFO },
-	.regs[RAPL_DOMAIN_PLATFORM] = {
-		MSR_PLATFORM_POWER_LIMIT, MSR_PLATFORM_ENERGY_STATUS, 0, 0, 0},
-};
-
-/* per domain data, some are optional */
-#define NR_RAW_PRIMITIVES (NR_RAPL_PRIMITIVES - 2)
-
-#define	DOMAIN_STATE_INACTIVE           BIT(0)
-#define	DOMAIN_STATE_POWER_LIMIT_SET    BIT(1)
-#define DOMAIN_STATE_BIOS_LOCKED        BIT(2)
-
-static const char pl1_name[] = "long_term";
-static const char pl2_name[] = "short_term";
-
-#define power_zone_to_rapl_domain(_zone) \
-	container_of(_zone, struct rapl_domain, power_zone)
-
-struct rapl_defaults {
-	u8 floor_freq_reg_addr;
-	int (*check_unit)(struct rapl_package *rp, int cpu);
-	void (*set_floor_freq)(struct rapl_domain *rd, bool mode);
-	u64 (*compute_time_window)(struct rapl_package *rp, u64 val,
-				bool to_raw);
-	unsigned int dram_domain_energy_unit;
-};
-static struct rapl_defaults *rapl_defaults;
-
-/* Sideband MBI registers */
-#define IOSF_CPU_POWER_BUDGET_CTL_BYT (0x2)
-#define IOSF_CPU_POWER_BUDGET_CTL_TNG (0xdf)
-
-#define PACKAGE_PLN_INT_SAVED   BIT(0)
-#define MAX_PRIM_NAME (32)
-
-/* per domain data. used to describe individual knobs such that access function
- * can be consolidated into one instead of many inline functions.
- */
-struct rapl_primitive_info {
-	const char *name;
-	u64 mask;
-	int shift;
-	enum rapl_domain_reg_id id;
-	enum unit_type unit;
-	u32 flag;
-};
-
-#define PRIMITIVE_INFO_INIT(p, m, s, i, u, f) {	\
-		.name = #p,			\
-		.mask = m,			\
-		.shift = s,			\
-		.id = i,			\
-		.unit = u,			\
-		.flag = f			\
-	}
-
-static void rapl_init_domains(struct rapl_package *rp);
-static int rapl_read_data_raw(struct rapl_domain *rd,
-			enum rapl_primitives prim,
-			bool xlate, u64 *data);
-static int rapl_write_data_raw(struct rapl_domain *rd,
-			enum rapl_primitives prim,
-			unsigned long long value);
-static u64 rapl_unit_xlate(struct rapl_domain *rd,
-			enum unit_type type, u64 value,
-			int to_raw);
-static void package_power_limit_irq_save(struct rapl_package *rp);
-
-static LIST_HEAD(rapl_packages); /* guarded by CPU hotplug lock */
-
-static const char * const rapl_domain_names[] = {
-	"package",
-	"core",
-	"uncore",
-	"dram",
-	"psys",
-};
-
-/* caller to ensure CPU hotplug lock is held */
-static struct rapl_package *rapl_find_package_domain(int cpu, struct rapl_if_priv *priv)
-{
-	int id = topology_logical_die_id(cpu);
-	struct rapl_package *rp;
-
-	list_for_each_entry(rp, &rapl_packages, plist) {
-		if (rp->id == id && rp->priv->control_type == priv->control_type)
-			return rp;
-	}
-
-	return NULL;
-}
-
-static int get_energy_counter(struct powercap_zone *power_zone, u64 *energy_raw)
-{
-	struct rapl_domain *rd;
-	u64 energy_now;
-
-	/* prevent CPU hotplug, make sure the RAPL domain does not go
-	 * away while reading the counter.
-	 */
-	get_online_cpus();
-	rd = power_zone_to_rapl_domain(power_zone);
-
-	if (!rapl_read_data_raw(rd, ENERGY_COUNTER, true, &energy_now)) {
-		*energy_raw = energy_now;
-		put_online_cpus();
-
-		return 0;
-	}
-	put_online_cpus();
-
-	return -EIO;
-}
-
-static int get_max_energy_counter(struct powercap_zone *pcd_dev, u64 *energy)
-{
-	struct rapl_domain *rd = power_zone_to_rapl_domain(pcd_dev);
-
-	*energy = rapl_unit_xlate(rd, ENERGY_UNIT, ENERGY_STATUS_MASK, 0);
-	return 0;
-}
-
-static int release_zone(struct powercap_zone *power_zone)
-{
-	struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
-	struct rapl_package *rp = rd->rp;
-
-	/* package zone is the last zone of a package, we can free
-	 * memory here since all children has been unregistered.
-	 */
-	if (rd->id == RAPL_DOMAIN_PACKAGE) {
-		kfree(rd);
-		rp->domains = NULL;
-	}
-
-	return 0;
-
-}
-
-static int find_nr_power_limit(struct rapl_domain *rd)
-{
-	int i, nr_pl = 0;
-
-	for (i = 0; i < NR_POWER_LIMITS; i++) {
-		if (rd->rpl[i].name)
-			nr_pl++;
-	}
-
-	return nr_pl;
-}
-
-static int set_domain_enable(struct powercap_zone *power_zone, bool mode)
-{
-	struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
-
-	if (rd->state & DOMAIN_STATE_BIOS_LOCKED)
-		return -EACCES;
-
-	get_online_cpus();
-	rapl_write_data_raw(rd, PL1_ENABLE, mode);
-	if (rapl_defaults->set_floor_freq)
-		rapl_defaults->set_floor_freq(rd, mode);
-	put_online_cpus();
-
-	return 0;
-}
-
-static int get_domain_enable(struct powercap_zone *power_zone, bool *mode)
-{
-	struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
-	u64 val;
-
-	if (rd->state & DOMAIN_STATE_BIOS_LOCKED) {
-		*mode = false;
-		return 0;
-	}
-	get_online_cpus();
-	if (rapl_read_data_raw(rd, PL1_ENABLE, true, &val)) {
-		put_online_cpus();
-		return -EIO;
-	}
-	*mode = val;
-	put_online_cpus();
-
-	return 0;
-}
-
-/* per RAPL domain ops, in the order of rapl_domain_type */
-static const struct powercap_zone_ops zone_ops[] = {
-	/* RAPL_DOMAIN_PACKAGE */
-	{
-		.get_energy_uj = get_energy_counter,
-		.get_max_energy_range_uj = get_max_energy_counter,
-		.release = release_zone,
-		.set_enable = set_domain_enable,
-		.get_enable = get_domain_enable,
-	},
-	/* RAPL_DOMAIN_PP0 */
-	{
-		.get_energy_uj = get_energy_counter,
-		.get_max_energy_range_uj = get_max_energy_counter,
-		.release = release_zone,
-		.set_enable = set_domain_enable,
-		.get_enable = get_domain_enable,
-	},
-	/* RAPL_DOMAIN_PP1 */
-	{
-		.get_energy_uj = get_energy_counter,
-		.get_max_energy_range_uj = get_max_energy_counter,
-		.release = release_zone,
-		.set_enable = set_domain_enable,
-		.get_enable = get_domain_enable,
-	},
-	/* RAPL_DOMAIN_DRAM */
-	{
-		.get_energy_uj = get_energy_counter,
-		.get_max_energy_range_uj = get_max_energy_counter,
-		.release = release_zone,
-		.set_enable = set_domain_enable,
-		.get_enable = get_domain_enable,
-	},
-	/* RAPL_DOMAIN_PLATFORM */
-	{
-		.get_energy_uj = get_energy_counter,
-		.get_max_energy_range_uj = get_max_energy_counter,
-		.release = release_zone,
-		.set_enable = set_domain_enable,
-		.get_enable = get_domain_enable,
-	},
-};
-
-
-/*
- * Constraint index used by powercap can be different than power limit (PL)
- * index in that some  PLs maybe missing due to non-existant MSRs. So we
- * need to convert here by finding the valid PLs only (name populated).
- */
-static int contraint_to_pl(struct rapl_domain *rd, int cid)
-{
-	int i, j;
-
-	for (i = 0, j = 0; i < NR_POWER_LIMITS; i++) {
-		if ((rd->rpl[i].name) && j++ == cid) {
-			pr_debug("%s: index %d\n", __func__, i);
-			return i;
-		}
-	}
-	pr_err("Cannot find matching power limit for constraint %d\n", cid);
-
-	return -EINVAL;
-}
-
-static int set_power_limit(struct powercap_zone *power_zone, int cid,
-			u64 power_limit)
-{
-	struct rapl_domain *rd;
-	struct rapl_package *rp;
-	int ret = 0;
-	int id;
-
-	get_online_cpus();
-	rd = power_zone_to_rapl_domain(power_zone);
-	id = contraint_to_pl(rd, cid);
-	if (id < 0) {
-		ret = id;
-		goto set_exit;
-	}
-
-	rp = rd->rp;
-
-	if (rd->state & DOMAIN_STATE_BIOS_LOCKED) {
-		dev_warn(&power_zone->dev, "%s locked by BIOS, monitoring only\n",
-			rd->name);
-		ret = -EACCES;
-		goto set_exit;
-	}
-
-	switch (rd->rpl[id].prim_id) {
-	case PL1_ENABLE:
-		rapl_write_data_raw(rd, POWER_LIMIT1, power_limit);
-		break;
-	case PL2_ENABLE:
-		rapl_write_data_raw(rd, POWER_LIMIT2, power_limit);
-		break;
-	default:
-		ret = -EINVAL;
-	}
-	if (!ret)
-		package_power_limit_irq_save(rp);
-set_exit:
-	put_online_cpus();
-	return ret;
-}
-
-static int get_current_power_limit(struct powercap_zone *power_zone, int cid,
-					u64 *data)
-{
-	struct rapl_domain *rd;
-	u64 val;
-	int prim;
-	int ret = 0;
-	int id;
-
-	get_online_cpus();
-	rd = power_zone_to_rapl_domain(power_zone);
-	id = contraint_to_pl(rd, cid);
-	if (id < 0) {
-		ret = id;
-		goto get_exit;
-	}
-
-	switch (rd->rpl[id].prim_id) {
-	case PL1_ENABLE:
-		prim = POWER_LIMIT1;
-		break;
-	case PL2_ENABLE:
-		prim = POWER_LIMIT2;
-		break;
-	default:
-		put_online_cpus();
-		return -EINVAL;
-	}
-	if (rapl_read_data_raw(rd, prim, true, &val))
-		ret = -EIO;
-	else
-		*data = val;
-
-get_exit:
-	put_online_cpus();
-
-	return ret;
-}
-
-static int set_time_window(struct powercap_zone *power_zone, int cid,
-								u64 window)
-{
-	struct rapl_domain *rd;
-	int ret = 0;
-	int id;
-
-	get_online_cpus();
-	rd = power_zone_to_rapl_domain(power_zone);
-	id = contraint_to_pl(rd, cid);
-	if (id < 0) {
-		ret = id;
-		goto set_time_exit;
-	}
-
-	switch (rd->rpl[id].prim_id) {
-	case PL1_ENABLE:
-		rapl_write_data_raw(rd, TIME_WINDOW1, window);
-		break;
-	case PL2_ENABLE:
-		rapl_write_data_raw(rd, TIME_WINDOW2, window);
-		break;
-	default:
-		ret = -EINVAL;
-	}
-
-set_time_exit:
-	put_online_cpus();
-	return ret;
-}
-
-static int get_time_window(struct powercap_zone *power_zone, int cid, u64 *data)
-{
-	struct rapl_domain *rd;
-	u64 val;
-	int ret = 0;
-	int id;
-
-	get_online_cpus();
-	rd = power_zone_to_rapl_domain(power_zone);
-	id = contraint_to_pl(rd, cid);
-	if (id < 0) {
-		ret = id;
-		goto get_time_exit;
-	}
-
-	switch (rd->rpl[id].prim_id) {
-	case PL1_ENABLE:
-		ret = rapl_read_data_raw(rd, TIME_WINDOW1, true, &val);
-		break;
-	case PL2_ENABLE:
-		ret = rapl_read_data_raw(rd, TIME_WINDOW2, true, &val);
-		break;
-	default:
-		put_online_cpus();
-		return -EINVAL;
-	}
-	if (!ret)
-		*data = val;
-
-get_time_exit:
-	put_online_cpus();
-
-	return ret;
-}
-
-static const char *get_constraint_name(struct powercap_zone *power_zone, int cid)
-{
-	struct rapl_domain *rd;
-	int id;
-
-	rd = power_zone_to_rapl_domain(power_zone);
-	id = contraint_to_pl(rd, cid);
-	if (id >= 0)
-		return rd->rpl[id].name;
-
-	return NULL;
-}
-
-
-static int get_max_power(struct powercap_zone *power_zone, int id,
-					u64 *data)
-{
-	struct rapl_domain *rd;
-	u64 val;
-	int prim;
-	int ret = 0;
-
-	get_online_cpus();
-	rd = power_zone_to_rapl_domain(power_zone);
-	switch (rd->rpl[id].prim_id) {
-	case PL1_ENABLE:
-		prim = THERMAL_SPEC_POWER;
-		break;
-	case PL2_ENABLE:
-		prim = MAX_POWER;
-		break;
-	default:
-		put_online_cpus();
-		return -EINVAL;
-	}
-	if (rapl_read_data_raw(rd, prim, true, &val))
-		ret = -EIO;
-	else
-		*data = val;
-
-	put_online_cpus();
-
-	return ret;
-}
-
-static const struct powercap_zone_constraint_ops constraint_ops = {
-	.set_power_limit_uw = set_power_limit,
-	.get_power_limit_uw = get_current_power_limit,
-	.set_time_window_us = set_time_window,
-	.get_time_window_us = get_time_window,
-	.get_max_power_uw = get_max_power,
-	.get_name = get_constraint_name,
-};
-
-/* called after domain detection and package level data are set */
-static void rapl_init_domains(struct rapl_package *rp)
-{
-	int i;
-	struct rapl_domain *rd = rp->domains;
-
-	for (i = 0; i < RAPL_DOMAIN_MAX; i++) {
-		unsigned int mask = rp->domain_map & (1 << i);
-
-		rd->regs[RAPL_DOMAIN_REG_LIMIT] = rp->priv->regs[i][RAPL_DOMAIN_REG_LIMIT];
-		rd->regs[RAPL_DOMAIN_REG_STATUS] = rp->priv->regs[i][RAPL_DOMAIN_REG_STATUS];
-		rd->regs[RAPL_DOMAIN_REG_PERF] = rp->priv->regs[i][RAPL_DOMAIN_REG_PERF];
-		rd->regs[RAPL_DOMAIN_REG_POLICY] = rp->priv->regs[i][RAPL_DOMAIN_REG_POLICY];
-		rd->regs[RAPL_DOMAIN_REG_INFO] = rp->priv->regs[i][RAPL_DOMAIN_REG_INFO];
-
-		switch (mask) {
-		case BIT(RAPL_DOMAIN_PACKAGE):
-			rd->name = rapl_domain_names[RAPL_DOMAIN_PACKAGE];
-			rd->id = RAPL_DOMAIN_PACKAGE;
-			rd->rpl[0].prim_id = PL1_ENABLE;
-			rd->rpl[0].name = pl1_name;
-			rd->rpl[1].prim_id = PL2_ENABLE;
-			rd->rpl[1].name = pl2_name;
-			break;
-		case BIT(RAPL_DOMAIN_PP0):
-			rd->name = rapl_domain_names[RAPL_DOMAIN_PP0];
-			rd->id = RAPL_DOMAIN_PP0;
-			rd->rpl[0].prim_id = PL1_ENABLE;
-			rd->rpl[0].name = pl1_name;
-			break;
-		case BIT(RAPL_DOMAIN_PP1):
-			rd->name = rapl_domain_names[RAPL_DOMAIN_PP1];
-			rd->id = RAPL_DOMAIN_PP1;
-			rd->rpl[0].prim_id = PL1_ENABLE;
-			rd->rpl[0].name = pl1_name;
-			break;
-		case BIT(RAPL_DOMAIN_DRAM):
-			rd->name = rapl_domain_names[RAPL_DOMAIN_DRAM];
-			rd->id = RAPL_DOMAIN_DRAM;
-			rd->rpl[0].prim_id = PL1_ENABLE;
-			rd->rpl[0].name = pl1_name;
-			rd->domain_energy_unit =
-				rapl_defaults->dram_domain_energy_unit;
-			if (rd->domain_energy_unit)
-				pr_info("DRAM domain energy unit %dpj\n",
-					rd->domain_energy_unit);
-			break;
-		}
-		if (mask) {
-			rd->rp = rp;
-			rd++;
-		}
-	}
-}
-
-static u64 rapl_unit_xlate(struct rapl_domain *rd, enum unit_type type,
-			u64 value, int to_raw)
-{
-	u64 units = 1;
-	struct rapl_package *rp = rd->rp;
-	u64 scale = 1;
-
-	switch (type) {
-	case POWER_UNIT:
-		units = rp->power_unit;
-		break;
-	case ENERGY_UNIT:
-		scale = ENERGY_UNIT_SCALE;
-		/* per domain unit takes precedence */
-		if (rd->domain_energy_unit)
-			units = rd->domain_energy_unit;
-		else
-			units = rp->energy_unit;
-		break;
-	case TIME_UNIT:
-		return rapl_defaults->compute_time_window(rp, value, to_raw);
-	case ARBITRARY_UNIT:
-	default:
-		return value;
-	};
-
-	if (to_raw)
-		return div64_u64(value, units) * scale;
-
-	value *= units;
-
-	return div64_u64(value, scale);
-}
-
-/* in the order of enum rapl_primitives */
-static struct rapl_primitive_info rpi[] = {
-	/* name, mask, shift, msr index, unit divisor */
-	PRIMITIVE_INFO_INIT(ENERGY_COUNTER, ENERGY_STATUS_MASK, 0,
-				RAPL_DOMAIN_REG_STATUS, ENERGY_UNIT, 0),
-	PRIMITIVE_INFO_INIT(POWER_LIMIT1, POWER_LIMIT1_MASK, 0,
-				RAPL_DOMAIN_REG_LIMIT, POWER_UNIT, 0),
-	PRIMITIVE_INFO_INIT(POWER_LIMIT2, POWER_LIMIT2_MASK, 32,
-				RAPL_DOMAIN_REG_LIMIT, POWER_UNIT, 0),
-	PRIMITIVE_INFO_INIT(FW_LOCK, POWER_PP_LOCK, 31,
-				RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
-	PRIMITIVE_INFO_INIT(PL1_ENABLE, POWER_LIMIT1_ENABLE, 15,
-				RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
-	PRIMITIVE_INFO_INIT(PL1_CLAMP, POWER_LIMIT1_CLAMP, 16,
-				RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
-	PRIMITIVE_INFO_INIT(PL2_ENABLE, POWER_LIMIT2_ENABLE, 47,
-				RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
-	PRIMITIVE_INFO_INIT(PL2_CLAMP, POWER_LIMIT2_CLAMP, 48,
-				RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
-	PRIMITIVE_INFO_INIT(TIME_WINDOW1, TIME_WINDOW1_MASK, 17,
-				RAPL_DOMAIN_REG_LIMIT, TIME_UNIT, 0),
-	PRIMITIVE_INFO_INIT(TIME_WINDOW2, TIME_WINDOW2_MASK, 49,
-				RAPL_DOMAIN_REG_LIMIT, TIME_UNIT, 0),
-	PRIMITIVE_INFO_INIT(THERMAL_SPEC_POWER, POWER_INFO_THERMAL_SPEC_MASK,
-				0, RAPL_DOMAIN_REG_INFO, POWER_UNIT, 0),
-	PRIMITIVE_INFO_INIT(MAX_POWER, POWER_INFO_MAX_MASK, 32,
-				RAPL_DOMAIN_REG_INFO, POWER_UNIT, 0),
-	PRIMITIVE_INFO_INIT(MIN_POWER, POWER_INFO_MIN_MASK, 16,
-				RAPL_DOMAIN_REG_INFO, POWER_UNIT, 0),
-	PRIMITIVE_INFO_INIT(MAX_TIME_WINDOW, POWER_INFO_MAX_TIME_WIN_MASK, 48,
-				RAPL_DOMAIN_REG_INFO, TIME_UNIT, 0),
-	PRIMITIVE_INFO_INIT(THROTTLED_TIME, PERF_STATUS_THROTTLE_TIME_MASK, 0,
-				RAPL_DOMAIN_REG_PERF, TIME_UNIT, 0),
-	PRIMITIVE_INFO_INIT(PRIORITY_LEVEL, PP_POLICY_MASK, 0,
-				RAPL_DOMAIN_REG_POLICY, ARBITRARY_UNIT, 0),
-	/* non-hardware */
-	PRIMITIVE_INFO_INIT(AVERAGE_POWER, 0, 0, 0, POWER_UNIT,
-				RAPL_PRIMITIVE_DERIVED),
-	{NULL, 0, 0, 0},
-};
-
-/* Read primitive data based on its related struct rapl_primitive_info.
- * if xlate flag is set, return translated data based on data units, i.e.
- * time, energy, and power.
- * RAPL MSRs are non-architectual and are laid out not consistently across
- * domains. Here we use primitive info to allow writing consolidated access
- * functions.
- * For a given primitive, it is processed by MSR mask and shift. Unit conversion
- * is pre-assigned based on RAPL unit MSRs read at init time.
- * 63-------------------------- 31--------------------------- 0
- * |                           xxxxx (mask)                   |
- * |                                |<- shift ----------------|
- * 63-------------------------- 31--------------------------- 0
- */
-static int rapl_read_data_raw(struct rapl_domain *rd,
-			enum rapl_primitives prim,
-			bool xlate, u64 *data)
-{
-	u64 value;
-	struct rapl_primitive_info *rp = &rpi[prim];
-	struct reg_action ra;
-	int cpu;
-
-	if (!rp->name || rp->flag & RAPL_PRIMITIVE_DUMMY)
-		return -EINVAL;
-
-	ra.reg = rd->regs[rp->id];
-	if (!ra.reg)
-		return -EINVAL;
-
-	cpu = rd->rp->lead_cpu;
-
-	/* special-case package domain, which uses a different bit*/
-	if (prim == FW_LOCK && rd->id == RAPL_DOMAIN_PACKAGE) {
-		rp->mask = POWER_PACKAGE_LOCK;
-		rp->shift = 63;
-	}
-	/* non-hardware data are collected by the polling thread */
-	if (rp->flag & RAPL_PRIMITIVE_DERIVED) {
-		*data = rd->rdd.primitives[prim];
-		return 0;
-	}
-
-	ra.mask = rp->mask;
-
-	if (rd->rp->priv->read_raw(cpu, &ra)) {
-		pr_debug("failed to read reg 0x%x on cpu %d\n", ra.reg, cpu);
-		return -EIO;
-	}
-
-	value = ra.value >> rp->shift;
-
-	if (xlate)
-		*data = rapl_unit_xlate(rd, rp->unit, value, 0);
-	else
-		*data = value;
-
-	return 0;
-}
-
-/* Similar use of primitive info in the read counterpart */
-static int rapl_write_data_raw(struct rapl_domain *rd,
-			enum rapl_primitives prim,
-			unsigned long long value)
-{
-	struct rapl_primitive_info *rp = &rpi[prim];
-	int cpu;
-	u64 bits;
-	struct reg_action ra;
-	int ret;
-
-	cpu = rd->rp->lead_cpu;
-	bits = rapl_unit_xlate(rd, rp->unit, value, 1);
-	bits <<= rp->shift;
-	bits &= rp->mask;
-
-	memset(&ra, 0, sizeof(ra));
-
-	ra.reg = rd->regs[rp->id];
-	ra.mask = rp->mask;
-	ra.value = bits;
-
-	ret = rd->rp->priv->write_raw(cpu, &ra);
-
-	return ret;
-}
-
-/*
- * Raw RAPL data stored in MSRs are in certain scales. We need to
- * convert them into standard units based on the units reported in
- * the RAPL unit MSRs. This is specific to CPUs as the method to
- * calculate units differ on different CPUs.
- * We convert the units to below format based on CPUs.
- * i.e.
- * energy unit: picoJoules  : Represented in picoJoules by default
- * power unit : microWatts  : Represented in milliWatts by default
- * time unit  : microseconds: Represented in seconds by default
- */
-static int rapl_check_unit_core(struct rapl_package *rp, int cpu)
-{
-	struct reg_action ra;
-	u32 value;
-
-	ra.reg = rp->priv->reg_unit;
-	ra.mask = ~0;
-	if (rp->priv->read_raw(cpu, &ra)) {
-		pr_err("Failed to read power unit REG 0x%x on CPU %d, exit.\n",
-			rp->priv->reg_unit, cpu);
-		return -ENODEV;
-	}
-
-	value = (ra.value & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
-	rp->energy_unit = ENERGY_UNIT_SCALE * 1000000 / (1 << value);
-
-	value = (ra.value & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
-	rp->power_unit = 1000000 / (1 << value);
-
-	value = (ra.value & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
-	rp->time_unit = 1000000 / (1 << value);
-
-	pr_debug("Core CPU %s energy=%dpJ, time=%dus, power=%duW\n",
-		rp->name, rp->energy_unit, rp->time_unit, rp->power_unit);
-
-	return 0;
-}
-
-static int rapl_check_unit_atom(struct rapl_package *rp, int cpu)
-{
-	struct reg_action ra;
-	u32 value;
-
-	ra.reg = rp->priv->reg_unit;
-	ra.mask = ~0;
-	if (rp->priv->read_raw(cpu, &ra)) {
-		pr_err("Failed to read power unit REG 0x%x on CPU %d, exit.\n",
-			rp->priv->reg_unit, cpu);
-		return -ENODEV;
-	}
-
-	value = (ra.value & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
-	rp->energy_unit = ENERGY_UNIT_SCALE * 1 << value;
-
-	value = (ra.value & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
-	rp->power_unit = (1 << value) * 1000;
-
-	value = (ra.value & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
-	rp->time_unit = 1000000 / (1 << value);
-
-	pr_debug("Atom %s energy=%dpJ, time=%dus, power=%duW\n",
-		rp->name, rp->energy_unit, rp->time_unit, rp->power_unit);
-
-	return 0;
-}
-
-static void power_limit_irq_save_cpu(void *info)
-{
-	u32 l, h = 0;
-	struct rapl_package *rp = (struct rapl_package *)info;
-
-	/* save the state of PLN irq mask bit before disabling it */
-	rdmsr_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, &l, &h);
-	if (!(rp->power_limit_irq & PACKAGE_PLN_INT_SAVED)) {
-		rp->power_limit_irq = l & PACKAGE_THERM_INT_PLN_ENABLE;
-		rp->power_limit_irq |= PACKAGE_PLN_INT_SAVED;
-	}
-	l &= ~PACKAGE_THERM_INT_PLN_ENABLE;
-	wrmsr_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
-}
-
-
-/* REVISIT:
- * When package power limit is set artificially low by RAPL, LVT
- * thermal interrupt for package power limit should be ignored
- * since we are not really exceeding the real limit. The intention
- * is to avoid excessive interrupts while we are trying to save power.
- * A useful feature might be routing the package_power_limit interrupt
- * to userspace via eventfd. once we have a usecase, this is simple
- * to do by adding an atomic notifier.
- */
-
-static void package_power_limit_irq_save(struct rapl_package *rp)
-{
-	if (!boot_cpu_has(X86_FEATURE_PTS) || !boot_cpu_has(X86_FEATURE_PLN))
-		return;
-
-	smp_call_function_single(rp->lead_cpu, power_limit_irq_save_cpu, rp, 1);
-}
-
-/*
- * Restore per package power limit interrupt enable state. Called from cpu
- * hotplug code on package removal.
- */
-static void package_power_limit_irq_restore(struct rapl_package *rp)
-{
-	u32 l, h;
-
-	if (!boot_cpu_has(X86_FEATURE_PTS) || !boot_cpu_has(X86_FEATURE_PLN))
-		return;
-
-	/* irq enable state not saved, nothing to restore */
-	if (!(rp->power_limit_irq & PACKAGE_PLN_INT_SAVED))
-		return;
-
-	rdmsr_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, &l, &h);
-
-	if (rp->power_limit_irq & PACKAGE_THERM_INT_PLN_ENABLE)
-		l |= PACKAGE_THERM_INT_PLN_ENABLE;
-	else
-		l &= ~PACKAGE_THERM_INT_PLN_ENABLE;
-
-	wrmsr_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
-}
-
-static void set_floor_freq_default(struct rapl_domain *rd, bool mode)
-{
-	int nr_powerlimit = find_nr_power_limit(rd);
-
-	/* always enable clamp such that p-state can go below OS requested
-	 * range. power capping priority over guranteed frequency.
-	 */
-	rapl_write_data_raw(rd, PL1_CLAMP, mode);
-
-	/* some domains have pl2 */
-	if (nr_powerlimit > 1) {
-		rapl_write_data_raw(rd, PL2_ENABLE, mode);
-		rapl_write_data_raw(rd, PL2_CLAMP, mode);
-	}
-}
-
-static void set_floor_freq_atom(struct rapl_domain *rd, bool enable)
-{
-	static u32 power_ctrl_orig_val;
-	u32 mdata;
-
-	if (!rapl_defaults->floor_freq_reg_addr) {
-		pr_err("Invalid floor frequency config register\n");
-		return;
-	}
-
-	if (!power_ctrl_orig_val)
-		iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_CR_READ,
-			      rapl_defaults->floor_freq_reg_addr,
-			      &power_ctrl_orig_val);
-	mdata = power_ctrl_orig_val;
-	if (enable) {
-		mdata &= ~(0x7f << 8);
-		mdata |= 1 << 8;
-	}
-	iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_CR_WRITE,
-		       rapl_defaults->floor_freq_reg_addr, mdata);
-}
-
-static u64 rapl_compute_time_window_core(struct rapl_package *rp, u64 value,
-					bool to_raw)
-{
-	u64 f, y; /* fraction and exp. used for time unit */
-
-	/*
-	 * Special processing based on 2^Y*(1+F/4), refer
-	 * to Intel Software Developer's manual Vol.3B: CH 14.9.3.
-	 */
-	if (!to_raw) {
-		f = (value & 0x60) >> 5;
-		y = value & 0x1f;
-		value = (1 << y) * (4 + f) * rp->time_unit / 4;
-	} else {
-		do_div(value, rp->time_unit);
-		y = ilog2(value);
-		f = div64_u64(4 * (value - (1 << y)), 1 << y);
-		value = (y & 0x1f) | ((f & 0x3) << 5);
-	}
-	return value;
-}
-
-static u64 rapl_compute_time_window_atom(struct rapl_package *rp, u64 value,
-					bool to_raw)
-{
-	/*
-	 * Atom time unit encoding is straight forward val * time_unit,
-	 * where time_unit is default to 1 sec. Never 0.
-	 */
-	if (!to_raw)
-		return (value) ? value *= rp->time_unit : rp->time_unit;
-	else
-		value = div64_u64(value, rp->time_unit);
-
-	return value;
-}
-
-static const struct rapl_defaults rapl_defaults_core = {
-	.floor_freq_reg_addr = 0,
-	.check_unit = rapl_check_unit_core,
-	.set_floor_freq = set_floor_freq_default,
-	.compute_time_window = rapl_compute_time_window_core,
-};
-
-static const struct rapl_defaults rapl_defaults_hsw_server = {
-	.check_unit = rapl_check_unit_core,
-	.set_floor_freq = set_floor_freq_default,
-	.compute_time_window = rapl_compute_time_window_core,
-	.dram_domain_energy_unit = 15300,
-};
-
-static const struct rapl_defaults rapl_defaults_byt = {
-	.floor_freq_reg_addr = IOSF_CPU_POWER_BUDGET_CTL_BYT,
-	.check_unit = rapl_check_unit_atom,
-	.set_floor_freq = set_floor_freq_atom,
-	.compute_time_window = rapl_compute_time_window_atom,
-};
-
-static const struct rapl_defaults rapl_defaults_tng = {
-	.floor_freq_reg_addr = IOSF_CPU_POWER_BUDGET_CTL_TNG,
-	.check_unit = rapl_check_unit_atom,
-	.set_floor_freq = set_floor_freq_atom,
-	.compute_time_window = rapl_compute_time_window_atom,
-};
-
-static const struct rapl_defaults rapl_defaults_ann = {
-	.floor_freq_reg_addr = 0,
-	.check_unit = rapl_check_unit_atom,
-	.set_floor_freq = NULL,
-	.compute_time_window = rapl_compute_time_window_atom,
-};
-
-static const struct rapl_defaults rapl_defaults_cht = {
-	.floor_freq_reg_addr = 0,
-	.check_unit = rapl_check_unit_atom,
-	.set_floor_freq = NULL,
-	.compute_time_window = rapl_compute_time_window_atom,
-};
-
-static const struct x86_cpu_id rapl_ids[] __initconst = {
-	INTEL_CPU_FAM6(SANDYBRIDGE,		rapl_defaults_core),
-	INTEL_CPU_FAM6(SANDYBRIDGE_X,		rapl_defaults_core),
-
-	INTEL_CPU_FAM6(IVYBRIDGE,		rapl_defaults_core),
-	INTEL_CPU_FAM6(IVYBRIDGE_X,		rapl_defaults_core),
-
-	INTEL_CPU_FAM6(HASWELL_CORE,		rapl_defaults_core),
-	INTEL_CPU_FAM6(HASWELL_ULT,		rapl_defaults_core),
-	INTEL_CPU_FAM6(HASWELL_GT3E,		rapl_defaults_core),
-	INTEL_CPU_FAM6(HASWELL_X,		rapl_defaults_hsw_server),
-
-	INTEL_CPU_FAM6(BROADWELL_CORE,		rapl_defaults_core),
-	INTEL_CPU_FAM6(BROADWELL_GT3E,		rapl_defaults_core),
-	INTEL_CPU_FAM6(BROADWELL_XEON_D,	rapl_defaults_core),
-	INTEL_CPU_FAM6(BROADWELL_X,		rapl_defaults_hsw_server),
-
-	INTEL_CPU_FAM6(SKYLAKE_DESKTOP,		rapl_defaults_core),
-	INTEL_CPU_FAM6(SKYLAKE_MOBILE,		rapl_defaults_core),
-	INTEL_CPU_FAM6(SKYLAKE_X,		rapl_defaults_hsw_server),
-	INTEL_CPU_FAM6(KABYLAKE_MOBILE,		rapl_defaults_core),
-	INTEL_CPU_FAM6(KABYLAKE_DESKTOP,	rapl_defaults_core),
-	INTEL_CPU_FAM6(CANNONLAKE_MOBILE,	rapl_defaults_core),
-	INTEL_CPU_FAM6(ICELAKE_MOBILE,		rapl_defaults_core),
-
-	INTEL_CPU_FAM6(ATOM_SILVERMONT,		rapl_defaults_byt),
-	INTEL_CPU_FAM6(ATOM_AIRMONT,		rapl_defaults_cht),
-	INTEL_CPU_FAM6(ATOM_SILVERMONT_MID,	rapl_defaults_tng),
-	INTEL_CPU_FAM6(ATOM_AIRMONT_MID,	rapl_defaults_ann),
-	INTEL_CPU_FAM6(ATOM_GOLDMONT,		rapl_defaults_core),
-	INTEL_CPU_FAM6(ATOM_GOLDMONT_PLUS,	rapl_defaults_core),
-	INTEL_CPU_FAM6(ATOM_GOLDMONT_X,		rapl_defaults_core),
-	INTEL_CPU_FAM6(ATOM_TREMONT_X,		rapl_defaults_core),
-
-	INTEL_CPU_FAM6(XEON_PHI_KNL,		rapl_defaults_hsw_server),
-	INTEL_CPU_FAM6(XEON_PHI_KNM,		rapl_defaults_hsw_server),
-	{}
-};
-MODULE_DEVICE_TABLE(x86cpu, rapl_ids);
-
-/* Read once for all raw primitive data for domains */
-static void rapl_update_domain_data(struct rapl_package *rp)
-{
-	int dmn, prim;
-	u64 val;
-
-	for (dmn = 0; dmn < rp->nr_domains; dmn++) {
-		pr_debug("update %s domain %s data\n", rp->name,
-			 rp->domains[dmn].name);
-		/* exclude non-raw primitives */
-		for (prim = 0; prim < NR_RAW_PRIMITIVES; prim++) {
-			if (!rapl_read_data_raw(&rp->domains[dmn], prim,
-						rpi[prim].unit, &val))
-				rp->domains[dmn].rdd.primitives[prim] =	val;
-		}
-	}
-
-}
-
-static int rapl_package_register_powercap(struct rapl_package *rp)
-{
-	struct rapl_domain *rd;
-	struct powercap_zone *power_zone = NULL;
-	int nr_pl, ret;
-
-	/* Update the domain data of the new package */
-	rapl_update_domain_data(rp);
-
-	/* first we register package domain as the parent zone*/
-	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
-		if (rd->id == RAPL_DOMAIN_PACKAGE) {
-			nr_pl = find_nr_power_limit(rd);
-			pr_debug("register package domain %s\n", rp->name);
-			power_zone = powercap_register_zone(&rd->power_zone,
-							rp->priv->control_type,
-							rp->name, NULL,
-							&zone_ops[rd->id],
-							nr_pl,
-							&constraint_ops);
-			if (IS_ERR(power_zone)) {
-				pr_debug("failed to register power zone %s\n",
-					rp->name);
-				return PTR_ERR(power_zone);
-			}
-			/* track parent zone in per package/socket data */
-			rp->power_zone = power_zone;
-			/* done, only one package domain per socket */
-			break;
-		}
-	}
-	if (!power_zone) {
-		pr_err("no package domain found, unknown topology!\n");
-		return -ENODEV;
-	}
-	/* now register domains as children of the socket/package*/
-	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
-		if (rd->id == RAPL_DOMAIN_PACKAGE)
-			continue;
-		/* number of power limits per domain varies */
-		nr_pl = find_nr_power_limit(rd);
-		power_zone = powercap_register_zone(&rd->power_zone,
-						rp->priv->control_type, rd->name,
-						rp->power_zone,
-						&zone_ops[rd->id], nr_pl,
-						&constraint_ops);
-
-		if (IS_ERR(power_zone)) {
-			pr_debug("failed to register power_zone, %s:%s\n",
-				rp->name, rd->name);
-			ret = PTR_ERR(power_zone);
-			goto err_cleanup;
-		}
-	}
-	return 0;
-
-err_cleanup:
-	/*
-	 * Clean up previously initialized domains within the package if we
-	 * failed after the first domain setup.
-	 */
-	while (--rd >= rp->domains) {
-		pr_debug("unregister %s domain %s\n", rp->name, rd->name);
-		powercap_unregister_zone(rp->priv->control_type, &rd->power_zone);
-	}
-
-	return ret;
-}
-
-static int __init rapl_add_platform_domain(struct rapl_if_priv *priv)
-{
-	struct rapl_domain *rd;
-	struct powercap_zone *power_zone;
-	struct reg_action ra;
-	int ret;
-
-	ra.reg = priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_STATUS];
-	ra.mask = ~0;
-	ret = priv->read_raw(0, &ra);
-	if (ret || !ra.value)
-		return -ENODEV;
-
-	ra.reg = priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_LIMIT];
-	ra.mask = ~0;
-	ret = priv->read_raw(0, &ra);
-	if (ret || !ra.value)
-		return -ENODEV;
-
-	rd = kzalloc(sizeof(*rd), GFP_KERNEL);
-	if (!rd)
-		return -ENOMEM;
-
-	rd->name = rapl_domain_names[RAPL_DOMAIN_PLATFORM];
-	rd->id = RAPL_DOMAIN_PLATFORM;
-	rd->regs[RAPL_DOMAIN_REG_LIMIT] = priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_LIMIT];
-	rd->regs[RAPL_DOMAIN_REG_STATUS] = priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_STATUS];
-	rd->rpl[0].prim_id = PL1_ENABLE;
-	rd->rpl[0].name = pl1_name;
-	rd->rpl[1].prim_id = PL2_ENABLE;
-	rd->rpl[1].name = pl2_name;
-	rd->rp = rapl_find_package_domain(0, priv);
-
-	power_zone = powercap_register_zone(&rd->power_zone, priv->control_type,
-					    "psys", NULL,
-					    &zone_ops[RAPL_DOMAIN_PLATFORM],
-					    2, &constraint_ops);
-
-	if (IS_ERR(power_zone)) {
-		kfree(rd);
-		return PTR_ERR(power_zone);
-	}
-
-	priv->platform_rapl_domain = rd;
-
-	return 0;
-}
-
-static void rapl_remove_platform_domain(struct rapl_if_priv *priv)
-{
-	if (priv->platform_rapl_domain) {
-		powercap_unregister_zone(priv->control_type,
-			&priv->platform_rapl_domain->power_zone);
-		kfree(priv->platform_rapl_domain);
-	}
-}
-
-static int rapl_check_domain(int cpu, int domain, struct rapl_package *rp)
-{
-	struct reg_action ra;
-
-	switch (domain) {
-	case RAPL_DOMAIN_PACKAGE:
-	case RAPL_DOMAIN_PP0:
-	case RAPL_DOMAIN_PP1:
-	case RAPL_DOMAIN_DRAM:
-		ra.reg = rp->priv->regs[domain][RAPL_DOMAIN_REG_STATUS];
-		break;
-	case RAPL_DOMAIN_PLATFORM:
-		/* PSYS(PLATFORM) is not a CPU domain, so avoid printng error */
-		return -EINVAL;
-	default:
-		pr_err("invalid domain id %d\n", domain);
-		return -EINVAL;
-	}
-	/* make sure domain counters are available and contains non-zero
-	 * values, otherwise skip it.
-	 */
-
-	ra.mask = ~0;
-	if (rp->priv->read_raw(cpu, &ra) || !ra.value)
-		return -ENODEV;
-
-	return 0;
-}
-
-
-/*
- * Check if power limits are available. Two cases when they are not available:
- * 1. Locked by BIOS, in this case we still provide read-only access so that
- *    users can see what limit is set by the BIOS.
- * 2. Some CPUs make some domains monitoring only which means PLx MSRs may not
- *    exist at all. In this case, we do not show the contraints in powercap.
- *
- * Called after domains are detected and initialized.
- */
-static void rapl_detect_powerlimit(struct rapl_domain *rd)
-{
-	u64 val64;
-	int i;
-
-	/* check if the domain is locked by BIOS, ignore if MSR doesn't exist */
-	if (!rapl_read_data_raw(rd, FW_LOCK, false, &val64)) {
-		if (val64) {
-			pr_info("RAPL %s domain %s locked by BIOS\n",
-				rd->rp->name, rd->name);
-			rd->state |= DOMAIN_STATE_BIOS_LOCKED;
-		}
-	}
-	/* check if power limit MSRs exists, otherwise domain is monitoring only */
-	for (i = 0; i < NR_POWER_LIMITS; i++) {
-		int prim = rd->rpl[i].prim_id;
-		if (rapl_read_data_raw(rd, prim, false, &val64))
-			rd->rpl[i].name = NULL;
-	}
-}
-
-/* Detect active and valid domains for the given CPU, caller must
- * ensure the CPU belongs to the targeted package and CPU hotlug is disabled.
- */
-static int rapl_detect_domains(struct rapl_package *rp, int cpu)
-{
-	struct rapl_domain *rd;
-	int i;
-
-	for (i = 0; i < RAPL_DOMAIN_MAX; i++) {
-		/* use physical package id to read counters */
-		if (!rapl_check_domain(cpu, i, rp)) {
-			rp->domain_map |= 1 << i;
-			pr_info("Found RAPL domain %s\n", rapl_domain_names[i]);
-		}
-	}
-	rp->nr_domains = bitmap_weight(&rp->domain_map,	RAPL_DOMAIN_MAX);
-	if (!rp->nr_domains) {
-		pr_debug("no valid rapl domains found in %s\n", rp->name);
-		return -ENODEV;
-	}
-	pr_debug("found %d domains on %s\n", rp->nr_domains, rp->name);
-
-	rp->domains = kcalloc(rp->nr_domains + 1, sizeof(struct rapl_domain),
-			GFP_KERNEL);
-	if (!rp->domains)
-		return -ENOMEM;
-
-	rapl_init_domains(rp);
-
-	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++)
-		rapl_detect_powerlimit(rd);
-
-	return 0;
-}
-
-/* called from CPU hotplug notifier, hotplug lock held */
-static void rapl_remove_package(struct rapl_package *rp)
-{
-	struct rapl_domain *rd, *rd_package = NULL;
-
-	package_power_limit_irq_restore(rp);
-
-	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
-		rapl_write_data_raw(rd, PL1_ENABLE, 0);
-		rapl_write_data_raw(rd, PL1_CLAMP, 0);
-		if (find_nr_power_limit(rd) > 1) {
-			rapl_write_data_raw(rd, PL2_ENABLE, 0);
-			rapl_write_data_raw(rd, PL2_CLAMP, 0);
-		}
-		if (rd->id == RAPL_DOMAIN_PACKAGE) {
-			rd_package = rd;
-			continue;
-		}
-		pr_debug("remove package, undo power limit on %s: %s\n",
-			 rp->name, rd->name);
-		powercap_unregister_zone(rp->priv->control_type, &rd->power_zone);
-	}
-	/* do parent zone last */
-	powercap_unregister_zone(rp->priv->control_type, &rd_package->power_zone);
-	list_del(&rp->plist);
-	kfree(rp);
-}
-
-/* called from CPU hotplug notifier, hotplug lock held */
-static struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv)
-{
-	int id = topology_logical_die_id(cpu);
-	struct rapl_package *rp;
-	struct cpuinfo_x86 *c = &cpu_data(cpu);
-	int ret;
-
-	rp = kzalloc(sizeof(struct rapl_package), GFP_KERNEL);
-	if (!rp)
-		return ERR_PTR(-ENOMEM);
-
-	/* add the new package to the list */
-	rp->id = id;
-	rp->lead_cpu = cpu;
-	rp->priv = priv;
-
-	if (topology_max_die_per_package() > 1)
-		snprintf(rp->name, PACKAGE_DOMAIN_NAME_LENGTH,
-			"package-%d-die-%d", c->phys_proc_id, c->cpu_die_id);
-	else
-		snprintf(rp->name, PACKAGE_DOMAIN_NAME_LENGTH, "package-%d",
-			c->phys_proc_id);
-
-	/* check if the package contains valid domains */
-	if (rapl_detect_domains(rp, cpu) ||
-		rapl_defaults->check_unit(rp, cpu)) {
-		ret = -ENODEV;
-		goto err_free_package;
-	}
-	ret = rapl_package_register_powercap(rp);
-	if (!ret) {
-		INIT_LIST_HEAD(&rp->plist);
-		list_add(&rp->plist, &rapl_packages);
-		return rp;
-	}
-
-err_free_package:
-	kfree(rp->domains);
-	kfree(rp);
-	return ERR_PTR(ret);
-}
-
-/* Handles CPU hotplug on multi-socket systems.
- * If a CPU goes online as the first CPU of the physical package
- * we add the RAPL package to the system. Similarly, when the last
- * CPU of the package is removed, we remove the RAPL package and its
- * associated domains. Cooling devices are handled accordingly at
- * per-domain level.
- */
-static int rapl_cpu_online(unsigned int cpu)
-{
-	struct rapl_package *rp;
-
-	rp = rapl_find_package_domain(cpu, &rapl_msr_priv);
-	if (!rp) {
-		rp = rapl_add_package(cpu, &rapl_msr_priv);
-		if (IS_ERR(rp))
-			return PTR_ERR(rp);
-	}
-	cpumask_set_cpu(cpu, &rp->cpumask);
-	return 0;
-}
-
-static int rapl_cpu_down_prep(unsigned int cpu)
-{
-	struct rapl_package *rp;
-	int lead_cpu;
-
-	rp = rapl_find_package_domain(cpu, &rapl_msr_priv);
-	if (!rp)
-		return 0;
-
-	cpumask_clear_cpu(cpu, &rp->cpumask);
-	lead_cpu = cpumask_first(&rp->cpumask);
-	if (lead_cpu >= nr_cpu_ids)
-		rapl_remove_package(rp);
-	else if (rp->lead_cpu == cpu)
-		rp->lead_cpu = lead_cpu;
-	return 0;
-}
-
-static void power_limit_state_save(void)
-{
-	struct rapl_package *rp;
-	struct rapl_domain *rd;
-	int nr_pl, ret, i;
-
-	get_online_cpus();
-	list_for_each_entry(rp, &rapl_packages, plist) {
-		if (!rp->power_zone)
-			continue;
-		rd = power_zone_to_rapl_domain(rp->power_zone);
-		nr_pl = find_nr_power_limit(rd);
-		for (i = 0; i < nr_pl; i++) {
-			switch (rd->rpl[i].prim_id) {
-			case PL1_ENABLE:
-				ret = rapl_read_data_raw(rd,
-						POWER_LIMIT1,
-						true,
-						&rd->rpl[i].last_power_limit);
-				if (ret)
-					rd->rpl[i].last_power_limit = 0;
-				break;
-			case PL2_ENABLE:
-				ret = rapl_read_data_raw(rd,
-						POWER_LIMIT2,
-						true,
-						&rd->rpl[i].last_power_limit);
-				if (ret)
-					rd->rpl[i].last_power_limit = 0;
-				break;
-			}
-		}
-	}
-	put_online_cpus();
-}
-
-static void power_limit_state_restore(void)
-{
-	struct rapl_package *rp;
-	struct rapl_domain *rd;
-	int nr_pl, i;
-
-	get_online_cpus();
-	list_for_each_entry(rp, &rapl_packages, plist) {
-		if (!rp->power_zone)
-			continue;
-		rd = power_zone_to_rapl_domain(rp->power_zone);
-		nr_pl = find_nr_power_limit(rd);
-		for (i = 0; i < nr_pl; i++) {
-			switch (rd->rpl[i].prim_id) {
-			case PL1_ENABLE:
-				if (rd->rpl[i].last_power_limit)
-					rapl_write_data_raw(rd,
-						POWER_LIMIT1,
-						rd->rpl[i].last_power_limit);
-				break;
-			case PL2_ENABLE:
-				if (rd->rpl[i].last_power_limit)
-					rapl_write_data_raw(rd,
-						POWER_LIMIT2,
-						rd->rpl[i].last_power_limit);
-				break;
-			}
-		}
-	}
-	put_online_cpus();
-}
-
-static int rapl_pm_callback(struct notifier_block *nb,
-	unsigned long mode, void *_unused)
-{
-	switch (mode) {
-	case PM_SUSPEND_PREPARE:
-		power_limit_state_save();
-		break;
-	case PM_POST_SUSPEND:
-		power_limit_state_restore();
-		break;
-	}
-	return NOTIFY_OK;
-}
-
-static struct notifier_block rapl_pm_notifier = {
-	.notifier_call = rapl_pm_callback,
-};
-
-static int rapl_msr_read_raw(int cpu, struct reg_action *ra)
-{
-	if (rdmsrl_safe_on_cpu(cpu, ra->reg, &ra->value)) {
-		pr_debug("failed to read msr 0x%x on cpu %d\n", ra->reg, cpu);
-		return -EIO;
-	}
-	ra->value &= ra->mask;
-	return 0;
-}
-
-static void rapl_msr_update_func(void *info)
-{
-	struct reg_action *ra = info;
-	u64 val;
-
-	ra->err = rdmsrl_safe(ra->reg, &val);
-	if (ra->err)
-		return;
-
-	val &= ~ra->mask;
-	val |= ra->value;
-
-	ra->err = wrmsrl_safe(ra->reg, val);
-}
-
-
-static int rapl_msr_write_raw(int cpu, struct reg_action *ra)
-{
-	int ret;
-
-	ret = smp_call_function_single(cpu, rapl_msr_update_func, ra, 1);
-	if (WARN_ON_ONCE(ret))
-		return ret;
-
-	return ra->err;
-}
-
-static int __init rapl_init(void)
-{
-	const struct x86_cpu_id *id;
-	int ret;
-
-	id = x86_match_cpu(rapl_ids);
-	if (!id) {
-		pr_err("driver does not support CPU family %d model %d\n",
-			boot_cpu_data.x86, boot_cpu_data.x86_model);
-
-		return -ENODEV;
-	}
-
-	rapl_defaults = (struct rapl_defaults *)id->driver_data;
-
-	rapl_msr_priv.read_raw = rapl_msr_read_raw;
-	rapl_msr_priv.write_raw = rapl_msr_write_raw;
-
-	rapl_msr_priv.control_type = powercap_register_control_type(NULL, "intel-rapl", NULL);
-	if (IS_ERR(rapl_msr_priv.control_type)) {
-		pr_debug("failed to register powercap control_type.\n");
-		return PTR_ERR(rapl_msr_priv.control_type);
-	}
-
-	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powercap/rapl:online",
-				rapl_cpu_online, rapl_cpu_down_prep);
-	if (ret < 0)
-		goto err_unreg;
-	rapl_msr_priv.pcap_rapl_online = ret;
-
-	/* Don't bail out if PSys is not supported */
-	rapl_add_platform_domain(&rapl_msr_priv);
-
-	ret = register_pm_notifier(&rapl_pm_notifier);
-	if (ret)
-		goto err_unreg_all;
-
-	return 0;
-
-err_unreg_all:
-	cpuhp_remove_state(rapl_msr_priv.pcap_rapl_online);
-
-err_unreg:
-	powercap_unregister_control_type(rapl_msr_priv.control_type);
-	return ret;
-}
-
-static void __exit rapl_exit(void)
-{
-	unregister_pm_notifier(&rapl_pm_notifier);
-	cpuhp_remove_state(rapl_msr_priv.pcap_rapl_online);
-	rapl_remove_platform_domain(&rapl_msr_priv);
-	powercap_unregister_control_type(rapl_msr_priv.control_type);
-}
-
-module_init(rapl_init);
-module_exit(rapl_exit);
-
-MODULE_DESCRIPTION("Driver for Intel RAPL (Running Average Power Limit)");
-MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c
new file mode 100644
index 0000000..323ed41
--- /dev/null
+++ b/drivers/powercap/intel_rapl_common.c
@@ -0,0 +1,1469 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Common code for Intel Running Average Power Limit (RAPL) support.
+ * Copyright (c) 2019, Intel Corporation.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/log2.h>
+#include <linux/bitmap.h>
+#include <linux/delay.h>
+#include <linux/sysfs.h>
+#include <linux/cpu.h>
+#include <linux/powercap.h>
+#include <linux/suspend.h>
+#include <asm/iosf_mbi.h>
+#include <linux/intel_rapl.h>
+
+#include <linux/processor.h>
+#include <asm/cpu_device_id.h>
+#include <asm/intel-family.h>
+
+/* Local defines */
+#define MSR_PLATFORM_POWER_LIMIT	0x0000065C
+
+/* bitmasks for RAPL MSRs, used by primitive access functions */
+#define ENERGY_STATUS_MASK      0xffffffff
+
+#define POWER_LIMIT1_MASK       0x7FFF
+#define POWER_LIMIT1_ENABLE     BIT(15)
+#define POWER_LIMIT1_CLAMP      BIT(16)
+
+#define POWER_LIMIT2_MASK       (0x7FFFULL<<32)
+#define POWER_LIMIT2_ENABLE     BIT_ULL(47)
+#define POWER_LIMIT2_CLAMP      BIT_ULL(48)
+#define POWER_PACKAGE_LOCK      BIT_ULL(63)
+#define POWER_PP_LOCK           BIT(31)
+
+#define TIME_WINDOW1_MASK       (0x7FULL<<17)
+#define TIME_WINDOW2_MASK       (0x7FULL<<49)
+
+#define POWER_UNIT_OFFSET	0
+#define POWER_UNIT_MASK		0x0F
+
+#define ENERGY_UNIT_OFFSET	0x08
+#define ENERGY_UNIT_MASK	0x1F00
+
+#define TIME_UNIT_OFFSET	0x10
+#define TIME_UNIT_MASK		0xF0000
+
+#define POWER_INFO_MAX_MASK     (0x7fffULL<<32)
+#define POWER_INFO_MIN_MASK     (0x7fffULL<<16)
+#define POWER_INFO_MAX_TIME_WIN_MASK     (0x3fULL<<48)
+#define POWER_INFO_THERMAL_SPEC_MASK     0x7fff
+
+#define PERF_STATUS_THROTTLE_TIME_MASK 0xffffffff
+#define PP_POLICY_MASK         0x1F
+
+/* Non HW constants */
+#define RAPL_PRIMITIVE_DERIVED       BIT(1)	/* not from raw data */
+#define RAPL_PRIMITIVE_DUMMY         BIT(2)
+
+#define TIME_WINDOW_MAX_MSEC 40000
+#define TIME_WINDOW_MIN_MSEC 250
+#define ENERGY_UNIT_SCALE    1000	/* scale from driver unit to powercap unit */
+enum unit_type {
+	ARBITRARY_UNIT,		/* no translation */
+	POWER_UNIT,
+	ENERGY_UNIT,
+	TIME_UNIT,
+};
+
+/* per domain data, some are optional */
+#define NR_RAW_PRIMITIVES (NR_RAPL_PRIMITIVES - 2)
+
+#define	DOMAIN_STATE_INACTIVE           BIT(0)
+#define	DOMAIN_STATE_POWER_LIMIT_SET    BIT(1)
+#define DOMAIN_STATE_BIOS_LOCKED        BIT(2)
+
+static const char pl1_name[] = "long_term";
+static const char pl2_name[] = "short_term";
+
+#define power_zone_to_rapl_domain(_zone) \
+	container_of(_zone, struct rapl_domain, power_zone)
+
+struct rapl_defaults {
+	u8 floor_freq_reg_addr;
+	int (*check_unit)(struct rapl_package *rp, int cpu);
+	void (*set_floor_freq)(struct rapl_domain *rd, bool mode);
+	u64 (*compute_time_window)(struct rapl_package *rp, u64 val,
+				    bool to_raw);
+	unsigned int dram_domain_energy_unit;
+};
+static struct rapl_defaults *rapl_defaults;
+
+/* Sideband MBI registers */
+#define IOSF_CPU_POWER_BUDGET_CTL_BYT (0x2)
+#define IOSF_CPU_POWER_BUDGET_CTL_TNG (0xdf)
+
+#define PACKAGE_PLN_INT_SAVED   BIT(0)
+#define MAX_PRIM_NAME (32)
+
+/* per domain data. used to describe individual knobs such that access function
+ * can be consolidated into one instead of many inline functions.
+ */
+struct rapl_primitive_info {
+	const char *name;
+	u64 mask;
+	int shift;
+	enum rapl_domain_reg_id id;
+	enum unit_type unit;
+	u32 flag;
+};
+
+#define PRIMITIVE_INFO_INIT(p, m, s, i, u, f) {	\
+		.name = #p,			\
+		.mask = m,			\
+		.shift = s,			\
+		.id = i,			\
+		.unit = u,			\
+		.flag = f			\
+	}
+
+static void rapl_init_domains(struct rapl_package *rp);
+static int rapl_read_data_raw(struct rapl_domain *rd,
+			      enum rapl_primitives prim,
+			      bool xlate, u64 *data);
+static int rapl_write_data_raw(struct rapl_domain *rd,
+			       enum rapl_primitives prim,
+			       unsigned long long value);
+static u64 rapl_unit_xlate(struct rapl_domain *rd,
+			   enum unit_type type, u64 value, int to_raw);
+static void package_power_limit_irq_save(struct rapl_package *rp);
+static int rapl_init_core(void);
+static void rapl_remove_core(void);
+
+static LIST_HEAD(rapl_packages);	/* guarded by CPU hotplug lock */
+
+static const char *const rapl_domain_names[] = {
+	"package",
+	"core",
+	"uncore",
+	"dram",
+	"psys",
+};
+
+static int get_energy_counter(struct powercap_zone *power_zone,
+			      u64 *energy_raw)
+{
+	struct rapl_domain *rd;
+	u64 energy_now;
+
+	/* prevent CPU hotplug, make sure the RAPL domain does not go
+	 * away while reading the counter.
+	 */
+	get_online_cpus();
+	rd = power_zone_to_rapl_domain(power_zone);
+
+	if (!rapl_read_data_raw(rd, ENERGY_COUNTER, true, &energy_now)) {
+		*energy_raw = energy_now;
+		put_online_cpus();
+
+		return 0;
+	}
+	put_online_cpus();
+
+	return -EIO;
+}
+
+static int get_max_energy_counter(struct powercap_zone *pcd_dev, u64 *energy)
+{
+	struct rapl_domain *rd = power_zone_to_rapl_domain(pcd_dev);
+
+	*energy = rapl_unit_xlate(rd, ENERGY_UNIT, ENERGY_STATUS_MASK, 0);
+	return 0;
+}
+
+static int release_zone(struct powercap_zone *power_zone)
+{
+	struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
+	struct rapl_package *rp = rd->rp;
+
+	/* package zone is the last zone of a package, we can free
+	 * memory here since all children has been unregistered.
+	 */
+	if (rd->id == RAPL_DOMAIN_PACKAGE) {
+		kfree(rd);
+		rp->domains = NULL;
+	}
+
+	return 0;
+
+}
+
+static int find_nr_power_limit(struct rapl_domain *rd)
+{
+	int i, nr_pl = 0;
+
+	for (i = 0; i < NR_POWER_LIMITS; i++) {
+		if (rd->rpl[i].name)
+			nr_pl++;
+	}
+
+	return nr_pl;
+}
+
+static int set_domain_enable(struct powercap_zone *power_zone, bool mode)
+{
+	struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
+
+	if (rd->state & DOMAIN_STATE_BIOS_LOCKED)
+		return -EACCES;
+
+	get_online_cpus();
+	rapl_write_data_raw(rd, PL1_ENABLE, mode);
+	if (rapl_defaults->set_floor_freq)
+		rapl_defaults->set_floor_freq(rd, mode);
+	put_online_cpus();
+
+	return 0;
+}
+
+static int get_domain_enable(struct powercap_zone *power_zone, bool *mode)
+{
+	struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
+	u64 val;
+
+	if (rd->state & DOMAIN_STATE_BIOS_LOCKED) {
+		*mode = false;
+		return 0;
+	}
+	get_online_cpus();
+	if (rapl_read_data_raw(rd, PL1_ENABLE, true, &val)) {
+		put_online_cpus();
+		return -EIO;
+	}
+	*mode = val;
+	put_online_cpus();
+
+	return 0;
+}
+
+/* per RAPL domain ops, in the order of rapl_domain_type */
+static const struct powercap_zone_ops zone_ops[] = {
+	/* RAPL_DOMAIN_PACKAGE */
+	{
+	 .get_energy_uj = get_energy_counter,
+	 .get_max_energy_range_uj = get_max_energy_counter,
+	 .release = release_zone,
+	 .set_enable = set_domain_enable,
+	 .get_enable = get_domain_enable,
+	 },
+	/* RAPL_DOMAIN_PP0 */
+	{
+	 .get_energy_uj = get_energy_counter,
+	 .get_max_energy_range_uj = get_max_energy_counter,
+	 .release = release_zone,
+	 .set_enable = set_domain_enable,
+	 .get_enable = get_domain_enable,
+	 },
+	/* RAPL_DOMAIN_PP1 */
+	{
+	 .get_energy_uj = get_energy_counter,
+	 .get_max_energy_range_uj = get_max_energy_counter,
+	 .release = release_zone,
+	 .set_enable = set_domain_enable,
+	 .get_enable = get_domain_enable,
+	 },
+	/* RAPL_DOMAIN_DRAM */
+	{
+	 .get_energy_uj = get_energy_counter,
+	 .get_max_energy_range_uj = get_max_energy_counter,
+	 .release = release_zone,
+	 .set_enable = set_domain_enable,
+	 .get_enable = get_domain_enable,
+	 },
+	/* RAPL_DOMAIN_PLATFORM */
+	{
+	 .get_energy_uj = get_energy_counter,
+	 .get_max_energy_range_uj = get_max_energy_counter,
+	 .release = release_zone,
+	 .set_enable = set_domain_enable,
+	 .get_enable = get_domain_enable,
+	 },
+};
+
+/*
+ * Constraint index used by powercap can be different than power limit (PL)
+ * index in that some  PLs maybe missing due to non-existent MSRs. So we
+ * need to convert here by finding the valid PLs only (name populated).
+ */
+static int contraint_to_pl(struct rapl_domain *rd, int cid)
+{
+	int i, j;
+
+	for (i = 0, j = 0; i < NR_POWER_LIMITS; i++) {
+		if ((rd->rpl[i].name) && j++ == cid) {
+			pr_debug("%s: index %d\n", __func__, i);
+			return i;
+		}
+	}
+	pr_err("Cannot find matching power limit for constraint %d\n", cid);
+
+	return -EINVAL;
+}
+
+static int set_power_limit(struct powercap_zone *power_zone, int cid,
+			   u64 power_limit)
+{
+	struct rapl_domain *rd;
+	struct rapl_package *rp;
+	int ret = 0;
+	int id;
+
+	get_online_cpus();
+	rd = power_zone_to_rapl_domain(power_zone);
+	id = contraint_to_pl(rd, cid);
+	if (id < 0) {
+		ret = id;
+		goto set_exit;
+	}
+
+	rp = rd->rp;
+
+	if (rd->state & DOMAIN_STATE_BIOS_LOCKED) {
+		dev_warn(&power_zone->dev,
+			 "%s locked by BIOS, monitoring only\n", rd->name);
+		ret = -EACCES;
+		goto set_exit;
+	}
+
+	switch (rd->rpl[id].prim_id) {
+	case PL1_ENABLE:
+		rapl_write_data_raw(rd, POWER_LIMIT1, power_limit);
+		break;
+	case PL2_ENABLE:
+		rapl_write_data_raw(rd, POWER_LIMIT2, power_limit);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	if (!ret)
+		package_power_limit_irq_save(rp);
+set_exit:
+	put_online_cpus();
+	return ret;
+}
+
+static int get_current_power_limit(struct powercap_zone *power_zone, int cid,
+				   u64 *data)
+{
+	struct rapl_domain *rd;
+	u64 val;
+	int prim;
+	int ret = 0;
+	int id;
+
+	get_online_cpus();
+	rd = power_zone_to_rapl_domain(power_zone);
+	id = contraint_to_pl(rd, cid);
+	if (id < 0) {
+		ret = id;
+		goto get_exit;
+	}
+
+	switch (rd->rpl[id].prim_id) {
+	case PL1_ENABLE:
+		prim = POWER_LIMIT1;
+		break;
+	case PL2_ENABLE:
+		prim = POWER_LIMIT2;
+		break;
+	default:
+		put_online_cpus();
+		return -EINVAL;
+	}
+	if (rapl_read_data_raw(rd, prim, true, &val))
+		ret = -EIO;
+	else
+		*data = val;
+
+get_exit:
+	put_online_cpus();
+
+	return ret;
+}
+
+static int set_time_window(struct powercap_zone *power_zone, int cid,
+			   u64 window)
+{
+	struct rapl_domain *rd;
+	int ret = 0;
+	int id;
+
+	get_online_cpus();
+	rd = power_zone_to_rapl_domain(power_zone);
+	id = contraint_to_pl(rd, cid);
+	if (id < 0) {
+		ret = id;
+		goto set_time_exit;
+	}
+
+	switch (rd->rpl[id].prim_id) {
+	case PL1_ENABLE:
+		rapl_write_data_raw(rd, TIME_WINDOW1, window);
+		break;
+	case PL2_ENABLE:
+		rapl_write_data_raw(rd, TIME_WINDOW2, window);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+set_time_exit:
+	put_online_cpus();
+	return ret;
+}
+
+static int get_time_window(struct powercap_zone *power_zone, int cid,
+			   u64 *data)
+{
+	struct rapl_domain *rd;
+	u64 val;
+	int ret = 0;
+	int id;
+
+	get_online_cpus();
+	rd = power_zone_to_rapl_domain(power_zone);
+	id = contraint_to_pl(rd, cid);
+	if (id < 0) {
+		ret = id;
+		goto get_time_exit;
+	}
+
+	switch (rd->rpl[id].prim_id) {
+	case PL1_ENABLE:
+		ret = rapl_read_data_raw(rd, TIME_WINDOW1, true, &val);
+		break;
+	case PL2_ENABLE:
+		ret = rapl_read_data_raw(rd, TIME_WINDOW2, true, &val);
+		break;
+	default:
+		put_online_cpus();
+		return -EINVAL;
+	}
+	if (!ret)
+		*data = val;
+
+get_time_exit:
+	put_online_cpus();
+
+	return ret;
+}
+
+static const char *get_constraint_name(struct powercap_zone *power_zone,
+				       int cid)
+{
+	struct rapl_domain *rd;
+	int id;
+
+	rd = power_zone_to_rapl_domain(power_zone);
+	id = contraint_to_pl(rd, cid);
+	if (id >= 0)
+		return rd->rpl[id].name;
+
+	return NULL;
+}
+
+static int get_max_power(struct powercap_zone *power_zone, int id, u64 *data)
+{
+	struct rapl_domain *rd;
+	u64 val;
+	int prim;
+	int ret = 0;
+
+	get_online_cpus();
+	rd = power_zone_to_rapl_domain(power_zone);
+	switch (rd->rpl[id].prim_id) {
+	case PL1_ENABLE:
+		prim = THERMAL_SPEC_POWER;
+		break;
+	case PL2_ENABLE:
+		prim = MAX_POWER;
+		break;
+	default:
+		put_online_cpus();
+		return -EINVAL;
+	}
+	if (rapl_read_data_raw(rd, prim, true, &val))
+		ret = -EIO;
+	else
+		*data = val;
+
+	put_online_cpus();
+
+	return ret;
+}
+
+static const struct powercap_zone_constraint_ops constraint_ops = {
+	.set_power_limit_uw = set_power_limit,
+	.get_power_limit_uw = get_current_power_limit,
+	.set_time_window_us = set_time_window,
+	.get_time_window_us = get_time_window,
+	.get_max_power_uw = get_max_power,
+	.get_name = get_constraint_name,
+};
+
+/* called after domain detection and package level data are set */
+static void rapl_init_domains(struct rapl_package *rp)
+{
+	int i;
+	struct rapl_domain *rd = rp->domains;
+
+	for (i = 0; i < RAPL_DOMAIN_MAX; i++) {
+		unsigned int mask = rp->domain_map & (1 << i);
+
+		rd->regs[RAPL_DOMAIN_REG_LIMIT] =
+		    rp->priv->regs[i][RAPL_DOMAIN_REG_LIMIT];
+		rd->regs[RAPL_DOMAIN_REG_STATUS] =
+		    rp->priv->regs[i][RAPL_DOMAIN_REG_STATUS];
+		rd->regs[RAPL_DOMAIN_REG_PERF] =
+		    rp->priv->regs[i][RAPL_DOMAIN_REG_PERF];
+		rd->regs[RAPL_DOMAIN_REG_POLICY] =
+		    rp->priv->regs[i][RAPL_DOMAIN_REG_POLICY];
+		rd->regs[RAPL_DOMAIN_REG_INFO] =
+		    rp->priv->regs[i][RAPL_DOMAIN_REG_INFO];
+
+		switch (mask) {
+		case BIT(RAPL_DOMAIN_PACKAGE):
+			rd->name = rapl_domain_names[RAPL_DOMAIN_PACKAGE];
+			rd->id = RAPL_DOMAIN_PACKAGE;
+			rd->rpl[0].prim_id = PL1_ENABLE;
+			rd->rpl[0].name = pl1_name;
+			rd->rpl[1].prim_id = PL2_ENABLE;
+			rd->rpl[1].name = pl2_name;
+			break;
+		case BIT(RAPL_DOMAIN_PP0):
+			rd->name = rapl_domain_names[RAPL_DOMAIN_PP0];
+			rd->id = RAPL_DOMAIN_PP0;
+			rd->rpl[0].prim_id = PL1_ENABLE;
+			rd->rpl[0].name = pl1_name;
+			break;
+		case BIT(RAPL_DOMAIN_PP1):
+			rd->name = rapl_domain_names[RAPL_DOMAIN_PP1];
+			rd->id = RAPL_DOMAIN_PP1;
+			rd->rpl[0].prim_id = PL1_ENABLE;
+			rd->rpl[0].name = pl1_name;
+			break;
+		case BIT(RAPL_DOMAIN_DRAM):
+			rd->name = rapl_domain_names[RAPL_DOMAIN_DRAM];
+			rd->id = RAPL_DOMAIN_DRAM;
+			rd->rpl[0].prim_id = PL1_ENABLE;
+			rd->rpl[0].name = pl1_name;
+			rd->domain_energy_unit =
+			    rapl_defaults->dram_domain_energy_unit;
+			if (rd->domain_energy_unit)
+				pr_info("DRAM domain energy unit %dpj\n",
+					rd->domain_energy_unit);
+			break;
+		}
+		if (mask) {
+			rd->rp = rp;
+			rd++;
+		}
+	}
+}
+
+static u64 rapl_unit_xlate(struct rapl_domain *rd, enum unit_type type,
+			   u64 value, int to_raw)
+{
+	u64 units = 1;
+	struct rapl_package *rp = rd->rp;
+	u64 scale = 1;
+
+	switch (type) {
+	case POWER_UNIT:
+		units = rp->power_unit;
+		break;
+	case ENERGY_UNIT:
+		scale = ENERGY_UNIT_SCALE;
+		/* per domain unit takes precedence */
+		if (rd->domain_energy_unit)
+			units = rd->domain_energy_unit;
+		else
+			units = rp->energy_unit;
+		break;
+	case TIME_UNIT:
+		return rapl_defaults->compute_time_window(rp, value, to_raw);
+	case ARBITRARY_UNIT:
+	default:
+		return value;
+	};
+
+	if (to_raw)
+		return div64_u64(value, units) * scale;
+
+	value *= units;
+
+	return div64_u64(value, scale);
+}
+
+/* in the order of enum rapl_primitives */
+static struct rapl_primitive_info rpi[] = {
+	/* name, mask, shift, msr index, unit divisor */
+	PRIMITIVE_INFO_INIT(ENERGY_COUNTER, ENERGY_STATUS_MASK, 0,
+			    RAPL_DOMAIN_REG_STATUS, ENERGY_UNIT, 0),
+	PRIMITIVE_INFO_INIT(POWER_LIMIT1, POWER_LIMIT1_MASK, 0,
+			    RAPL_DOMAIN_REG_LIMIT, POWER_UNIT, 0),
+	PRIMITIVE_INFO_INIT(POWER_LIMIT2, POWER_LIMIT2_MASK, 32,
+			    RAPL_DOMAIN_REG_LIMIT, POWER_UNIT, 0),
+	PRIMITIVE_INFO_INIT(FW_LOCK, POWER_PP_LOCK, 31,
+			    RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
+	PRIMITIVE_INFO_INIT(PL1_ENABLE, POWER_LIMIT1_ENABLE, 15,
+			    RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
+	PRIMITIVE_INFO_INIT(PL1_CLAMP, POWER_LIMIT1_CLAMP, 16,
+			    RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
+	PRIMITIVE_INFO_INIT(PL2_ENABLE, POWER_LIMIT2_ENABLE, 47,
+			    RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
+	PRIMITIVE_INFO_INIT(PL2_CLAMP, POWER_LIMIT2_CLAMP, 48,
+			    RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
+	PRIMITIVE_INFO_INIT(TIME_WINDOW1, TIME_WINDOW1_MASK, 17,
+			    RAPL_DOMAIN_REG_LIMIT, TIME_UNIT, 0),
+	PRIMITIVE_INFO_INIT(TIME_WINDOW2, TIME_WINDOW2_MASK, 49,
+			    RAPL_DOMAIN_REG_LIMIT, TIME_UNIT, 0),
+	PRIMITIVE_INFO_INIT(THERMAL_SPEC_POWER, POWER_INFO_THERMAL_SPEC_MASK,
+			    0, RAPL_DOMAIN_REG_INFO, POWER_UNIT, 0),
+	PRIMITIVE_INFO_INIT(MAX_POWER, POWER_INFO_MAX_MASK, 32,
+			    RAPL_DOMAIN_REG_INFO, POWER_UNIT, 0),
+	PRIMITIVE_INFO_INIT(MIN_POWER, POWER_INFO_MIN_MASK, 16,
+			    RAPL_DOMAIN_REG_INFO, POWER_UNIT, 0),
+	PRIMITIVE_INFO_INIT(MAX_TIME_WINDOW, POWER_INFO_MAX_TIME_WIN_MASK, 48,
+			    RAPL_DOMAIN_REG_INFO, TIME_UNIT, 0),
+	PRIMITIVE_INFO_INIT(THROTTLED_TIME, PERF_STATUS_THROTTLE_TIME_MASK, 0,
+			    RAPL_DOMAIN_REG_PERF, TIME_UNIT, 0),
+	PRIMITIVE_INFO_INIT(PRIORITY_LEVEL, PP_POLICY_MASK, 0,
+			    RAPL_DOMAIN_REG_POLICY, ARBITRARY_UNIT, 0),
+	/* non-hardware */
+	PRIMITIVE_INFO_INIT(AVERAGE_POWER, 0, 0, 0, POWER_UNIT,
+			    RAPL_PRIMITIVE_DERIVED),
+	{NULL, 0, 0, 0},
+};
+
+/* Read primitive data based on its related struct rapl_primitive_info.
+ * if xlate flag is set, return translated data based on data units, i.e.
+ * time, energy, and power.
+ * RAPL MSRs are non-architectual and are laid out not consistently across
+ * domains. Here we use primitive info to allow writing consolidated access
+ * functions.
+ * For a given primitive, it is processed by MSR mask and shift. Unit conversion
+ * is pre-assigned based on RAPL unit MSRs read at init time.
+ * 63-------------------------- 31--------------------------- 0
+ * |                           xxxxx (mask)                   |
+ * |                                |<- shift ----------------|
+ * 63-------------------------- 31--------------------------- 0
+ */
+static int rapl_read_data_raw(struct rapl_domain *rd,
+			      enum rapl_primitives prim, bool xlate, u64 *data)
+{
+	u64 value;
+	struct rapl_primitive_info *rp = &rpi[prim];
+	struct reg_action ra;
+	int cpu;
+
+	if (!rp->name || rp->flag & RAPL_PRIMITIVE_DUMMY)
+		return -EINVAL;
+
+	ra.reg = rd->regs[rp->id];
+	if (!ra.reg)
+		return -EINVAL;
+
+	cpu = rd->rp->lead_cpu;
+
+	/* special-case package domain, which uses a different bit */
+	if (prim == FW_LOCK && rd->id == RAPL_DOMAIN_PACKAGE) {
+		rp->mask = POWER_PACKAGE_LOCK;
+		rp->shift = 63;
+	}
+	/* non-hardware data are collected by the polling thread */
+	if (rp->flag & RAPL_PRIMITIVE_DERIVED) {
+		*data = rd->rdd.primitives[prim];
+		return 0;
+	}
+
+	ra.mask = rp->mask;
+
+	if (rd->rp->priv->read_raw(cpu, &ra)) {
+		pr_debug("failed to read reg 0x%x on cpu %d\n", ra.reg, cpu);
+		return -EIO;
+	}
+
+	value = ra.value >> rp->shift;
+
+	if (xlate)
+		*data = rapl_unit_xlate(rd, rp->unit, value, 0);
+	else
+		*data = value;
+
+	return 0;
+}
+
+/* Similar use of primitive info in the read counterpart */
+static int rapl_write_data_raw(struct rapl_domain *rd,
+			       enum rapl_primitives prim,
+			       unsigned long long value)
+{
+	struct rapl_primitive_info *rp = &rpi[prim];
+	int cpu;
+	u64 bits;
+	struct reg_action ra;
+	int ret;
+
+	cpu = rd->rp->lead_cpu;
+	bits = rapl_unit_xlate(rd, rp->unit, value, 1);
+	bits <<= rp->shift;
+	bits &= rp->mask;
+
+	memset(&ra, 0, sizeof(ra));
+
+	ra.reg = rd->regs[rp->id];
+	ra.mask = rp->mask;
+	ra.value = bits;
+
+	ret = rd->rp->priv->write_raw(cpu, &ra);
+
+	return ret;
+}
+
+/*
+ * Raw RAPL data stored in MSRs are in certain scales. We need to
+ * convert them into standard units based on the units reported in
+ * the RAPL unit MSRs. This is specific to CPUs as the method to
+ * calculate units differ on different CPUs.
+ * We convert the units to below format based on CPUs.
+ * i.e.
+ * energy unit: picoJoules  : Represented in picoJoules by default
+ * power unit : microWatts  : Represented in milliWatts by default
+ * time unit  : microseconds: Represented in seconds by default
+ */
+static int rapl_check_unit_core(struct rapl_package *rp, int cpu)
+{
+	struct reg_action ra;
+	u32 value;
+
+	ra.reg = rp->priv->reg_unit;
+	ra.mask = ~0;
+	if (rp->priv->read_raw(cpu, &ra)) {
+		pr_err("Failed to read power unit REG 0x%x on CPU %d, exit.\n",
+		       rp->priv->reg_unit, cpu);
+		return -ENODEV;
+	}
+
+	value = (ra.value & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
+	rp->energy_unit = ENERGY_UNIT_SCALE * 1000000 / (1 << value);
+
+	value = (ra.value & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
+	rp->power_unit = 1000000 / (1 << value);
+
+	value = (ra.value & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
+	rp->time_unit = 1000000 / (1 << value);
+
+	pr_debug("Core CPU %s energy=%dpJ, time=%dus, power=%duW\n",
+		 rp->name, rp->energy_unit, rp->time_unit, rp->power_unit);
+
+	return 0;
+}
+
+static int rapl_check_unit_atom(struct rapl_package *rp, int cpu)
+{
+	struct reg_action ra;
+	u32 value;
+
+	ra.reg = rp->priv->reg_unit;
+	ra.mask = ~0;
+	if (rp->priv->read_raw(cpu, &ra)) {
+		pr_err("Failed to read power unit REG 0x%x on CPU %d, exit.\n",
+		       rp->priv->reg_unit, cpu);
+		return -ENODEV;
+	}
+
+	value = (ra.value & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
+	rp->energy_unit = ENERGY_UNIT_SCALE * 1 << value;
+
+	value = (ra.value & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
+	rp->power_unit = (1 << value) * 1000;
+
+	value = (ra.value & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
+	rp->time_unit = 1000000 / (1 << value);
+
+	pr_debug("Atom %s energy=%dpJ, time=%dus, power=%duW\n",
+		 rp->name, rp->energy_unit, rp->time_unit, rp->power_unit);
+
+	return 0;
+}
+
+static void power_limit_irq_save_cpu(void *info)
+{
+	u32 l, h = 0;
+	struct rapl_package *rp = (struct rapl_package *)info;
+
+	/* save the state of PLN irq mask bit before disabling it */
+	rdmsr_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, &l, &h);
+	if (!(rp->power_limit_irq & PACKAGE_PLN_INT_SAVED)) {
+		rp->power_limit_irq = l & PACKAGE_THERM_INT_PLN_ENABLE;
+		rp->power_limit_irq |= PACKAGE_PLN_INT_SAVED;
+	}
+	l &= ~PACKAGE_THERM_INT_PLN_ENABLE;
+	wrmsr_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
+}
+
+/* REVISIT:
+ * When package power limit is set artificially low by RAPL, LVT
+ * thermal interrupt for package power limit should be ignored
+ * since we are not really exceeding the real limit. The intention
+ * is to avoid excessive interrupts while we are trying to save power.
+ * A useful feature might be routing the package_power_limit interrupt
+ * to userspace via eventfd. once we have a usecase, this is simple
+ * to do by adding an atomic notifier.
+ */
+
+static void package_power_limit_irq_save(struct rapl_package *rp)
+{
+	if (!boot_cpu_has(X86_FEATURE_PTS) || !boot_cpu_has(X86_FEATURE_PLN))
+		return;
+
+	smp_call_function_single(rp->lead_cpu, power_limit_irq_save_cpu, rp, 1);
+}
+
+/*
+ * Restore per package power limit interrupt enable state. Called from cpu
+ * hotplug code on package removal.
+ */
+static void package_power_limit_irq_restore(struct rapl_package *rp)
+{
+	u32 l, h;
+
+	if (!boot_cpu_has(X86_FEATURE_PTS) || !boot_cpu_has(X86_FEATURE_PLN))
+		return;
+
+	/* irq enable state not saved, nothing to restore */
+	if (!(rp->power_limit_irq & PACKAGE_PLN_INT_SAVED))
+		return;
+
+	rdmsr_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, &l, &h);
+
+	if (rp->power_limit_irq & PACKAGE_THERM_INT_PLN_ENABLE)
+		l |= PACKAGE_THERM_INT_PLN_ENABLE;
+	else
+		l &= ~PACKAGE_THERM_INT_PLN_ENABLE;
+
+	wrmsr_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
+}
+
+static void set_floor_freq_default(struct rapl_domain *rd, bool mode)
+{
+	int nr_powerlimit = find_nr_power_limit(rd);
+
+	/* always enable clamp such that p-state can go below OS requested
+	 * range. power capping priority over guranteed frequency.
+	 */
+	rapl_write_data_raw(rd, PL1_CLAMP, mode);
+
+	/* some domains have pl2 */
+	if (nr_powerlimit > 1) {
+		rapl_write_data_raw(rd, PL2_ENABLE, mode);
+		rapl_write_data_raw(rd, PL2_CLAMP, mode);
+	}
+}
+
+static void set_floor_freq_atom(struct rapl_domain *rd, bool enable)
+{
+	static u32 power_ctrl_orig_val;
+	u32 mdata;
+
+	if (!rapl_defaults->floor_freq_reg_addr) {
+		pr_err("Invalid floor frequency config register\n");
+		return;
+	}
+
+	if (!power_ctrl_orig_val)
+		iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_CR_READ,
+			      rapl_defaults->floor_freq_reg_addr,
+			      &power_ctrl_orig_val);
+	mdata = power_ctrl_orig_val;
+	if (enable) {
+		mdata &= ~(0x7f << 8);
+		mdata |= 1 << 8;
+	}
+	iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_CR_WRITE,
+		       rapl_defaults->floor_freq_reg_addr, mdata);
+}
+
+static u64 rapl_compute_time_window_core(struct rapl_package *rp, u64 value,
+					 bool to_raw)
+{
+	u64 f, y;		/* fraction and exp. used for time unit */
+
+	/*
+	 * Special processing based on 2^Y*(1+F/4), refer
+	 * to Intel Software Developer's manual Vol.3B: CH 14.9.3.
+	 */
+	if (!to_raw) {
+		f = (value & 0x60) >> 5;
+		y = value & 0x1f;
+		value = (1 << y) * (4 + f) * rp->time_unit / 4;
+	} else {
+		do_div(value, rp->time_unit);
+		y = ilog2(value);
+		f = div64_u64(4 * (value - (1 << y)), 1 << y);
+		value = (y & 0x1f) | ((f & 0x3) << 5);
+	}
+	return value;
+}
+
+static u64 rapl_compute_time_window_atom(struct rapl_package *rp, u64 value,
+					 bool to_raw)
+{
+	/*
+	 * Atom time unit encoding is straight forward val * time_unit,
+	 * where time_unit is default to 1 sec. Never 0.
+	 */
+	if (!to_raw)
+		return (value) ? value *= rp->time_unit : rp->time_unit;
+
+	value = div64_u64(value, rp->time_unit);
+
+	return value;
+}
+
+static const struct rapl_defaults rapl_defaults_core = {
+	.floor_freq_reg_addr = 0,
+	.check_unit = rapl_check_unit_core,
+	.set_floor_freq = set_floor_freq_default,
+	.compute_time_window = rapl_compute_time_window_core,
+};
+
+static const struct rapl_defaults rapl_defaults_hsw_server = {
+	.check_unit = rapl_check_unit_core,
+	.set_floor_freq = set_floor_freq_default,
+	.compute_time_window = rapl_compute_time_window_core,
+	.dram_domain_energy_unit = 15300,
+};
+
+static const struct rapl_defaults rapl_defaults_byt = {
+	.floor_freq_reg_addr = IOSF_CPU_POWER_BUDGET_CTL_BYT,
+	.check_unit = rapl_check_unit_atom,
+	.set_floor_freq = set_floor_freq_atom,
+	.compute_time_window = rapl_compute_time_window_atom,
+};
+
+static const struct rapl_defaults rapl_defaults_tng = {
+	.floor_freq_reg_addr = IOSF_CPU_POWER_BUDGET_CTL_TNG,
+	.check_unit = rapl_check_unit_atom,
+	.set_floor_freq = set_floor_freq_atom,
+	.compute_time_window = rapl_compute_time_window_atom,
+};
+
+static const struct rapl_defaults rapl_defaults_ann = {
+	.floor_freq_reg_addr = 0,
+	.check_unit = rapl_check_unit_atom,
+	.set_floor_freq = NULL,
+	.compute_time_window = rapl_compute_time_window_atom,
+};
+
+static const struct rapl_defaults rapl_defaults_cht = {
+	.floor_freq_reg_addr = 0,
+	.check_unit = rapl_check_unit_atom,
+	.set_floor_freq = NULL,
+	.compute_time_window = rapl_compute_time_window_atom,
+};
+
+static const struct x86_cpu_id rapl_ids[] = {
+	INTEL_CPU_FAM6(SANDYBRIDGE, rapl_defaults_core),
+	INTEL_CPU_FAM6(SANDYBRIDGE_X, rapl_defaults_core),
+
+	INTEL_CPU_FAM6(IVYBRIDGE, rapl_defaults_core),
+	INTEL_CPU_FAM6(IVYBRIDGE_X, rapl_defaults_core),
+
+	INTEL_CPU_FAM6(HASWELL_CORE, rapl_defaults_core),
+	INTEL_CPU_FAM6(HASWELL_ULT, rapl_defaults_core),
+	INTEL_CPU_FAM6(HASWELL_GT3E, rapl_defaults_core),
+	INTEL_CPU_FAM6(HASWELL_X, rapl_defaults_hsw_server),
+
+	INTEL_CPU_FAM6(BROADWELL_CORE, rapl_defaults_core),
+	INTEL_CPU_FAM6(BROADWELL_GT3E, rapl_defaults_core),
+	INTEL_CPU_FAM6(BROADWELL_XEON_D, rapl_defaults_core),
+	INTEL_CPU_FAM6(BROADWELL_X, rapl_defaults_hsw_server),
+
+	INTEL_CPU_FAM6(SKYLAKE_DESKTOP, rapl_defaults_core),
+	INTEL_CPU_FAM6(SKYLAKE_MOBILE, rapl_defaults_core),
+	INTEL_CPU_FAM6(SKYLAKE_X, rapl_defaults_hsw_server),
+	INTEL_CPU_FAM6(KABYLAKE_MOBILE, rapl_defaults_core),
+	INTEL_CPU_FAM6(KABYLAKE_DESKTOP, rapl_defaults_core),
+	INTEL_CPU_FAM6(CANNONLAKE_MOBILE, rapl_defaults_core),
+	INTEL_CPU_FAM6(ICELAKE_MOBILE, rapl_defaults_core),
+
+	INTEL_CPU_FAM6(ATOM_SILVERMONT, rapl_defaults_byt),
+	INTEL_CPU_FAM6(ATOM_AIRMONT, rapl_defaults_cht),
+	INTEL_CPU_FAM6(ATOM_SILVERMONT_MID, rapl_defaults_tng),
+	INTEL_CPU_FAM6(ATOM_AIRMONT_MID, rapl_defaults_ann),
+	INTEL_CPU_FAM6(ATOM_GOLDMONT, rapl_defaults_core),
+	INTEL_CPU_FAM6(ATOM_GOLDMONT_PLUS, rapl_defaults_core),
+	INTEL_CPU_FAM6(ATOM_GOLDMONT_X, rapl_defaults_core),
+	INTEL_CPU_FAM6(ATOM_TREMONT_X, rapl_defaults_core),
+
+	INTEL_CPU_FAM6(XEON_PHI_KNL, rapl_defaults_hsw_server),
+	INTEL_CPU_FAM6(XEON_PHI_KNM, rapl_defaults_hsw_server),
+	{}
+};
+
+MODULE_DEVICE_TABLE(x86cpu, rapl_ids);
+
+/* Read once for all raw primitive data for domains */
+static void rapl_update_domain_data(struct rapl_package *rp)
+{
+	int dmn, prim;
+	u64 val;
+
+	for (dmn = 0; dmn < rp->nr_domains; dmn++) {
+		pr_debug("update %s domain %s data\n", rp->name,
+			 rp->domains[dmn].name);
+		/* exclude non-raw primitives */
+		for (prim = 0; prim < NR_RAW_PRIMITIVES; prim++) {
+			if (!rapl_read_data_raw(&rp->domains[dmn], prim,
+						rpi[prim].unit, &val))
+				rp->domains[dmn].rdd.primitives[prim] = val;
+		}
+	}
+
+}
+
+static int rapl_package_register_powercap(struct rapl_package *rp)
+{
+	struct rapl_domain *rd;
+	struct powercap_zone *power_zone = NULL;
+	int nr_pl, ret;
+
+	/* Update the domain data of the new package */
+	rapl_update_domain_data(rp);
+
+	/* first we register package domain as the parent zone */
+	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
+		if (rd->id == RAPL_DOMAIN_PACKAGE) {
+			nr_pl = find_nr_power_limit(rd);
+			pr_debug("register package domain %s\n", rp->name);
+			power_zone = powercap_register_zone(&rd->power_zone,
+					    rp->priv->control_type, rp->name,
+					    NULL, &zone_ops[rd->id], nr_pl,
+					    &constraint_ops);
+			if (IS_ERR(power_zone)) {
+				pr_debug("failed to register power zone %s\n",
+					 rp->name);
+				return PTR_ERR(power_zone);
+			}
+			/* track parent zone in per package/socket data */
+			rp->power_zone = power_zone;
+			/* done, only one package domain per socket */
+			break;
+		}
+	}
+	if (!power_zone) {
+		pr_err("no package domain found, unknown topology!\n");
+		return -ENODEV;
+	}
+	/* now register domains as children of the socket/package */
+	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
+		if (rd->id == RAPL_DOMAIN_PACKAGE)
+			continue;
+		/* number of power limits per domain varies */
+		nr_pl = find_nr_power_limit(rd);
+		power_zone = powercap_register_zone(&rd->power_zone,
+						    rp->priv->control_type,
+						    rd->name, rp->power_zone,
+						    &zone_ops[rd->id], nr_pl,
+						    &constraint_ops);
+
+		if (IS_ERR(power_zone)) {
+			pr_debug("failed to register power_zone, %s:%s\n",
+				 rp->name, rd->name);
+			ret = PTR_ERR(power_zone);
+			goto err_cleanup;
+		}
+	}
+	return 0;
+
+err_cleanup:
+	/*
+	 * Clean up previously initialized domains within the package if we
+	 * failed after the first domain setup.
+	 */
+	while (--rd >= rp->domains) {
+		pr_debug("unregister %s domain %s\n", rp->name, rd->name);
+		powercap_unregister_zone(rp->priv->control_type,
+					 &rd->power_zone);
+	}
+
+	return ret;
+}
+
+int rapl_add_platform_domain(struct rapl_if_priv *priv)
+{
+	struct rapl_domain *rd;
+	struct powercap_zone *power_zone;
+	struct reg_action ra;
+	int ret;
+
+	ra.reg = priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_STATUS];
+	ra.mask = ~0;
+	ret = priv->read_raw(0, &ra);
+	if (ret || !ra.value)
+		return -ENODEV;
+
+	ra.reg = priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_LIMIT];
+	ra.mask = ~0;
+	ret = priv->read_raw(0, &ra);
+	if (ret || !ra.value)
+		return -ENODEV;
+
+	rd = kzalloc(sizeof(*rd), GFP_KERNEL);
+	if (!rd)
+		return -ENOMEM;
+
+	rd->name = rapl_domain_names[RAPL_DOMAIN_PLATFORM];
+	rd->id = RAPL_DOMAIN_PLATFORM;
+	rd->regs[RAPL_DOMAIN_REG_LIMIT] =
+	    priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_LIMIT];
+	rd->regs[RAPL_DOMAIN_REG_STATUS] =
+	    priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_STATUS];
+	rd->rpl[0].prim_id = PL1_ENABLE;
+	rd->rpl[0].name = pl1_name;
+	rd->rpl[1].prim_id = PL2_ENABLE;
+	rd->rpl[1].name = pl2_name;
+	rd->rp = rapl_find_package_domain(0, priv);
+
+	power_zone = powercap_register_zone(&rd->power_zone, priv->control_type,
+					    "psys", NULL,
+					    &zone_ops[RAPL_DOMAIN_PLATFORM],
+					    2, &constraint_ops);
+
+	if (IS_ERR(power_zone)) {
+		kfree(rd);
+		return PTR_ERR(power_zone);
+	}
+
+	priv->platform_rapl_domain = rd;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rapl_add_platform_domain);
+
+void rapl_remove_platform_domain(struct rapl_if_priv *priv)
+{
+	if (priv->platform_rapl_domain) {
+		powercap_unregister_zone(priv->control_type,
+				 &priv->platform_rapl_domain->power_zone);
+		kfree(priv->platform_rapl_domain);
+	}
+}
+EXPORT_SYMBOL_GPL(rapl_remove_platform_domain);
+
+static int rapl_check_domain(int cpu, int domain, struct rapl_package *rp)
+{
+	struct reg_action ra;
+
+	switch (domain) {
+	case RAPL_DOMAIN_PACKAGE:
+	case RAPL_DOMAIN_PP0:
+	case RAPL_DOMAIN_PP1:
+	case RAPL_DOMAIN_DRAM:
+		ra.reg = rp->priv->regs[domain][RAPL_DOMAIN_REG_STATUS];
+		break;
+	case RAPL_DOMAIN_PLATFORM:
+		/* PSYS(PLATFORM) is not a CPU domain, so avoid printng error */
+		return -EINVAL;
+	default:
+		pr_err("invalid domain id %d\n", domain);
+		return -EINVAL;
+	}
+	/* make sure domain counters are available and contains non-zero
+	 * values, otherwise skip it.
+	 */
+
+	ra.mask = ~0;
+	if (rp->priv->read_raw(cpu, &ra) || !ra.value)
+		return -ENODEV;
+
+	return 0;
+}
+
+/*
+ * Check if power limits are available. Two cases when they are not available:
+ * 1. Locked by BIOS, in this case we still provide read-only access so that
+ *    users can see what limit is set by the BIOS.
+ * 2. Some CPUs make some domains monitoring only which means PLx MSRs may not
+ *    exist at all. In this case, we do not show the constraints in powercap.
+ *
+ * Called after domains are detected and initialized.
+ */
+static void rapl_detect_powerlimit(struct rapl_domain *rd)
+{
+	u64 val64;
+	int i;
+
+	/* check if the domain is locked by BIOS, ignore if MSR doesn't exist */
+	if (!rapl_read_data_raw(rd, FW_LOCK, false, &val64)) {
+		if (val64) {
+			pr_info("RAPL %s domain %s locked by BIOS\n",
+				rd->rp->name, rd->name);
+			rd->state |= DOMAIN_STATE_BIOS_LOCKED;
+		}
+	}
+	/* check if power limit MSR exists, otherwise domain is monitoring only */
+	for (i = 0; i < NR_POWER_LIMITS; i++) {
+		int prim = rd->rpl[i].prim_id;
+
+		if (rapl_read_data_raw(rd, prim, false, &val64))
+			rd->rpl[i].name = NULL;
+	}
+}
+
+/* Detect active and valid domains for the given CPU, caller must
+ * ensure the CPU belongs to the targeted package and CPU hotlug is disabled.
+ */
+static int rapl_detect_domains(struct rapl_package *rp, int cpu)
+{
+	struct rapl_domain *rd;
+	int i;
+
+	for (i = 0; i < RAPL_DOMAIN_MAX; i++) {
+		/* use physical package id to read counters */
+		if (!rapl_check_domain(cpu, i, rp)) {
+			rp->domain_map |= 1 << i;
+			pr_info("Found RAPL domain %s\n", rapl_domain_names[i]);
+		}
+	}
+	rp->nr_domains = bitmap_weight(&rp->domain_map, RAPL_DOMAIN_MAX);
+	if (!rp->nr_domains) {
+		pr_debug("no valid rapl domains found in %s\n", rp->name);
+		return -ENODEV;
+	}
+	pr_debug("found %d domains on %s\n", rp->nr_domains, rp->name);
+
+	rp->domains = kcalloc(rp->nr_domains + 1, sizeof(struct rapl_domain),
+			      GFP_KERNEL);
+	if (!rp->domains)
+		return -ENOMEM;
+
+	rapl_init_domains(rp);
+
+	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++)
+		rapl_detect_powerlimit(rd);
+
+	return 0;
+}
+
+/* called from CPU hotplug notifier, hotplug lock held */
+void rapl_remove_package(struct rapl_package *rp)
+{
+	struct rapl_domain *rd, *rd_package = NULL;
+
+	package_power_limit_irq_restore(rp);
+
+	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
+		rapl_write_data_raw(rd, PL1_ENABLE, 0);
+		rapl_write_data_raw(rd, PL1_CLAMP, 0);
+		if (find_nr_power_limit(rd) > 1) {
+			rapl_write_data_raw(rd, PL2_ENABLE, 0);
+			rapl_write_data_raw(rd, PL2_CLAMP, 0);
+		}
+		if (rd->id == RAPL_DOMAIN_PACKAGE) {
+			rd_package = rd;
+			continue;
+		}
+		pr_debug("remove package, undo power limit on %s: %s\n",
+			 rp->name, rd->name);
+		powercap_unregister_zone(rp->priv->control_type,
+					 &rd->power_zone);
+	}
+	/* do parent zone last */
+	powercap_unregister_zone(rp->priv->control_type,
+				 &rd_package->power_zone);
+	list_del(&rp->plist);
+	if (list_empty(&rapl_packages))
+		rapl_remove_core();
+	kfree(rp);
+}
+EXPORT_SYMBOL_GPL(rapl_remove_package);
+
+/* caller to ensure CPU hotplug lock is held */
+struct rapl_package *rapl_find_package_domain(int cpu, struct rapl_if_priv *priv)
+{
+	int id = topology_logical_die_id(cpu);
+	struct rapl_package *rp;
+
+	list_for_each_entry(rp, &rapl_packages, plist) {
+		if (rp->id == id
+		    && rp->priv->control_type == priv->control_type)
+			return rp;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(rapl_find_package_domain);
+
+/* called from CPU hotplug notifier, hotplug lock held */
+struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv)
+{
+	int id = topology_logical_die_id(cpu);
+	struct rapl_package *rp;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
+	int ret;
+
+	ret = rapl_init_core();
+	if (ret)
+		return ERR_PTR(ret);
+
+	rp = kzalloc(sizeof(struct rapl_package), GFP_KERNEL);
+	if (!rp)
+		return ERR_PTR(-ENOMEM);
+
+	/* add the new package to the list */
+	rp->id = id;
+	rp->lead_cpu = cpu;
+	rp->priv = priv;
+
+	if (topology_max_die_per_package() > 1)
+		snprintf(rp->name, PACKAGE_DOMAIN_NAME_LENGTH,
+			 "package-%d-die-%d", c->phys_proc_id, c->cpu_die_id);
+	else
+		snprintf(rp->name, PACKAGE_DOMAIN_NAME_LENGTH, "package-%d",
+			 c->phys_proc_id);
+
+	/* check if the package contains valid domains */
+	if (rapl_detect_domains(rp, cpu) || rapl_defaults->check_unit(rp, cpu)) {
+		ret = -ENODEV;
+		goto err_free_package;
+	}
+	ret = rapl_package_register_powercap(rp);
+	if (!ret) {
+		INIT_LIST_HEAD(&rp->plist);
+		list_add(&rp->plist, &rapl_packages);
+		return rp;
+	}
+
+err_free_package:
+	kfree(rp->domains);
+	kfree(rp);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(rapl_add_package);
+
+static void power_limit_state_save(void)
+{
+	struct rapl_package *rp;
+	struct rapl_domain *rd;
+	int nr_pl, ret, i;
+
+	get_online_cpus();
+	list_for_each_entry(rp, &rapl_packages, plist) {
+		if (!rp->power_zone)
+			continue;
+		rd = power_zone_to_rapl_domain(rp->power_zone);
+		nr_pl = find_nr_power_limit(rd);
+		for (i = 0; i < nr_pl; i++) {
+			switch (rd->rpl[i].prim_id) {
+			case PL1_ENABLE:
+				ret = rapl_read_data_raw(rd,
+						 POWER_LIMIT1, true,
+						 &rd->rpl[i].last_power_limit);
+				if (ret)
+					rd->rpl[i].last_power_limit = 0;
+				break;
+			case PL2_ENABLE:
+				ret = rapl_read_data_raw(rd,
+						 POWER_LIMIT2, true,
+						 &rd->rpl[i].last_power_limit);
+				if (ret)
+					rd->rpl[i].last_power_limit = 0;
+				break;
+			}
+		}
+	}
+	put_online_cpus();
+}
+
+static void power_limit_state_restore(void)
+{
+	struct rapl_package *rp;
+	struct rapl_domain *rd;
+	int nr_pl, i;
+
+	get_online_cpus();
+	list_for_each_entry(rp, &rapl_packages, plist) {
+		if (!rp->power_zone)
+			continue;
+		rd = power_zone_to_rapl_domain(rp->power_zone);
+		nr_pl = find_nr_power_limit(rd);
+		for (i = 0; i < nr_pl; i++) {
+			switch (rd->rpl[i].prim_id) {
+			case PL1_ENABLE:
+				if (rd->rpl[i].last_power_limit)
+					rapl_write_data_raw(rd, POWER_LIMIT1,
+					    rd->rpl[i].last_power_limit);
+				break;
+			case PL2_ENABLE:
+				if (rd->rpl[i].last_power_limit)
+					rapl_write_data_raw(rd, POWER_LIMIT2,
+					    rd->rpl[i].last_power_limit);
+				break;
+			}
+		}
+	}
+	put_online_cpus();
+}
+
+static int rapl_pm_callback(struct notifier_block *nb,
+			    unsigned long mode, void *_unused)
+{
+	switch (mode) {
+	case PM_SUSPEND_PREPARE:
+		power_limit_state_save();
+		break;
+	case PM_POST_SUSPEND:
+		power_limit_state_restore();
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block rapl_pm_notifier = {
+	.notifier_call = rapl_pm_callback,
+};
+
+static int rapl_init_core(void)
+{
+	const struct x86_cpu_id *id;
+	int ret;
+
+	if (rapl_defaults)
+		return 0;
+
+	id = x86_match_cpu(rapl_ids);
+	if (!id) {
+		pr_err("driver does not support CPU family %d model %d\n",
+		       boot_cpu_data.x86, boot_cpu_data.x86_model);
+
+		return -ENODEV;
+	}
+
+	rapl_defaults = (struct rapl_defaults *)id->driver_data;
+
+	ret = register_pm_notifier(&rapl_pm_notifier);
+
+	return 0;
+}
+
+static void rapl_remove_core(void)
+{
+	unregister_pm_notifier(&rapl_pm_notifier);
+	rapl_defaults = NULL;
+}
+
+MODULE_DESCRIPTION("Intel Runtime Average Power Limit (RAPL) common code");
+MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c
new file mode 100644
index 0000000..8964522
--- /dev/null
+++ b/drivers/powercap/intel_rapl_msr.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Intel Running Average Power Limit (RAPL) Driver via MSR interface
+ * Copyright (c) 2019, Intel Corporation.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/log2.h>
+#include <linux/bitmap.h>
+#include <linux/delay.h>
+#include <linux/sysfs.h>
+#include <linux/cpu.h>
+#include <linux/powercap.h>
+#include <linux/suspend.h>
+#include <linux/intel_rapl.h>
+#include <linux/processor.h>
+
+#include <asm/iosf_mbi.h>
+#include <asm/cpu_device_id.h>
+#include <asm/intel-family.h>
+
+/* Local defines */
+#define MSR_PLATFORM_POWER_LIMIT	0x0000065C
+
+/* private data for RAPL MSR Interface */
+static struct rapl_if_priv rapl_msr_priv = {
+	.reg_unit = MSR_RAPL_POWER_UNIT,
+	.regs[RAPL_DOMAIN_PACKAGE] = {
+		MSR_PKG_POWER_LIMIT, MSR_PKG_ENERGY_STATUS, MSR_PKG_PERF_STATUS, 0, MSR_PKG_POWER_INFO },
+	.regs[RAPL_DOMAIN_PP0] = {
+		MSR_PP0_POWER_LIMIT, MSR_PP0_ENERGY_STATUS, 0, MSR_PP0_POLICY, 0 },
+	.regs[RAPL_DOMAIN_PP1] = {
+		MSR_PP1_POWER_LIMIT, MSR_PP1_ENERGY_STATUS, 0, MSR_PP1_POLICY, 0 },
+	.regs[RAPL_DOMAIN_DRAM] = {
+		MSR_DRAM_POWER_LIMIT, MSR_DRAM_ENERGY_STATUS, MSR_DRAM_PERF_STATUS, 0, MSR_DRAM_POWER_INFO },
+	.regs[RAPL_DOMAIN_PLATFORM] = {
+		MSR_PLATFORM_POWER_LIMIT, MSR_PLATFORM_ENERGY_STATUS, 0, 0, 0},
+};
+
+/* Handles CPU hotplug on multi-socket systems.
+ * If a CPU goes online as the first CPU of the physical package
+ * we add the RAPL package to the system. Similarly, when the last
+ * CPU of the package is removed, we remove the RAPL package and its
+ * associated domains. Cooling devices are handled accordingly at
+ * per-domain level.
+ */
+static int rapl_cpu_online(unsigned int cpu)
+{
+	struct rapl_package *rp;
+
+	rp = rapl_find_package_domain(cpu, &rapl_msr_priv);
+	if (!rp) {
+		rp = rapl_add_package(cpu, &rapl_msr_priv);
+		if (IS_ERR(rp))
+			return PTR_ERR(rp);
+	}
+	cpumask_set_cpu(cpu, &rp->cpumask);
+	return 0;
+}
+
+static int rapl_cpu_down_prep(unsigned int cpu)
+{
+	struct rapl_package *rp;
+	int lead_cpu;
+
+	rp = rapl_find_package_domain(cpu, &rapl_msr_priv);
+	if (!rp)
+		return 0;
+
+	cpumask_clear_cpu(cpu, &rp->cpumask);
+	lead_cpu = cpumask_first(&rp->cpumask);
+	if (lead_cpu >= nr_cpu_ids)
+		rapl_remove_package(rp);
+	else if (rp->lead_cpu == cpu)
+		rp->lead_cpu = lead_cpu;
+	return 0;
+}
+
+static int rapl_msr_read_raw(int cpu, struct reg_action *ra)
+{
+	if (rdmsrl_safe_on_cpu(cpu, ra->reg, &ra->value)) {
+		pr_debug("failed to read msr 0x%x on cpu %d\n", ra->reg, cpu);
+		return -EIO;
+	}
+	ra->value &= ra->mask;
+	return 0;
+}
+
+static void rapl_msr_update_func(void *info)
+{
+	struct reg_action *ra = info;
+	u64 val;
+
+	ra->err = rdmsrl_safe(ra->reg, &val);
+	if (ra->err)
+		return;
+
+	val &= ~ra->mask;
+	val |= ra->value;
+
+	ra->err = wrmsrl_safe(ra->reg, val);
+}
+
+static int rapl_msr_write_raw(int cpu, struct reg_action *ra)
+{
+	int ret;
+
+	ret = smp_call_function_single(cpu, rapl_msr_update_func, ra, 1);
+	if (WARN_ON_ONCE(ret))
+		return ret;
+
+	return ra->err;
+}
+
+static int __init rapl_msr_init(void)
+{
+	int ret;
+
+	rapl_msr_priv.read_raw = rapl_msr_read_raw;
+	rapl_msr_priv.write_raw = rapl_msr_write_raw;
+
+	rapl_msr_priv.control_type = powercap_register_control_type(NULL, "intel-rapl", NULL);
+	if (IS_ERR(rapl_msr_priv.control_type)) {
+		pr_debug("failed to register powercap control_type.\n");
+		return PTR_ERR(rapl_msr_priv.control_type);
+	}
+
+	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powercap/rapl:online",
+				rapl_cpu_online, rapl_cpu_down_prep);
+	if (ret < 0)
+		goto out;
+	rapl_msr_priv.pcap_rapl_online = ret;
+
+	/* Don't bail out if PSys is not supported */
+	rapl_add_platform_domain(&rapl_msr_priv);
+
+	return 0;
+
+out:
+	if (ret)
+		powercap_unregister_control_type(rapl_msr_priv.control_type);
+	return ret;
+}
+
+static void __exit rapl_msr_exit(void)
+{
+	cpuhp_remove_state(rapl_msr_priv.pcap_rapl_online);
+	rapl_remove_platform_domain(&rapl_msr_priv);
+	powercap_unregister_control_type(rapl_msr_priv.control_type);
+}
+
+module_init(rapl_msr_init);
+module_exit(rapl_msr_exit);
+
+MODULE_DESCRIPTION("Driver for Intel RAPL (Running Average Power Limit) control via MSR interface");
+MODULE_AUTHOR("Zhang Rui <rui.zhang@intel.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/intel_rapl.h b/include/linux/intel_rapl.h
index ff215d6..9579f45 100644
--- a/include/linux/intel_rapl.h
+++ b/include/linux/intel_rapl.h
@@ -142,4 +142,11 @@ struct rapl_package {
 	struct rapl_if_priv *priv;
 };
 
+struct rapl_package *rapl_find_package_domain(int cpu, struct rapl_if_priv *priv);
+struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv);
+void rapl_remove_package(struct rapl_package *rp);
+
+int rapl_add_platform_domain(struct rapl_if_priv *priv);
+void rapl_remove_platform_domain(struct rapl_if_priv *priv);
+
 #endif /* __INTEL_RAPL_H__ */
-- 
2.7.4


^ permalink raw reply related

* [PATCH V2 10/13] intel_rapl: support 64 bit register
From: Zhang Rui @ 2019-07-04 16:34 UTC (permalink / raw)
  To: rjw; +Cc: linux-pm, srinivas.pandruvada, rui.zhang
In-Reply-To: <1562258085-3165-1-git-send-email-rui.zhang@intel.com>

RAPL MMIO interface uses 64 bit registers, thus force use 64 bit register
for all the RAPL code.

Reviewed-and-tested-by: Pandruvada, Srinivas <srinivas.pandruvada@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/powercap/intel_rapl_common.c |  6 +++---
 drivers/powercap/intel_rapl_msr.c    | 11 +++++++----
 include/linux/intel_rapl.h           |  8 ++++----
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c
index 323ed41..d648411 100644
--- a/drivers/powercap/intel_rapl_common.c
+++ b/drivers/powercap/intel_rapl_common.c
@@ -689,7 +689,7 @@ static int rapl_read_data_raw(struct rapl_domain *rd,
 	ra.mask = rp->mask;
 
 	if (rd->rp->priv->read_raw(cpu, &ra)) {
-		pr_debug("failed to read reg 0x%x on cpu %d\n", ra.reg, cpu);
+		pr_debug("failed to read reg 0x%llx on cpu %d\n", ra.reg, cpu);
 		return -EIO;
 	}
 
@@ -749,7 +749,7 @@ static int rapl_check_unit_core(struct rapl_package *rp, int cpu)
 	ra.reg = rp->priv->reg_unit;
 	ra.mask = ~0;
 	if (rp->priv->read_raw(cpu, &ra)) {
-		pr_err("Failed to read power unit REG 0x%x on CPU %d, exit.\n",
+		pr_err("Failed to read power unit REG 0x%llx on CPU %d, exit.\n",
 		       rp->priv->reg_unit, cpu);
 		return -ENODEV;
 	}
@@ -777,7 +777,7 @@ static int rapl_check_unit_atom(struct rapl_package *rp, int cpu)
 	ra.reg = rp->priv->reg_unit;
 	ra.mask = ~0;
 	if (rp->priv->read_raw(cpu, &ra)) {
-		pr_err("Failed to read power unit REG 0x%x on CPU %d, exit.\n",
+		pr_err("Failed to read power unit REG 0x%llx on CPU %d, exit.\n",
 		       rp->priv->reg_unit, cpu);
 		return -ENODEV;
 	}
diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c
index 8964522..6cd8a8f 100644
--- a/drivers/powercap/intel_rapl_msr.c
+++ b/drivers/powercap/intel_rapl_msr.c
@@ -84,8 +84,10 @@ static int rapl_cpu_down_prep(unsigned int cpu)
 
 static int rapl_msr_read_raw(int cpu, struct reg_action *ra)
 {
-	if (rdmsrl_safe_on_cpu(cpu, ra->reg, &ra->value)) {
-		pr_debug("failed to read msr 0x%x on cpu %d\n", ra->reg, cpu);
+	u32 msr = (u32)ra->reg;
+
+	if (rdmsrl_safe_on_cpu(cpu, msr, &ra->value)) {
+		pr_debug("failed to read msr 0x%x on cpu %d\n", msr, cpu);
 		return -EIO;
 	}
 	ra->value &= ra->mask;
@@ -95,16 +97,17 @@ static int rapl_msr_read_raw(int cpu, struct reg_action *ra)
 static void rapl_msr_update_func(void *info)
 {
 	struct reg_action *ra = info;
+	u32 msr = (u32)ra->reg;
 	u64 val;
 
-	ra->err = rdmsrl_safe(ra->reg, &val);
+	ra->err = rdmsrl_safe(msr, &val);
 	if (ra->err)
 		return;
 
 	val &= ~ra->mask;
 	val |= ra->value;
 
-	ra->err = wrmsrl_safe(ra->reg, val);
+	ra->err = wrmsrl_safe(msr, val);
 }
 
 static int rapl_msr_write_raw(int cpu, struct reg_action *ra)
diff --git a/include/linux/intel_rapl.h b/include/linux/intel_rapl.h
index 9579f45..649e199 100644
--- a/include/linux/intel_rapl.h
+++ b/include/linux/intel_rapl.h
@@ -78,7 +78,7 @@ struct rapl_package;
 struct rapl_domain {
 	const char *name;
 	enum rapl_domain_type id;
-	int regs[RAPL_DOMAIN_REG_MAX];
+	u64 regs[RAPL_DOMAIN_REG_MAX];
 	struct powercap_zone power_zone;
 	struct rapl_domain_data rdd;
 	struct rapl_power_limit rpl[NR_POWER_LIMITS];
@@ -89,7 +89,7 @@ struct rapl_domain {
 };
 
 struct reg_action {
-	u32 reg;
+	u64 reg;
 	u64 mask;
 	u64 value;
 	int err;
@@ -113,8 +113,8 @@ struct rapl_if_priv {
 	struct powercap_control_type *control_type;
 	struct rapl_domain *platform_rapl_domain;
 	enum cpuhp_state pcap_rapl_online;
-	u32 reg_unit;
-	u32 regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX];
+	u64 reg_unit;
+	u64 regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX];
 	int (*read_raw)(int cpu, struct reg_action *ra);
 	int (*write_raw)(int cpu, struct reg_action *ra);
 };
-- 
2.7.4


^ permalink raw reply related

* [PATCH V2 07/13] intel_rapl: cleanup some functions
From: Zhang Rui @ 2019-07-04 16:34 UTC (permalink / raw)
  To: rjw; +Cc: linux-pm, srinivas.pandruvada, rui.zhang
In-Reply-To: <1562258085-3165-1-git-send-email-rui.zhang@intel.com>

Previously, there are three functions:
rapl_register_psys(), which registers platform rapl domain.
rapl_register_powercap(), which registers powercap control type.
rapl_unregsiter_powercap(), which unregisters platform rapl domain and
powercap control type.

This is confusing as the function name does not describe what it does
clearly.

With this patch, the three functions are removed, and two new functions
rapl_register_platform_domain()/rapl_unregister_platform_domain() are
introduced instead, and they do exactly what their function name describes.

Plus, as part of the common code, hardcoded MSR accesses in these functions
are converted to follow the abstracted register access.

Reviewed-and-tested-by: Pandruvada, Srinivas <srinivas.pandruvada@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/powercap/intel_rapl.c | 62 +++++++++++++++++++++----------------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c
index d3b9d1c..7a97d33 100644
--- a/drivers/powercap/intel_rapl.c
+++ b/drivers/powercap/intel_rapl.c
@@ -1052,16 +1052,6 @@ static void rapl_update_domain_data(struct rapl_package *rp)
 
 }
 
-static void rapl_unregister_powercap(void)
-{
-	if (&rapl_msr_priv.platform_rapl_domain) {
-		powercap_unregister_zone(rapl_msr_priv.control_type,
-					 &rapl_msr_priv.platform_rapl_domain->power_zone);
-		kfree(rapl_msr_priv.platform_rapl_domain);
-	}
-	powercap_unregister_control_type(rapl_msr_priv.control_type);
-}
-
 static int rapl_package_register_powercap(struct rapl_package *rp)
 {
 	struct rapl_domain *rd;
@@ -1131,16 +1121,23 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
 	return ret;
 }
 
-static int __init rapl_register_psys(void)
+static int __init rapl_add_platform_domain(struct rapl_if_priv *priv)
 {
 	struct rapl_domain *rd;
 	struct powercap_zone *power_zone;
-	u64 val;
+	struct reg_action ra;
+	int ret;
 
-	if (rdmsrl_safe_on_cpu(0, rapl_msr_priv.regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_STATUS], &val) || !val)
+	ra.reg = priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_STATUS];
+	ra.mask = ~0;
+	ret = priv->read_raw(0, &ra);
+	if (ret || !ra.value)
 		return -ENODEV;
 
-	if (rdmsrl_safe_on_cpu(0, rapl_msr_priv.regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_LIMIT], &val) || !val)
+	ra.reg = priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_LIMIT];
+	ra.mask = ~0;
+	ret = priv->read_raw(0, &ra);
+	if (ret || !ra.value)
 		return -ENODEV;
 
 	rd = kzalloc(sizeof(*rd), GFP_KERNEL);
@@ -1149,15 +1146,15 @@ static int __init rapl_register_psys(void)
 
 	rd->name = rapl_domain_names[RAPL_DOMAIN_PLATFORM];
 	rd->id = RAPL_DOMAIN_PLATFORM;
-	rd->regs[RAPL_DOMAIN_REG_LIMIT] = rapl_msr_priv.regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_LIMIT];
-	rd->regs[RAPL_DOMAIN_REG_STATUS] = rapl_msr_priv.regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_STATUS];
+	rd->regs[RAPL_DOMAIN_REG_LIMIT] = priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_LIMIT];
+	rd->regs[RAPL_DOMAIN_REG_STATUS] = priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_STATUS];
 	rd->rpl[0].prim_id = PL1_ENABLE;
 	rd->rpl[0].name = pl1_name;
 	rd->rpl[1].prim_id = PL2_ENABLE;
 	rd->rpl[1].name = pl2_name;
-	rd->rp = rapl_find_package_domain(0, &rapl_msr_priv);
+	rd->rp = rapl_find_package_domain(0, priv);
 
-	power_zone = powercap_register_zone(&rd->power_zone, rapl_msr_priv.control_type,
+	power_zone = powercap_register_zone(&rd->power_zone, priv->control_type,
 					    "psys", NULL,
 					    &zone_ops[RAPL_DOMAIN_PLATFORM],
 					    2, &constraint_ops);
@@ -1167,19 +1164,18 @@ static int __init rapl_register_psys(void)
 		return PTR_ERR(power_zone);
 	}
 
-	rapl_msr_priv.platform_rapl_domain = rd;
+	priv->platform_rapl_domain = rd;
 
 	return 0;
 }
 
-static int __init rapl_register_powercap(void)
+static void rapl_remove_platform_domain(struct rapl_if_priv *priv)
 {
-	rapl_msr_priv.control_type = powercap_register_control_type(NULL, "intel-rapl", NULL);
-	if (IS_ERR(rapl_msr_priv.control_type)) {
-		pr_debug("failed to register powercap control_type.\n");
-		return PTR_ERR(rapl_msr_priv.control_type);
+	if (priv->platform_rapl_domain) {
+		powercap_unregister_zone(priv->control_type,
+			&priv->platform_rapl_domain->power_zone);
+		kfree(priv->platform_rapl_domain);
 	}
-	return 0;
 }
 
 static int rapl_check_domain(int cpu, int domain, struct rapl_package *rp)
@@ -1526,9 +1522,12 @@ static int __init rapl_init(void)
 
 	rapl_msr_priv.read_raw = rapl_msr_read_raw;
 	rapl_msr_priv.write_raw = rapl_msr_write_raw;
-	ret = rapl_register_powercap();
-	if (ret)
-		return ret;
+
+	rapl_msr_priv.control_type = powercap_register_control_type(NULL, "intel-rapl", NULL);
+	if (IS_ERR(rapl_msr_priv.control_type)) {
+		pr_debug("failed to register powercap control_type.\n");
+		return PTR_ERR(rapl_msr_priv.control_type);
+	}
 
 	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powercap/rapl:online",
 				rapl_cpu_online, rapl_cpu_down_prep);
@@ -1537,7 +1536,7 @@ static int __init rapl_init(void)
 	rapl_msr_priv.pcap_rapl_online = ret;
 
 	/* Don't bail out if PSys is not supported */
-	rapl_register_psys();
+	rapl_add_platform_domain(&rapl_msr_priv);
 
 	ret = register_pm_notifier(&rapl_pm_notifier);
 	if (ret)
@@ -1549,7 +1548,7 @@ static int __init rapl_init(void)
 	cpuhp_remove_state(rapl_msr_priv.pcap_rapl_online);
 
 err_unreg:
-	rapl_unregister_powercap();
+	powercap_unregister_control_type(rapl_msr_priv.control_type);
 	return ret;
 }
 
@@ -1557,7 +1556,8 @@ static void __exit rapl_exit(void)
 {
 	unregister_pm_notifier(&rapl_pm_notifier);
 	cpuhp_remove_state(rapl_msr_priv.pcap_rapl_online);
-	rapl_unregister_powercap();
+	rapl_remove_platform_domain(&rapl_msr_priv);
+	powercap_unregister_control_type(rapl_msr_priv.control_type);
 }
 
 module_init(rapl_init);
-- 
2.7.4


^ permalink raw reply related

* [PATCH V2 08/13] intel_rapl: cleanup hardcoded MSR access
From: Zhang Rui @ 2019-07-04 16:34 UTC (permalink / raw)
  To: rjw; +Cc: linux-pm, srinivas.pandruvada, rui.zhang
In-Reply-To: <1562258085-3165-1-git-send-email-rui.zhang@intel.com>

There are still some places in the common code that have hardcoded
MSR access, convert them to follow the abstracted register access.

Reviewed-and-tested-by: Pandruvada, Srinivas <srinivas.pandruvada@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/powercap/intel_rapl.c | 38 ++++++++++++++++++++++----------------
 1 file changed, 22 insertions(+), 16 deletions(-)

diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c
index 7a97d33..aa54c06 100644
--- a/drivers/powercap/intel_rapl.c
+++ b/drivers/powercap/intel_rapl.c
@@ -767,22 +767,24 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
  */
 static int rapl_check_unit_core(struct rapl_package *rp, int cpu)
 {
-	u64 msr_val;
+	struct reg_action ra;
 	u32 value;
 
-	if (rdmsrl_safe_on_cpu(cpu, rp->priv->reg_unit, &msr_val)) {
-		pr_err("Failed to read power unit MSR 0x%x on CPU %d, exit.\n",
+	ra.reg = rp->priv->reg_unit;
+	ra.mask = ~0;
+	if (rp->priv->read_raw(cpu, &ra)) {
+		pr_err("Failed to read power unit REG 0x%x on CPU %d, exit.\n",
 			rp->priv->reg_unit, cpu);
 		return -ENODEV;
 	}
 
-	value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
+	value = (ra.value & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
 	rp->energy_unit = ENERGY_UNIT_SCALE * 1000000 / (1 << value);
 
-	value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
+	value = (ra.value & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
 	rp->power_unit = 1000000 / (1 << value);
 
-	value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
+	value = (ra.value & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
 	rp->time_unit = 1000000 / (1 << value);
 
 	pr_debug("Core CPU %s energy=%dpJ, time=%dus, power=%duW\n",
@@ -793,21 +795,24 @@ static int rapl_check_unit_core(struct rapl_package *rp, int cpu)
 
 static int rapl_check_unit_atom(struct rapl_package *rp, int cpu)
 {
-	u64 msr_val;
+	struct reg_action ra;
 	u32 value;
 
-	if (rdmsrl_safe_on_cpu(cpu, rp->priv->reg_unit, &msr_val)) {
-		pr_err("Failed to read power unit MSR 0x%x on CPU %d, exit.\n",
+	ra.reg = rp->priv->reg_unit;
+	ra.mask = ~0;
+	if (rp->priv->read_raw(cpu, &ra)) {
+		pr_err("Failed to read power unit REG 0x%x on CPU %d, exit.\n",
 			rp->priv->reg_unit, cpu);
 		return -ENODEV;
 	}
-	value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
+
+	value = (ra.value & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
 	rp->energy_unit = ENERGY_UNIT_SCALE * 1 << value;
 
-	value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
+	value = (ra.value & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
 	rp->power_unit = (1 << value) * 1000;
 
-	value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
+	value = (ra.value & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
 	rp->time_unit = 1000000 / (1 << value);
 
 	pr_debug("Atom %s energy=%dpJ, time=%dus, power=%duW\n",
@@ -1180,15 +1185,14 @@ static void rapl_remove_platform_domain(struct rapl_if_priv *priv)
 
 static int rapl_check_domain(int cpu, int domain, struct rapl_package *rp)
 {
-	u32 reg;
-	u64 val = 0;
+	struct reg_action ra;
 
 	switch (domain) {
 	case RAPL_DOMAIN_PACKAGE:
 	case RAPL_DOMAIN_PP0:
 	case RAPL_DOMAIN_PP1:
 	case RAPL_DOMAIN_DRAM:
-		reg = rp->priv->regs[domain][RAPL_DOMAIN_REG_STATUS];
+		ra.reg = rp->priv->regs[domain][RAPL_DOMAIN_REG_STATUS];
 		break;
 	case RAPL_DOMAIN_PLATFORM:
 		/* PSYS(PLATFORM) is not a CPU domain, so avoid printng error */
@@ -1200,7 +1204,9 @@ static int rapl_check_domain(int cpu, int domain, struct rapl_package *rp)
 	/* make sure domain counters are available and contains non-zero
 	 * values, otherwise skip it.
 	 */
-	if (rdmsrl_safe_on_cpu(cpu, reg, &val) || !val)
+
+	ra.mask = ~0;
+	if (rp->priv->read_raw(cpu, &ra) || !ra.value)
 		return -ENODEV;
 
 	return 0;
-- 
2.7.4


^ permalink raw reply related

* [PATCH V2 06/13] intel_rapl: abstract register access operations
From: Zhang Rui @ 2019-07-04 16:34 UTC (permalink / raw)
  To: rjw; +Cc: linux-pm, srinivas.pandruvada, rui.zhang
In-Reply-To: <1562258085-3165-1-git-send-email-rui.zhang@intel.com>

MSR and MMIO RAPL interfaces have different ways to access the registers,
thus in order to abstract the register access operations, two callbacks,
.read_raw()/.write_raw() are introduced, and they should be implemented by
MSR RAPL and MMIO RAPL interface driver respectly.

This patch implements them for the MSR I/F only.

Reviewed-and-tested-by: Pandruvada, Srinivas <srinivas.pandruvada@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/powercap/intel_rapl.c | 110 ++++++++++++++++++++++--------------------
 include/linux/intel_rapl.h    |  13 +++++
 2 files changed, 70 insertions(+), 53 deletions(-)

diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c
index 9f22aed..d3b9d1c 100644
--- a/drivers/powercap/intel_rapl.c
+++ b/drivers/powercap/intel_rapl.c
@@ -93,13 +93,6 @@ static struct rapl_if_priv rapl_msr_priv = {
 /* per domain data, some are optional */
 #define NR_RAW_PRIMITIVES (NR_RAPL_PRIMITIVES - 2)
 
-struct msrl_action {
-	u32 msr_no;
-	u64 clear_mask;
-	u64 set_mask;
-	int err;
-};
-
 #define	DOMAIN_STATE_INACTIVE           BIT(0)
 #define	DOMAIN_STATE_POWER_LIMIT_SET    BIT(1)
 #define DOMAIN_STATE_BIOS_LOCKED        BIT(2)
@@ -692,16 +685,16 @@ static int rapl_read_data_raw(struct rapl_domain *rd,
 			enum rapl_primitives prim,
 			bool xlate, u64 *data)
 {
-	u64 value, final;
-	u32 msr;
+	u64 value;
 	struct rapl_primitive_info *rp = &rpi[prim];
+	struct reg_action ra;
 	int cpu;
 
 	if (!rp->name || rp->flag & RAPL_PRIMITIVE_DUMMY)
 		return -EINVAL;
 
-	msr = rd->regs[rp->id];
-	if (!msr)
+	ra.reg = rd->regs[rp->id];
+	if (!ra.reg)
 		return -EINVAL;
 
 	cpu = rd->rp->lead_cpu;
@@ -717,47 +710,23 @@ static int rapl_read_data_raw(struct rapl_domain *rd,
 		return 0;
 	}
 
-	if (rdmsrl_safe_on_cpu(cpu, msr, &value)) {
-		pr_debug("failed to read msr 0x%x on cpu %d\n", msr, cpu);
+	ra.mask = rp->mask;
+
+	if (rd->rp->priv->read_raw(cpu, &ra)) {
+		pr_debug("failed to read reg 0x%x on cpu %d\n", ra.reg, cpu);
 		return -EIO;
 	}
 
-	final = value & rp->mask;
-	final = final >> rp->shift;
+	value = ra.value >> rp->shift;
+
 	if (xlate)
-		*data = rapl_unit_xlate(rd, rp->unit, final, 0);
+		*data = rapl_unit_xlate(rd, rp->unit, value, 0);
 	else
-		*data = final;
+		*data = value;
 
 	return 0;
 }
 
-
-static int msrl_update_safe(u32 msr_no, u64 clear_mask, u64 set_mask)
-{
-	int err;
-	u64 val;
-
-	err = rdmsrl_safe(msr_no, &val);
-	if (err)
-		goto out;
-
-	val &= ~clear_mask;
-	val |= set_mask;
-
-	err = wrmsrl_safe(msr_no, val);
-
-out:
-	return err;
-}
-
-static void msrl_update_func(void *info)
-{
-	struct msrl_action *ma = info;
-
-	ma->err = msrl_update_safe(ma->msr_no, ma->clear_mask, ma->set_mask);
-}
-
 /* Similar use of primitive info in the read counterpart */
 static int rapl_write_data_raw(struct rapl_domain *rd,
 			enum rapl_primitives prim,
@@ -766,7 +735,7 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
 	struct rapl_primitive_info *rp = &rpi[prim];
 	int cpu;
 	u64 bits;
-	struct msrl_action ma;
+	struct reg_action ra;
 	int ret;
 
 	cpu = rd->rp->lead_cpu;
@@ -774,17 +743,13 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
 	bits <<= rp->shift;
 	bits &= rp->mask;
 
-	memset(&ma, 0, sizeof(ma));
+	memset(&ra, 0, sizeof(ra));
 
-	ma.msr_no = rd->regs[rp->id];
-	ma.clear_mask = rp->mask;
-	ma.set_mask = bits;
+	ra.reg = rd->regs[rp->id];
+	ra.mask = rp->mask;
+	ra.value = bits;
 
-	ret = smp_call_function_single(cpu, msrl_update_func, &ma, 1);
-	if (ret)
-		WARN_ON_ONCE(ret);
-	else
-		ret = ma.err;
+	ret = rd->rp->priv->write_raw(cpu, &ra);
 
 	return ret;
 }
@@ -1507,6 +1472,43 @@ static struct notifier_block rapl_pm_notifier = {
 	.notifier_call = rapl_pm_callback,
 };
 
+static int rapl_msr_read_raw(int cpu, struct reg_action *ra)
+{
+	if (rdmsrl_safe_on_cpu(cpu, ra->reg, &ra->value)) {
+		pr_debug("failed to read msr 0x%x on cpu %d\n", ra->reg, cpu);
+		return -EIO;
+	}
+	ra->value &= ra->mask;
+	return 0;
+}
+
+static void rapl_msr_update_func(void *info)
+{
+	struct reg_action *ra = info;
+	u64 val;
+
+	ra->err = rdmsrl_safe(ra->reg, &val);
+	if (ra->err)
+		return;
+
+	val &= ~ra->mask;
+	val |= ra->value;
+
+	ra->err = wrmsrl_safe(ra->reg, val);
+}
+
+
+static int rapl_msr_write_raw(int cpu, struct reg_action *ra)
+{
+	int ret;
+
+	ret = smp_call_function_single(cpu, rapl_msr_update_func, ra, 1);
+	if (WARN_ON_ONCE(ret))
+		return ret;
+
+	return ra->err;
+}
+
 static int __init rapl_init(void)
 {
 	const struct x86_cpu_id *id;
@@ -1522,6 +1524,8 @@ static int __init rapl_init(void)
 
 	rapl_defaults = (struct rapl_defaults *)id->driver_data;
 
+	rapl_msr_priv.read_raw = rapl_msr_read_raw;
+	rapl_msr_priv.write_raw = rapl_msr_write_raw;
 	ret = rapl_register_powercap();
 	if (ret)
 		return ret;
diff --git a/include/linux/intel_rapl.h b/include/linux/intel_rapl.h
index ec2c9e8..ff215d6 100644
--- a/include/linux/intel_rapl.h
+++ b/include/linux/intel_rapl.h
@@ -88,6 +88,13 @@ struct rapl_domain {
 	struct rapl_package *rp;
 };
 
+struct reg_action {
+	u32 reg;
+	u64 mask;
+	u64 value;
+	int err;
+};
+
 /**
  * struct rapl_if_priv: private data for different RAPL interfaces
  * @control_type:		Each RAPL interface must have its own powercap
@@ -97,6 +104,10 @@ struct rapl_domain {
  * @pcap_rapl_online:		CPU hotplug state for each RAPL interface.
  * @reg_unit:			Register for getting energy/power/time unit.
  * @regs:			Register sets for different RAPL Domains.
+ * @read_raw:			Callback for reading RAPL interface specific
+ *				registers.
+ * @write_raw:			Callback for writing RAPL interface specific
+ *				registers.
  */
 struct rapl_if_priv {
 	struct powercap_control_type *control_type;
@@ -104,6 +115,8 @@ struct rapl_if_priv {
 	enum cpuhp_state pcap_rapl_online;
 	u32 reg_unit;
 	u32 regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX];
+	int (*read_raw)(int cpu, struct reg_action *ra);
+	int (*write_raw)(int cpu, struct reg_action *ra);
 };
 
 /* maximum rapl package domain name: package-%d-die-%d */
-- 
2.7.4


^ permalink raw reply related

* [PATCH V2 03/13] intel_rapl: introduce intel_rapl.h
From: Zhang Rui @ 2019-07-04 16:34 UTC (permalink / raw)
  To: rjw; +Cc: linux-pm, srinivas.pandruvada, rui.zhang
In-Reply-To: <1562258085-3165-1-git-send-email-rui.zhang@intel.com>

Create a new header file for the common definitions that might be used
by different RAPL Interface.

Reviewed-and-tested-by: Pandruvada, Srinivas <srinivas.pandruvada@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 MAINTAINERS                   |   1 +
 drivers/powercap/intel_rapl.c | 101 +------------------------------------
 include/linux/intel_rapl.h    | 113 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+), 99 deletions(-)
 create mode 100644 include/linux/intel_rapl.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 57f496c..b51f2b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12601,6 +12601,7 @@ F:	drivers/base/power/
 F:	include/linux/pm.h
 F:	include/linux/pm_*
 F:	include/linux/powercap.h
+F:	include/linux/intel_rapl.h
 F:	drivers/powercap/
 F:	kernel/configs/nopm.config
 
diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c
index 9be9f20..adb35ec 100644
--- a/drivers/powercap/intel_rapl.c
+++ b/drivers/powercap/intel_rapl.c
@@ -18,8 +18,9 @@
 #include <linux/cpu.h>
 #include <linux/powercap.h>
 #include <linux/suspend.h>
-#include <asm/iosf_mbi.h>
+#include <linux/intel_rapl.h>
 
+#include <asm/iosf_mbi.h>
 #include <asm/processor.h>
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
@@ -74,59 +75,9 @@ enum unit_type {
 	TIME_UNIT,
 };
 
-enum rapl_domain_type {
-	RAPL_DOMAIN_PACKAGE, /* entire package/socket */
-	RAPL_DOMAIN_PP0, /* core power plane */
-	RAPL_DOMAIN_PP1, /* graphics uncore */
-	RAPL_DOMAIN_DRAM,/* DRAM control_type */
-	RAPL_DOMAIN_PLATFORM, /* PSys control_type */
-	RAPL_DOMAIN_MAX,
-};
-
-enum rapl_domain_reg_id {
-	RAPL_DOMAIN_REG_LIMIT,
-	RAPL_DOMAIN_REG_STATUS,
-	RAPL_DOMAIN_REG_PERF,
-	RAPL_DOMAIN_REG_POLICY,
-	RAPL_DOMAIN_REG_INFO,
-	RAPL_DOMAIN_REG_MAX,
-};
-
 /* per domain data, some are optional */
-enum rapl_primitives {
-	ENERGY_COUNTER,
-	POWER_LIMIT1,
-	POWER_LIMIT2,
-	FW_LOCK,
-
-	PL1_ENABLE,  /* power limit 1, aka long term */
-	PL1_CLAMP,   /* allow frequency to go below OS request */
-	PL2_ENABLE,  /* power limit 2, aka short term, instantaneous */
-	PL2_CLAMP,
-
-	TIME_WINDOW1, /* long term */
-	TIME_WINDOW2, /* short term */
-	THERMAL_SPEC_POWER,
-	MAX_POWER,
-
-	MIN_POWER,
-	MAX_TIME_WINDOW,
-	THROTTLED_TIME,
-	PRIORITY_LEVEL,
-
-	/* below are not raw primitive data */
-	AVERAGE_POWER,
-	NR_RAPL_PRIMITIVES,
-};
-
 #define NR_RAW_PRIMITIVES (NR_RAPL_PRIMITIVES - 2)
 
-/* Can be expanded to include events, etc.*/
-struct rapl_domain_data {
-	u64 primitives[NR_RAPL_PRIMITIVES];
-	unsigned long timestamp;
-};
-
 struct msrl_action {
 	u32 msr_no;
 	u64 clear_mask;
@@ -138,60 +89,12 @@ struct msrl_action {
 #define	DOMAIN_STATE_POWER_LIMIT_SET    BIT(1)
 #define DOMAIN_STATE_BIOS_LOCKED        BIT(2)
 
-#define NR_POWER_LIMITS (2)
-struct rapl_power_limit {
-	struct powercap_zone_constraint *constraint;
-	int prim_id; /* primitive ID used to enable */
-	struct rapl_domain *domain;
-	const char *name;
-	u64 last_power_limit;
-};
-
 static const char pl1_name[] = "long_term";
 static const char pl2_name[] = "short_term";
 
-struct rapl_package;
-struct rapl_domain {
-	const char *name;
-	enum rapl_domain_type id;
-	int regs[RAPL_DOMAIN_REG_MAX];
-	struct powercap_zone power_zone;
-	struct rapl_domain_data rdd;
-	struct rapl_power_limit rpl[NR_POWER_LIMITS];
-	u64 attr_map; /* track capabilities */
-	unsigned int state;
-	unsigned int domain_energy_unit;
-	struct rapl_package *rp;
-};
 #define power_zone_to_rapl_domain(_zone) \
 	container_of(_zone, struct rapl_domain, power_zone)
 
-/* maximum rapl package domain name: package-%d-die-%d */
-#define PACKAGE_DOMAIN_NAME_LENGTH 30
-
-
-/* Each rapl package contains multiple domains, these are the common
- * data across RAPL domains within a package.
- */
-struct rapl_package {
-	unsigned int id; /* logical die id, equals physical 1-die systems */
-	unsigned int nr_domains;
-	unsigned long domain_map; /* bit map of active domains */
-	unsigned int power_unit;
-	unsigned int energy_unit;
-	unsigned int time_unit;
-	struct rapl_domain *domains; /* array of domains, sized at runtime */
-	struct powercap_zone *power_zone; /* keep track of parent zone */
-	unsigned long power_limit_irq; /* keep track of package power limit
-					* notify interrupt enable status.
-					*/
-	struct list_head plist;
-	int lead_cpu; /* one active cpu per package for access */
-	/* Track active cpus */
-	struct cpumask cpumask;
-	char name[PACKAGE_DOMAIN_NAME_LENGTH];
-};
-
 struct rapl_defaults {
 	u8 floor_freq_reg_addr;
 	int (*check_unit)(struct rapl_package *rp, int cpu);
diff --git a/include/linux/intel_rapl.h b/include/linux/intel_rapl.h
new file mode 100644
index 0000000..9471603
--- /dev/null
+++ b/include/linux/intel_rapl.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *  Data types and headers for RAPL support
+ *
+ *  Copyright (C) 2019  Intel Corporation.
+ *
+ *  Author: Zhang Rui <rui.zhang@intel.com>
+ */
+
+#ifndef __INTEL_RAPL_H__
+#define __INTEL_RAPL_H__
+
+#include <linux/types.h>
+#include <linux/powercap.h>
+
+enum rapl_domain_type {
+	RAPL_DOMAIN_PACKAGE,	/* entire package/socket */
+	RAPL_DOMAIN_PP0,	/* core power plane */
+	RAPL_DOMAIN_PP1,	/* graphics uncore */
+	RAPL_DOMAIN_DRAM,	/* DRAM control_type */
+	RAPL_DOMAIN_PLATFORM,	/* PSys control_type */
+	RAPL_DOMAIN_MAX,
+};
+
+enum rapl_domain_reg_id {
+	RAPL_DOMAIN_REG_LIMIT,
+	RAPL_DOMAIN_REG_STATUS,
+	RAPL_DOMAIN_REG_PERF,
+	RAPL_DOMAIN_REG_POLICY,
+	RAPL_DOMAIN_REG_INFO,
+	RAPL_DOMAIN_REG_MAX,
+};
+
+struct rapl_package;
+
+enum rapl_primitives {
+	ENERGY_COUNTER,
+	POWER_LIMIT1,
+	POWER_LIMIT2,
+	FW_LOCK,
+
+	PL1_ENABLE,		/* power limit 1, aka long term */
+	PL1_CLAMP,		/* allow frequency to go below OS request */
+	PL2_ENABLE,		/* power limit 2, aka short term, instantaneous */
+	PL2_CLAMP,
+
+	TIME_WINDOW1,		/* long term */
+	TIME_WINDOW2,		/* short term */
+	THERMAL_SPEC_POWER,
+	MAX_POWER,
+
+	MIN_POWER,
+	MAX_TIME_WINDOW,
+	THROTTLED_TIME,
+	PRIORITY_LEVEL,
+
+	/* below are not raw primitive data */
+	AVERAGE_POWER,
+	NR_RAPL_PRIMITIVES,
+};
+
+struct rapl_domain_data {
+	u64 primitives[NR_RAPL_PRIMITIVES];
+	unsigned long timestamp;
+};
+
+#define NR_POWER_LIMITS (2)
+struct rapl_power_limit {
+	struct powercap_zone_constraint *constraint;
+	int prim_id;		/* primitive ID used to enable */
+	struct rapl_domain *domain;
+	const char *name;
+	u64 last_power_limit;
+};
+
+struct rapl_package;
+
+struct rapl_domain {
+	const char *name;
+	enum rapl_domain_type id;
+	int regs[RAPL_DOMAIN_REG_MAX];
+	struct powercap_zone power_zone;
+	struct rapl_domain_data rdd;
+	struct rapl_power_limit rpl[NR_POWER_LIMITS];
+	u64 attr_map;		/* track capabilities */
+	unsigned int state;
+	unsigned int domain_energy_unit;
+	struct rapl_package *rp;
+};
+
+/* maximum rapl package domain name: package-%d-die-%d */
+#define PACKAGE_DOMAIN_NAME_LENGTH 30
+
+struct rapl_package {
+	unsigned int id;	/* logical die id, equals physical 1-die systems */
+	unsigned int nr_domains;
+	unsigned long domain_map;	/* bit map of active domains */
+	unsigned int power_unit;
+	unsigned int energy_unit;
+	unsigned int time_unit;
+	struct rapl_domain *domains;	/* array of domains, sized at runtime */
+	struct powercap_zone *power_zone;	/* keep track of parent zone */
+	unsigned long power_limit_irq;	/* keep track of package power limit
+					 * notify interrupt enable status.
+					 */
+	struct list_head plist;
+	int lead_cpu;		/* one active cpu per package for access */
+	/* Track active cpus */
+	struct cpumask cpumask;
+	char name[PACKAGE_DOMAIN_NAME_LENGTH];
+};
+
+#endif /* __INTEL_RAPL_H__ */
-- 
2.7.4


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox