This is the 5.4.251 stable release

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmTCEMUACgkQONu9yGCS
 aT52vhAAr5fuA8n3nANC/iWrnV+tR7PS9+ncqxloumGgIPnFijlCpB7DBoK7KAPw
 cs83aMisxfvWkSPuQebqY2xO2dUX03DiySCNta0W81Iw2ndASLnA/OXYn+ZOXMbW
 xKYA37d5EmQ+JWIhh3+Gnxjb3Tui6vVEJAgqkC+4FD/sB60VwuGNIKirkYT58402
 NlYExg0Wcgye8Qc50JXH96Dy6opvX84qGnnmz3slfKk7Jykifqh3jm1bSIQrngWs
 mUb8cXOkQgMrAWz8IJ4FgHisA0X3B3SklaiEO0ClPWw4nwC9PtpnAxZRxIVf2LDC
 eXj0fsJcP6So2b2vDnmfn2V+1bM8jQFuyv6eqhxW6sz4uiQQuZ3GAqdw0UhhfUmL
 ExzlCWTzdy2ZP4oN440JvxnYDItCsK263G+6l+LH3owWEbwHYmUh2uZoiC31rIEk
 pzXpZYzpFpGweTGtKx0+mW90i8l0lyQojN4pJMUrHgjp7u+bQIY0BkFUTClMH59E
 TsArErG8YOUh3cb+JkiTuJfgpv/D1kW//p3t2uJEsZPUHjN9BDsn0rsMftLYZI1C
 IKXpi69yYjbSmYAz6gRzi7AmlxRxqM4BEdOOyqHMylyyK5K0EneXqpA1UMT+Fuel
 5KXXVWjPu+C0I5x4MLnbBckJQHVsKY/sUE94ba4OFsTMbCJeNZ8=
 =Vm2g
 -----END PGP SIGNATURE-----

Merge 5.4.251 into android11-5.4-lts

Changes in 5.4.251
	gfs2: Don't deref jdesc in evict
	x86/smp: Use dedicated cache-line for mwait_play_dead()
	video: imsttfb: check for ioremap() failures
	fbdev: imsttfb: Fix use after free bug in imsttfb_probe
	HID: wacom: Use ktime_t rather than int when dealing with timestamps
	drm/i915: Initialise outparam for error return from wait_for_register
	scripts/tags.sh: Resolve gtags empty index generation
	drm/amdgpu: Validate VM ioctl flags.
	bgmac: fix *initial* chip reset to support BCM5358
	x86/resctrl: Use is_closid_match() in more places
	x86/resctrl: Only show tasks' pid in current pid namespace
	md/raid10: check slab-out-of-bounds in md_bitmap_get_counter
	md/raid10: fix overflow of md/safe_mode_delay
	md/raid10: fix wrong setting of max_corr_read_errors
	md/raid10: fix null-ptr-deref of mreplace in raid10_sync_request
	md/raid10: fix io loss while replacement replace rdev
	irqchip/jcore-aic: Kill use of irq_create_strict_mappings()
	irqchip/jcore-aic: Fix missing allocation of IRQ descriptors
	tracing/timer: Add missing hrtimer modes to decode_hrtimer_mode().
	clocksource/drivers/cadence-ttc: Use ttc driver as platform driver
	clocksource/drivers/cadence-ttc: Fix memory leak in ttc_timer_probe
	PM: domains: fix integer overflow issues in genpd_parse_state()
	powercap: RAPL: Fix CONFIG_IOSF_MBI dependency
	ARM: 9303/1: kprobes: avoid missing-declaration warnings
	evm: Complete description of evm_inode_setattr()
	pstore/ram: Add check for kstrdup
	ima: Fix build warnings
	wifi: ath9k: fix AR9003 mac hardware hang check register offset calculation
	wifi: ath9k: avoid referencing uninit memory in ath9k_wmi_ctrl_rx
	samples/bpf: Fix buffer overflow in tcp_basertt
	spi: spi-geni-qcom: Correct CS_TOGGLE bit in SPI_TRANS_CFG
	wifi: mwifiex: Fix the size of a memory allocation in mwifiex_ret_802_11_scan()
	nfc: constify several pointers to u8, char and sk_buff
	nfc: llcp: fix possible use of uninitialized variable in nfc_llcp_send_connect()
	regulator: core: Fix more error checking for debugfs_create_dir()
	regulator: core: Streamline debugfs operations
	wifi: orinoco: Fix an error handling path in spectrum_cs_probe()
	wifi: orinoco: Fix an error handling path in orinoco_cs_probe()
	wifi: atmel: Fix an error handling path in atmel_probe()
	wl3501_cs: Fix a bunch of formatting issues related to function docs
	wl3501_cs: Remove unnecessary NULL check
	wl3501_cs: Fix misspelling and provide missing documentation
	net: create netdev->dev_addr assignment helpers
	wl3501_cs: use eth_hw_addr_set()
	wifi: wl3501_cs: Fix an error handling path in wl3501_probe()
	wifi: ray_cs: Utilize strnlen() in parse_addr()
	wifi: ray_cs: Drop useless status variable in parse_addr()
	wifi: ray_cs: Fix an error handling path in ray_probe()
	wifi: ath9k: don't allow to overwrite ENDPOINT0 attributes
	wifi: rsi: Do not set MMC_PM_KEEP_POWER in shutdown
	watchdog/perf: define dummy watchdog_update_hrtimer_threshold() on correct config
	watchdog/perf: more properly prevent false positives with turbo modes
	kexec: fix a memory leak in crash_shrink_memory()
	memstick r592: make memstick_debug_get_tpc_name() static
	wifi: ath9k: Fix possible stall on ath9k_txq_list_has_key()
	rtnetlink: extend RTEXT_FILTER_SKIP_STATS to IFLA_VF_INFO
	wifi: iwlwifi: pull from TXQs with softirqs disabled
	wifi: cfg80211: rewrite merging of inherited elements
	wifi: ath9k: convert msecs to jiffies where needed
	netlink: fix potential deadlock in netlink_set_err()
	netlink: do not hard code device address lenth in fdb dumps
	selftests: rtnetlink: remove netdevsim device after ipsec offload test
	gtp: Fix use-after-free in __gtp_encap_destroy().
	nfc: llcp: simplify llcp_sock_connect() error paths
	net: nfc: Fix use-after-free caused by nfc_llcp_find_local
	lib/ts_bm: reset initial match offset for every block of text
	netfilter: conntrack: dccp: copy entire header to stack buffer, not just basic one
	netfilter: nf_conntrack_sip: fix the ct_sip_parse_numerical_param() return value.
	ipvlan: Fix return value of ipvlan_queue_xmit()
	netlink: Add __sock_i_ino() for __netlink_diag_dump().
	radeon: avoid double free in ci_dpm_init()
	Input: drv260x - sleep between polling GO bit
	ARM: dts: BCM5301X: Drop "clock-names" from the SPI node
	Input: adxl34x - do not hardcode interrupt trigger type
	drm: sun4i_tcon: use devm_clk_get_enabled in `sun4i_tcon_init_clocks`
	RDMA/bnxt_re: Fix to remove an unnecessary log
	ARM: dts: gta04: Move model property out of pinctrl node
	arm64: dts: qcom: msm8916: correct camss unit address
	drm/panel: simple: fix active size for Ampire AM-480272H3TMQW-T01H
	ARM: ep93xx: fix missing-prototype warnings
	memory: brcmstb_dpfe: fix testing array offset after use
	ASoC: es8316: Increment max value for ALC Capture Target Volume control
	ASoC: es8316: Do not set rate constraints for unsupported MCLKs
	soc/fsl/qe: fix usb.c build errors
	IB/hfi1: Fix sdma.h tx->num_descs off-by-one errors
	arm64: dts: renesas: ulcb-kf: Remove flow control for SCIF1
	fbdev: omapfb: lcd_mipid: Fix an error handling path in mipid_spi_probe()
	drm/amdkfd: Fix potential deallocation of previously deallocated memory.
	drm/radeon: fix possible division-by-zero errors
	clk: tegra: tegra124-emc: Fix potential memory leak
	ALSA: ac97: Fix possible NULL dereference in snd_ac97_mixer
	clk: cdce925: check return value of kasprintf()
	clk: keystone: sci-clk: check return value of kasprintf()
	ASoC: imx-audmix: check return value of devm_kasprintf()
	scsi: qedf: Fix NULL dereference in error handling
	PCI/ASPM: Disable ASPM on MFD function removal to avoid use-after-free
	scsi: 3w-xxxx: Add error handling for initialization failure in tw_probe()
	PCI: pciehp: Cancel bringup sequence if card is not present
	PCI: ftpci100: Release the clock resources
	PCI: Add pci_clear_master() stub for non-CONFIG_PCI
	pinctrl: cherryview: Return correct value if pin in push-pull mode
	perf dwarf-aux: Fix off-by-one in die_get_varname()
	pinctrl: at91-pio4: check return value of devm_kasprintf()
	powerpc/mm/dax: Fix the condition when checking if altmap vmemap can cross-boundary
	hwrng: virtio - add an internal buffer
	hwrng: virtio - don't wait on cleanup
	hwrng: virtio - don't waste entropy
	hwrng: virtio - always add a pending request
	hwrng: virtio - Fix race on data_avail and actual data
	crypto: nx - fix build warnings when DEBUG_FS is not enabled
	modpost: fix section mismatch message for R_ARM_ABS32
	modpost: fix section mismatch message for R_ARM_{PC24,CALL,JUMP24}
	crypto: marvell/cesa - Fix type mismatch warning
	modpost: fix off by one in is_executable_section()
	ARC: define ASM_NL and __ALIGN(_STR) outside #ifdef __ASSEMBLY__ guard
	NFSv4.1: freeze the session table upon receiving NFS4ERR_BADSESSION
	hwrng: st - Fix W=1 unused variable warning
	hwrng: st - keep clock enabled while hwrng is registered
	USB: serial: option: add LARA-R6 01B PIDs
	usb: dwc3: gadget: Propagate core init errors to UDC during pullup
	block: fix signed int overflow in Amiga partition support
	block: change all __u32 annotations to __be32 in affs_hardblocks.h
	w1: fix loop in w1_fini()
	sh: j2: Use ioremap() to translate device tree address into kernel memory
	media: usb: Check az6007_read() return value
	media: videodev2.h: Fix struct v4l2_input tuner index comment
	media: usb: siano: Fix warning due to null work_func_t function pointer
	usb: dwc3: qcom: Fix potential memory leak
	extcon: Fix kernel doc of property fields to avoid warnings
	extcon: Fix kernel doc of property capability fields to avoid warnings
	usb: phy: phy-tahvo: fix memory leak in tahvo_usb_probe()
	usb: hide unused usbfs_notify_suspend/resume functions
	mfd: rt5033: Drop rt5033-battery sub-device
	KVM: s390: fix KVM_S390_GET_CMMA_BITS for GFNs in memslot holes
	usb: dwc3: qcom: Release the correct resources in dwc3_qcom_remove()
	mfd: intel-lpss: Add missing check for platform_get_resource
	serial: 8250_omap: Use force_suspend and resume for system suspend
	mfd: stmfx: Fix error path in stmfx_chip_init
	KVM: s390: vsie: fix the length of APCB bitmap
	mfd: stmpe: Only disable the regulators if they are enabled
	pwm: imx-tpm: force 'real_period' to be zero in suspend
	pwm: sysfs: Do not apply state to already disabled PWMs
	rtc: st-lpc: Release some resources in st_rtc_probe() in case of error
	sctp: fix potential deadlock on &net->sctp.addr_wq_lock
	Add MODULE_FIRMWARE() for FIRMWARE_TG357766.
	spi: bcm-qspi: return error if neither hif_mspi nor mspi is available
	mailbox: ti-msgmgr: Fill non-message tx data fields with 0x0
	f2fs: fix error path handling in truncate_dnode()
	powerpc: allow PPC_EARLY_DEBUG_CPM only when SERIAL_CPM=y
	net: bridge: keep ports without IFF_UNICAST_FLT in BR_PROMISC mode
	tcp: annotate data races in __tcp_oow_rate_limited()
	xsk: Improve documentation for AF_XDP
	xsk: Honor SO_BINDTODEVICE on bind
	net/sched: act_pedit: Add size check for TCA_PEDIT_PARMS_EX
	net: dsa: tag_sja1105: fix MAC DA patching from meta frames
	sh: dma: Fix DMA channel offset calculation
	i2c: xiic: Defer xiic_wakeup() and __xiic_start_xfer() in xiic_process()
	i2c: xiic: Don't try to handle more interrupt events after error
	ALSA: jack: Fix mutex call in snd_jack_report()
	NFSD: add encoding of op_recall flag for write delegation
	mmc: core: disable TRIM on Kingston EMMC04G-M627
	mmc: core: disable TRIM on Micron MTFC4GACAJCN-1M
	mmc: sdhci: fix DMA configure compatibility issue when 64bit DMA mode is used.
	bcache: Remove unnecessary NULL point check in node allocations
	integrity: Fix possible multiple allocation in integrity_inode_get()
	jffs2: reduce stack usage in jffs2_build_xattr_subsystem()
	fs: avoid empty option when generating legacy mount string
	ext4: Remove ext4 locking of moved directory
	Revert "f2fs: fix potential corruption when moving a directory"
	fs: Establish locking order for unrelated directories
	fs: Lock moved directories
	btrfs: fix race when deleting quota root from the dirty cow roots list
	ARM: orion5x: fix d2net gpio initialization
	fs: no need to check source
	fanotify: disallow mount/sb marks on kernel internal pseudo fs
	block: add overflow checks for Amiga partition support
	netfilter: nf_tables: fix nat hook table deletion
	netfilter: nftables: add helper function to set the base sequence number
	netfilter: add helper function to set up the nfnetlink header and use it
	netfilter: nf_tables: use net_generic infra for transaction data
	netfilter: nf_tables: add rescheduling points during loop detection walks
	netfilter: nf_tables: incorrect error path handling with NFT_MSG_NEWRULE
	netfilter: nf_tables: add NFT_TRANS_PREPARE_ERROR to deal with bound set/chain
	netfilter: nf_tables: reject unbound anonymous set before commit phase
	netfilter: nf_tables: unbind non-anonymous set if rule construction fails
	netfilter: nf_tables: fix scheduling-while-atomic splat
	netfilter: conntrack: Avoid nf_ct_helper_hash uses after free
	netfilter: nf_tables: prevent OOB access in nft_byteorder_eval
	tty: serial: fsl_lpuart: add earlycon for imx8ulp platform
	block/partition: fix signedness issue for Amiga partitions
	net: lan743x: Don't sleep in atomic context
	workqueue: clean up WORK_* constant types, clarify masking
	drm/panel: Initialise panel dev and funcs through drm_panel_init()
	drm/panel: Add and fill drm_panel type field
	drm/panel: simple: Add connector_type for innolux_at043tn24
	igc: Remove delay during TX ring configuration
	igc: set TP bit in 'supported' and 'advertising' fields of ethtool_link_ksettings
	scsi: qla2xxx: Fix error code in qla2x00_start_sp()
	net: mvneta: fix txq_map in case of txq_number==1
	net/sched: cls_fw: Fix improper refcount update leads to use-after-free
	ionic: improve irq numa locality
	ionic: clean irq affinity on queue deinit
	ionic: move irq request to qcq alloc
	ionic: ionic_intr_free parameter change
	ionic: remove WARN_ON to prevent panic_on_warn
	icmp6: Fix null-ptr-deref of ip6_null_entry->rt6i_idev in icmp6_dev().
	udp6: fix udp6_ehashfn() typo
	ntb: idt: Fix error handling in idt_pci_driver_init()
	NTB: amd: Fix error handling in amd_ntb_pci_driver_init()
	ntb: intel: Fix error handling in intel_ntb_pci_driver_init()
	NTB: ntb_transport: fix possible memory leak while device_register() fails
	NTB: ntb_tool: Add check for devm_kcalloc
	ipv6/addrconf: fix a potential refcount underflow for idev
	platform/x86: wmi: Replace UUID redefinitions by their originals
	platform/x86: wmi: Fix indentation in some cases
	platform/x86: wmi: remove unnecessary argument
	platform/x86: wmi: use guid_t and guid_equal()
	platform/x86: wmi: move variables
	platform/x86: wmi: Break possible infinite loop when parsing GUID
	erofs: avoid infinite loop in z_erofs_do_read_page() when reading beyond EOF
	wifi: airo: avoid uninitialized warning in airo_get_rate()
	cls_flower: Add extack support for src and dst port range options
	net/sched: flower: Ensure both minimum and maximum ports are specified
	net/sched: make psched_mtu() RTNL-less safe
	pinctrl: amd: Fix mistake in handling clearing pins at startup
	pinctrl: amd: Detect internal GPIO0 debounce handling
	pinctrl: amd: Only use special debounce behavior for GPIO 0
	tpm: tpm_vtpm_proxy: fix a race condition in /dev/vtpmx creation
	mtd: rawnand: meson: fix unaligned DMA buffers handling
	net: bcmgenet: Ensure MDIO unregistration has clocks enabled
	powerpc: Fail build if using recordmcount with binutils v2.37
	misc: fastrpc: Create fastrpc scalar with correct buffer count
	SUNRPC: Fix UAF in svc_tcp_listen_data_ready()
	erofs: fix compact 4B support for 16k block size
	ext4: fix wrong unit use in ext4_mb_clear_bb
	ext4: only update i_reserved_data_blocks on successful block allocation
	jfs: jfs_dmap: Validate db_l2nbperpage while mounting
	PCI/PM: Avoid putting EloPOS E2/S2/H2 PCIe Ports in D3cold
	PCI: Add function 1 DMA alias quirk for Marvell 88SE9235
	PCI: qcom: Disable write access to read only registers for IP v2.3.3
	PCI: rockchip: Assert PCI Configuration Enable bit after probe
	PCI: rockchip: Write PCI Device ID to correct register
	PCI: rockchip: Add poll and timeout to wait for PHY PLLs to be locked
	PCI: rockchip: Fix legacy IRQ generation for RK3399 PCIe endpoint core
	PCI: rockchip: Use u32 variable to access 32-bit registers
	PCI: rockchip: Set address alignment for endpoint mode
	misc: pci_endpoint_test: Free IRQs before removing the device
	misc: pci_endpoint_test: Re-init completion for every test
	md/raid0: add discard support for the 'original' layout
	fs: dlm: return positive pid value for F_GETLK
	drm/atomic: Allow vblank-enabled + self-refresh "disable"
	drm/rockchip: vop: Leave vblank enabled in self-refresh
	serial: atmel: don't enable IRQs prematurely
	firmware: stratix10-svc: Fix a potential resource leak in svc_create_memory_pool()
	hwrng: imx-rngc - fix the timeout for init and self check
	ceph: don't let check_caps skip sending responses for revoke msgs
	meson saradc: fix clock divider mask length
	Revert "8250: add support for ASIX devices with a FIFO bug"
	tty: serial: samsung_tty: Fix a memory leak in s3c24xx_serial_getclk() in case of error
	tty: serial: samsung_tty: Fix a memory leak in s3c24xx_serial_getclk() when iterating clk
	tracing/histograms: Add histograms to hist_vars if they have referenced variables
	ring-buffer: Fix deadloop issue on reading trace_pipe
	xtensa: ISS: fix call to split_if_spec
	tracing: Fix null pointer dereference in tracing_err_log_open()
	tracing/probes: Fix not to count error code to total length
	scsi: qla2xxx: Wait for io return on terminate rport
	scsi: qla2xxx: Fix potential NULL pointer dereference
	scsi: qla2xxx: Check valid rport returned by fc_bsg_to_rport()
	scsi: qla2xxx: Correct the index of array
	scsi: qla2xxx: Pointer may be dereferenced
	scsi: qla2xxx: Remove unused nvme_ls_waitq wait queue
	drm/atomic: Fix potential use-after-free in nonblocking commits
	perf probe: Add test for regression introduced by switch to die_get_decl_file()
	btrfs: fix warning when putting transaction with qgroups enabled after abort
	fuse: revalidate: don't invalidate if interrupted
	selftests: tc: set timeout to 15 minutes
	can: bcm: Fix UAF in bcm_proc_show()
	drm/client: Fix memory leak in drm_client_target_cloned
	drm/client: Fix memory leak in drm_client_modeset_probe
	ext4: correct inline offset when handling xattrs in inode body
	debugobjects: Recheck debug_objects_enabled before reporting
	nbd: Add the maximum limit of allocated index in nbd_dev_add
	md: fix data corruption for raid456 when reshape restart while grow up
	md/raid10: prevent soft lockup while flush writes
	posix-timers: Ensure timer ID search-loop limit is valid
	arm64: mm: fix VA-range sanity check
	sched/fair: Don't balance task to its current running CPU
	bpf: Address KCSAN report on bpf_lru_list
	devlink: report devlink_port_type_warn source device
	wifi: wext-core: Fix -Wstringop-overflow warning in ioctl_standard_iw_point()
	wifi: iwlwifi: mvm: avoid baid size integer overflow
	igb: Fix igb_down hung on surprise removal
	spi: bcm63xx: fix max prepend length
	fbdev: imxfb: warn about invalid left/right margin
	pinctrl: amd: Use amd_pinconf_set() for all config options
	net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()/cpsw_ale_set_field()
	iavf: Fix use-after-free in free_netdev
	net:ipv6: check return value of pskb_trim()
	Revert "tcp: avoid the lookup process failing to get sk in ehash table"
	fbdev: au1200fb: Fix missing IRQ check in au1200fb_drv_probe
	llc: Don't drop packet from non-root netns.
	netfilter: nf_tables: fix spurious set element insertion failure
	netfilter: nf_tables: can't schedule in nft_chain_validate
	tcp: annotate data-races around tp->tcp_tx_delay
	net: Replace the limit of TCP_LINGER2 with TCP_FIN_TIMEOUT_MAX
	tcp: annotate data-races around tp->linger2
	tcp: annotate data-races around rskq_defer_accept
	tcp: annotate data-races around tp->notsent_lowat
	tcp: annotate data-races around fastopenq.max_qlen
	tracing/histograms: Return an error if we fail to add histogram to hist_vars list
	Linux 5.4.251

Change-Id: I0b8e1ac44b19c6c2c4f5f055395b3cbf6aecbbee
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2023-08-03 10:56:28 +00:00
commit 34df0a4c54
333 changed files with 3006 additions and 1725 deletions

View File

@ -22,12 +22,11 @@ exclusive.
3) object removal. Locking rules: caller locks parent, finds victim, 3) object removal. Locking rules: caller locks parent, finds victim,
locks victim and calls the method. Locks are exclusive. locks victim and calls the method. Locks are exclusive.
4) rename() that is _not_ cross-directory. Locking rules: caller locks 4) rename() that is _not_ cross-directory. Locking rules: caller locks the
the parent and finds source and target. In case of exchange (with parent and finds source and target. We lock both (provided they exist). If we
RENAME_EXCHANGE in flags argument) lock both. In any case, need to lock two inodes of different type (dir vs non-dir), we lock directory
if the target already exists, lock it. If the source is a non-directory, first. If we need to lock two inodes of the same type, lock them in inode
lock it. If we need to lock both, lock them in inode pointer order. pointer order. Then call the method. All locks are exclusive.
Then call the method. All locks are exclusive.
NB: we might get away with locking the the source (and target in exchange NB: we might get away with locking the the source (and target in exchange
case) shared. case) shared.
@ -44,15 +43,17 @@ All locks are exclusive.
rules: rules:
* lock the filesystem * lock the filesystem
* lock parents in "ancestors first" order. * lock parents in "ancestors first" order. If one is not ancestor of
the other, lock them in inode pointer order.
* find source and target. * find source and target.
* if old parent is equal to or is a descendent of target * if old parent is equal to or is a descendent of target
fail with -ENOTEMPTY fail with -ENOTEMPTY
* if new parent is equal to or is a descendent of source * if new parent is equal to or is a descendent of source
fail with -ELOOP fail with -ELOOP
* If it's an exchange, lock both the source and the target. * Lock both the source and the target provided they exist. If we
* If the target exists, lock it. If the source is a non-directory, need to lock two inodes of different type (dir vs non-dir), we lock
lock it. If we need to lock both, do so in inode pointer order. the directory first. If we need to lock two inodes of the same type,
lock them in inode pointer order.
* call the method. * call the method.
All ->i_rwsem are taken exclusive. Again, we might get away with locking All ->i_rwsem are taken exclusive. Again, we might get away with locking
@ -66,8 +67,9 @@ If no directory is its own ancestor, the scheme above is deadlock-free.
Proof: Proof:
First of all, at any moment we have a partial ordering of the First of all, at any moment we have a linear ordering of the
objects - A < B iff A is an ancestor of B. objects - A < B iff (A is an ancestor of B) or (B is not an ancestor
of A and ptr(A) < ptr(B)).
That ordering can change. However, the following is true: That ordering can change. However, the following is true:

View File

@ -40,13 +40,13 @@ allocates memory for this UMEM using whatever means it feels is most
appropriate (malloc, mmap, huge pages, etc). This memory area is then appropriate (malloc, mmap, huge pages, etc). This memory area is then
registered with the kernel using the new setsockopt XDP_UMEM_REG. The registered with the kernel using the new setsockopt XDP_UMEM_REG. The
UMEM also has two rings: the FILL ring and the COMPLETION ring. The UMEM also has two rings: the FILL ring and the COMPLETION ring. The
fill ring is used by the application to send down addr for the kernel FILL ring is used by the application to send down addr for the kernel
to fill in with RX packet data. References to these frames will then to fill in with RX packet data. References to these frames will then
appear in the RX ring once each packet has been received. The appear in the RX ring once each packet has been received. The
completion ring, on the other hand, contains frame addr that the COMPLETION ring, on the other hand, contains frame addr that the
kernel has transmitted completely and can now be used again by user kernel has transmitted completely and can now be used again by user
space, for either TX or RX. Thus, the frame addrs appearing in the space, for either TX or RX. Thus, the frame addrs appearing in the
completion ring are addrs that were previously transmitted using the COMPLETION ring are addrs that were previously transmitted using the
TX ring. In summary, the RX and FILL rings are used for the RX path TX ring. In summary, the RX and FILL rings are used for the RX path
and the TX and COMPLETION rings are used for the TX path. and the TX and COMPLETION rings are used for the TX path.
@ -91,11 +91,16 @@ Concepts
======== ========
In order to use an AF_XDP socket, a number of associated objects need In order to use an AF_XDP socket, a number of associated objects need
to be setup. to be setup. These objects and their options are explained in the
following sections.
Jonathan Corbet has also written an excellent article on LWN, For an overview on how AF_XDP works, you can also take a look at the
"Accelerating networking with AF_XDP". It can be found at Linux Plumbers paper from 2018 on the subject:
https://lwn.net/Articles/750845/. http://vger.kernel.org/lpc_net2018_talks/lpc18_paper_af_xdp_perf-v2.pdf. Do
NOT consult the paper from 2017 on "AF_PACKET v4", the first attempt
at AF_XDP. Nearly everything changed since then. Jonathan Corbet has
also written an excellent article on LWN, "Accelerating networking
with AF_XDP". It can be found at https://lwn.net/Articles/750845/.
UMEM UMEM
---- ----
@ -113,22 +118,22 @@ the next socket B can do this by setting the XDP_SHARED_UMEM flag in
struct sockaddr_xdp member sxdp_flags, and passing the file descriptor struct sockaddr_xdp member sxdp_flags, and passing the file descriptor
of A to struct sockaddr_xdp member sxdp_shared_umem_fd. of A to struct sockaddr_xdp member sxdp_shared_umem_fd.
The UMEM has two single-producer/single-consumer rings, that are used The UMEM has two single-producer/single-consumer rings that are used
to transfer ownership of UMEM frames between the kernel and the to transfer ownership of UMEM frames between the kernel and the
user-space application. user-space application.
Rings Rings
----- -----
There are a four different kind of rings: Fill, Completion, RX and There are a four different kind of rings: FILL, COMPLETION, RX and
TX. All rings are single-producer/single-consumer, so the user-space TX. All rings are single-producer/single-consumer, so the user-space
application need explicit synchronization of multiple application need explicit synchronization of multiple
processes/threads are reading/writing to them. processes/threads are reading/writing to them.
The UMEM uses two rings: Fill and Completion. Each socket associated The UMEM uses two rings: FILL and COMPLETION. Each socket associated
with the UMEM must have an RX queue, TX queue or both. Say, that there with the UMEM must have an RX queue, TX queue or both. Say, that there
is a setup with four sockets (all doing TX and RX). Then there will be is a setup with four sockets (all doing TX and RX). Then there will be
one Fill ring, one Completion ring, four TX rings and four RX rings. one FILL ring, one COMPLETION ring, four TX rings and four RX rings.
The rings are head(producer)/tail(consumer) based rings. A producer The rings are head(producer)/tail(consumer) based rings. A producer
writes the data ring at the index pointed out by struct xdp_ring writes the data ring at the index pointed out by struct xdp_ring
@ -146,7 +151,7 @@ The size of the rings need to be of size power of two.
UMEM Fill Ring UMEM Fill Ring
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
The Fill ring is used to transfer ownership of UMEM frames from The FILL ring is used to transfer ownership of UMEM frames from
user-space to kernel-space. The UMEM addrs are passed in the ring. As user-space to kernel-space. The UMEM addrs are passed in the ring. As
an example, if the UMEM is 64k and each chunk is 4k, then the UMEM has an example, if the UMEM is 64k and each chunk is 4k, then the UMEM has
16 chunks and can pass addrs between 0 and 64k. 16 chunks and can pass addrs between 0 and 64k.
@ -164,8 +169,8 @@ chunks mode, then the incoming addr will be left untouched.
UMEM Completion Ring UMEM Completion Ring
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
The Completion Ring is used transfer ownership of UMEM frames from The COMPLETION Ring is used transfer ownership of UMEM frames from
kernel-space to user-space. Just like the Fill ring, UMEM indicies are kernel-space to user-space. Just like the FILL ring, UMEM indices are
used. used.
Frames passed from the kernel to user-space are frames that has been Frames passed from the kernel to user-space are frames that has been
@ -181,7 +186,7 @@ The RX ring is the receiving side of a socket. Each entry in the ring
is a struct xdp_desc descriptor. The descriptor contains UMEM offset is a struct xdp_desc descriptor. The descriptor contains UMEM offset
(addr) and the length of the data (len). (addr) and the length of the data (len).
If no frames have been passed to kernel via the Fill ring, no If no frames have been passed to kernel via the FILL ring, no
descriptors will (or can) appear on the RX ring. descriptors will (or can) appear on the RX ring.
The user application consumes struct xdp_desc descriptors from this The user application consumes struct xdp_desc descriptors from this
@ -199,8 +204,24 @@ be relaxed in the future.
The user application produces struct xdp_desc descriptors to this The user application produces struct xdp_desc descriptors to this
ring. ring.
Libbpf
======
Libbpf is a helper library for eBPF and XDP that makes using these
technologies a lot simpler. It also contains specific helper functions
in tools/lib/bpf/xsk.h for facilitating the use of AF_XDP. It
contains two types of functions: those that can be used to make the
setup of AF_XDP socket easier and ones that can be used in the data
plane to access the rings safely and quickly. To see an example on how
to use this API, please take a look at the sample application in
samples/bpf/xdpsock_usr.c which uses libbpf for both setup and data
plane operations.
We recommend that you use this library unless you have become a power
user. It will make your program a lot simpler.
XSKMAP / BPF_MAP_TYPE_XSKMAP XSKMAP / BPF_MAP_TYPE_XSKMAP
---------------------------- ============================
On XDP side there is a BPF map type BPF_MAP_TYPE_XSKMAP (XSKMAP) that On XDP side there is a BPF map type BPF_MAP_TYPE_XSKMAP (XSKMAP) that
is used in conjunction with bpf_redirect_map() to pass the ingress is used in conjunction with bpf_redirect_map() to pass the ingress
@ -216,21 +237,193 @@ queue 17. Only the XDP program executing for eth0 and queue 17 will
successfully pass data to the socket. Please refer to the sample successfully pass data to the socket. Please refer to the sample
application (samples/bpf/) in for an example. application (samples/bpf/) in for an example.
Configuration Flags and Socket Options
======================================
These are the various configuration flags that can be used to control
and monitor the behavior of AF_XDP sockets.
XDP_COPY and XDP_ZERO_COPY bind flags
-------------------------------------
When you bind to a socket, the kernel will first try to use zero-copy
copy. If zero-copy is not supported, it will fall back on using copy
mode, i.e. copying all packets out to user space. But if you would
like to force a certain mode, you can use the following flags. If you
pass the XDP_COPY flag to the bind call, the kernel will force the
socket into copy mode. If it cannot use copy mode, the bind call will
fail with an error. Conversely, the XDP_ZERO_COPY flag will force the
socket into zero-copy mode or fail.
XDP_SHARED_UMEM bind flag
-------------------------
This flag enables you to bind multiple sockets to the same UMEM, but
only if they share the same queue id. In this mode, each socket has
their own RX and TX rings, but the UMEM (tied to the fist socket
created) only has a single FILL ring and a single COMPLETION
ring. To use this mode, create the first socket and bind it in the normal
way. Create a second socket and create an RX and a TX ring, or at
least one of them, but no FILL or COMPLETION rings as the ones from
the first socket will be used. In the bind call, set he
XDP_SHARED_UMEM option and provide the initial socket's fd in the
sxdp_shared_umem_fd field. You can attach an arbitrary number of extra
sockets this way.
What socket will then a packet arrive on? This is decided by the XDP
program. Put all the sockets in the XSK_MAP and just indicate which
index in the array you would like to send each packet to. A simple
round-robin example of distributing packets is shown below:
.. code-block:: c
#include <linux/bpf.h>
#include "bpf_helpers.h"
#define MAX_SOCKS 16
struct {
__uint(type, BPF_MAP_TYPE_XSKMAP);
__uint(max_entries, MAX_SOCKS);
__uint(key_size, sizeof(int));
__uint(value_size, sizeof(int));
} xsks_map SEC(".maps");
static unsigned int rr;
SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx)
{
rr = (rr + 1) & (MAX_SOCKS - 1);
return bpf_redirect_map(&xsks_map, rr, 0);
}
Note, that since there is only a single set of FILL and COMPLETION
rings, and they are single producer, single consumer rings, you need
to make sure that multiple processes or threads do not use these rings
concurrently. There are no synchronization primitives in the
libbpf code that protects multiple users at this point in time.
XDP_USE_NEED_WAKEUP bind flag
-----------------------------
This option adds support for a new flag called need_wakeup that is
present in the FILL ring and the TX ring, the rings for which user
space is a producer. When this option is set in the bind call, the
need_wakeup flag will be set if the kernel needs to be explicitly
woken up by a syscall to continue processing packets. If the flag is
zero, no syscall is needed.
If the flag is set on the FILL ring, the application needs to call
poll() to be able to continue to receive packets on the RX ring. This
can happen, for example, when the kernel has detected that there are no
more buffers on the FILL ring and no buffers left on the RX HW ring of
the NIC. In this case, interrupts are turned off as the NIC cannot
receive any packets (as there are no buffers to put them in), and the
need_wakeup flag is set so that user space can put buffers on the
FILL ring and then call poll() so that the kernel driver can put these
buffers on the HW ring and start to receive packets.
If the flag is set for the TX ring, it means that the application
needs to explicitly notify the kernel to send any packets put on the
TX ring. This can be accomplished either by a poll() call, as in the
RX path, or by calling sendto().
An example of how to use this flag can be found in
samples/bpf/xdpsock_user.c. An example with the use of libbpf helpers
would look like this for the TX path:
.. code-block:: c
if (xsk_ring_prod__needs_wakeup(&my_tx_ring))
sendto(xsk_socket__fd(xsk_handle), NULL, 0, MSG_DONTWAIT, NULL, 0);
I.e., only use the syscall if the flag is set.
We recommend that you always enable this mode as it usually leads to
better performance especially if you run the application and the
driver on the same core, but also if you use different cores for the
application and the kernel driver, as it reduces the number of
syscalls needed for the TX path.
XDP_{RX|TX|UMEM_FILL|UMEM_COMPLETION}_RING setsockopts
------------------------------------------------------
These setsockopts sets the number of descriptors that the RX, TX,
FILL, and COMPLETION rings respectively should have. It is mandatory
to set the size of at least one of the RX and TX rings. If you set
both, you will be able to both receive and send traffic from your
application, but if you only want to do one of them, you can save
resources by only setting up one of them. Both the FILL ring and the
COMPLETION ring are mandatory if you have a UMEM tied to your socket,
which is the normal case. But if the XDP_SHARED_UMEM flag is used, any
socket after the first one does not have a UMEM and should in that
case not have any FILL or COMPLETION rings created.
XDP_UMEM_REG setsockopt
-----------------------
This setsockopt registers a UMEM to a socket. This is the area that
contain all the buffers that packet can recide in. The call takes a
pointer to the beginning of this area and the size of it. Moreover, it
also has parameter called chunk_size that is the size that the UMEM is
divided into. It can only be 2K or 4K at the moment. If you have an
UMEM area that is 128K and a chunk size of 2K, this means that you
will be able to hold a maximum of 128K / 2K = 64 packets in your UMEM
area and that your largest packet size can be 2K.
There is also an option to set the headroom of each single buffer in
the UMEM. If you set this to N bytes, it means that the packet will
start N bytes into the buffer leaving the first N bytes for the
application to use. The final option is the flags field, but it will
be dealt with in separate sections for each UMEM flag.
SO_BINDTODEVICE setsockopt
--------------------------
This is a generic SOL_SOCKET option that can be used to tie AF_XDP
socket to a particular network interface. It is useful when a socket
is created by a privileged process and passed to a non-privileged one.
Once the option is set, kernel will refuse attempts to bind that socket
to a different interface. Updating the value requires CAP_NET_RAW.
XDP_STATISTICS getsockopt
-------------------------
Gets drop statistics of a socket that can be useful for debug
purposes. The supported statistics are shown below:
.. code-block:: c
struct xdp_statistics {
__u64 rx_dropped; /* Dropped for reasons other than invalid desc */
__u64 rx_invalid_descs; /* Dropped due to invalid descriptor */
__u64 tx_invalid_descs; /* Dropped due to invalid descriptor */
};
XDP_OPTIONS getsockopt
----------------------
Gets options from an XDP socket. The only one supported so far is
XDP_OPTIONS_ZEROCOPY which tells you if zero-copy is on or not.
Usage Usage
===== =====
In order to use AF_XDP sockets there are two parts needed. The In order to use AF_XDP sockets two parts are needed. The
user-space application and the XDP program. For a complete setup and user-space application and the XDP program. For a complete setup and
usage example, please refer to the sample application. The user-space usage example, please refer to the sample application. The user-space
side is xdpsock_user.c and the XDP side is part of libbpf. side is xdpsock_user.c and the XDP side is part of libbpf.
The XDP code sample included in tools/lib/bpf/xsk.c is the following:: The XDP code sample included in tools/lib/bpf/xsk.c is the following:
.. code-block:: c
SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx) SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx)
{ {
int index = ctx->rx_queue_index; int index = ctx->rx_queue_index;
// A set entry here means that the correspnding queue_id // A set entry here means that the corresponding queue_id
// has an active AF_XDP socket bound to it. // has an active AF_XDP socket bound to it.
if (bpf_map_lookup_elem(&xsks_map, &index)) if (bpf_map_lookup_elem(&xsks_map, &index))
return bpf_redirect_map(&xsks_map, index, 0); return bpf_redirect_map(&xsks_map, index, 0);
@ -238,7 +431,10 @@ The XDP code sample included in tools/lib/bpf/xsk.c is the following::
return XDP_PASS; return XDP_PASS;
} }
Naive ring dequeue and enqueue could look like this:: A simple but not so performance ring dequeue and enqueue could look
like this:
.. code-block:: c
// struct xdp_rxtx_ring { // struct xdp_rxtx_ring {
// __u32 *producer; // __u32 *producer;
@ -287,17 +483,16 @@ Naive ring dequeue and enqueue could look like this::
return 0; return 0;
} }
But please use the libbpf functions as they are optimized and ready to
For a more optimized version, please refer to the sample application. use. Will make your life easier.
Sample application Sample application
================== ==================
There is a xdpsock benchmarking/test application included that There is a xdpsock benchmarking/test application included that
demonstrates how to use AF_XDP sockets with both private and shared demonstrates how to use AF_XDP sockets with private UMEMs. Say that
UMEMs. Say that you would like your UDP traffic from port 4242 to end you would like your UDP traffic from port 4242 to end up in queue 16,
up in queue 16, that we will enable AF_XDP on. Here, we use ethtool that we will enable AF_XDP on. Here, we use ethtool for this::
for this::
ethtool -N p3p2 rx-flow-hash udp4 fn ethtool -N p3p2 rx-flow-hash udp4 fn
ethtool -N p3p2 flow-type udp4 src-port 4242 dst-port 4242 \ ethtool -N p3p2 flow-type udp4 src-port 4242 dst-port 4242 \
@ -311,13 +506,18 @@ using::
For XDP_SKB mode, use the switch "-S" instead of "-N" and all options For XDP_SKB mode, use the switch "-S" instead of "-N" and all options
can be displayed with "-h", as usual. can be displayed with "-h", as usual.
This sample application uses libbpf to make the setup and usage of
AF_XDP simpler. If you want to know how the raw uapi of AF_XDP is
really used to make something more advanced, take a look at the libbpf
code in tools/lib/bpf/xsk.[ch].
FAQ FAQ
======= =======
Q: I am not seeing any traffic on the socket. What am I doing wrong? Q: I am not seeing any traffic on the socket. What am I doing wrong?
A: When a netdev of a physical NIC is initialized, Linux usually A: When a netdev of a physical NIC is initialized, Linux usually
allocates one Rx and Tx queue pair per core. So on a 8 core system, allocates one RX and TX queue pair per core. So on a 8 core system,
queue ids 0 to 7 will be allocated, one per core. In the AF_XDP queue ids 0 to 7 will be allocated, one per core. In the AF_XDP
bind call or the xsk_socket__create libbpf function call, you bind call or the xsk_socket__create libbpf function call, you
specify a specific queue id to bind to and it is only the traffic specify a specific queue id to bind to and it is only the traffic
@ -343,9 +543,21 @@ A: When a netdev of a physical NIC is initialized, Linux usually
sudo ethtool -N <interface> flow-type udp4 src-port 4242 dst-port \ sudo ethtool -N <interface> flow-type udp4 src-port 4242 dst-port \
4242 action 2 4242 action 2
A number of other ways are possible all up to the capabilitites of A number of other ways are possible all up to the capabilities of
the NIC you have. the NIC you have.
Q: Can I use the XSKMAP to implement a switch betwen different umems
in copy mode?
A: The short answer is no, that is not supported at the moment. The
XSKMAP can only be used to switch traffic coming in on queue id X
to sockets bound to the same queue id X. The XSKMAP can contain
sockets bound to different queue ids, for example X and Y, but only
traffic goming in from queue id Y can be directed to sockets bound
to the same queue id Y. In zero-copy mode, you should use the
switch, or other distribution mechanism, in your NIC to direct
traffic to the correct queue id and socket.
Credits Credits
======= =======

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 5 VERSION = 5
PATCHLEVEL = 4 PATCHLEVEL = 4
SUBLEVEL = 250 SUBLEVEL = 251
EXTRAVERSION = EXTRAVERSION =
NAME = Kleptomaniac Octopus NAME = Kleptomaniac Octopus

View File

@ -8,6 +8,10 @@
#include <asm/dwarf.h> #include <asm/dwarf.h>
#define ASM_NL ` /* use '`' to mark new line in macro */
#define __ALIGN .align 4
#define __ALIGN_STR __stringify(__ALIGN)
#ifdef __ASSEMBLY__ #ifdef __ASSEMBLY__
.macro ST2 e, o, off .macro ST2 e, o, off
@ -28,10 +32,6 @@
#endif #endif
.endm .endm
#define ASM_NL ` /* use '`' to mark new line in macro */
#define __ALIGN .align 4
#define __ALIGN_STR __stringify(__ALIGN)
/* annotation for data we want in DCCM - if enabled in .config */ /* annotation for data we want in DCCM - if enabled in .config */
.macro ARCFP_DATA nm .macro ARCFP_DATA nm
#ifdef CONFIG_ARC_HAS_DCCM #ifdef CONFIG_ARC_HAS_DCCM

View File

@ -511,7 +511,6 @@
"spi_lr_session_done", "spi_lr_session_done",
"spi_lr_overread"; "spi_lr_overread";
clocks = <&iprocmed>; clocks = <&iprocmed>;
clock-names = "iprocmed";
num-cs = <2>; num-cs = <2>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;

View File

@ -5,9 +5,11 @@
#include "omap3-gta04a5.dts" #include "omap3-gta04a5.dts"
&omap3_pmx_core { / {
model = "Goldelico GTA04A5/Letux 2804 with OneNAND"; model = "Goldelico GTA04A5/Letux 2804 with OneNAND";
};
&omap3_pmx_core {
gpmc_pins: pinmux_gpmc_pins { gpmc_pins: pinmux_gpmc_pins {
pinctrl-single,pins = < pinctrl-single,pins = <

View File

@ -9,6 +9,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include "soc.h" #include "soc.h"
#include "platform.h"
/************************************************************************* /*************************************************************************
* Timer handling for EP93xx * Timer handling for EP93xx
@ -60,7 +61,7 @@ static u64 notrace ep93xx_read_sched_clock(void)
return ret; return ret;
} }
u64 ep93xx_clocksource_read(struct clocksource *c) static u64 ep93xx_clocksource_read(struct clocksource *c)
{ {
u64 ret; u64 ret;

View File

@ -63,6 +63,9 @@ static void __init orion5x_dt_init(void)
if (of_machine_is_compatible("maxtor,shared-storage-2")) if (of_machine_is_compatible("maxtor,shared-storage-2"))
mss2_init(); mss2_init();
if (of_machine_is_compatible("lacie,d2-network"))
d2net_init();
of_platform_default_populate(NULL, orion5x_auxdata_lookup, NULL); of_platform_default_populate(NULL, orion5x_auxdata_lookup, NULL);
} }

View File

@ -75,6 +75,12 @@ extern void mss2_init(void);
static inline void mss2_init(void) {} static inline void mss2_init(void) {}
#endif #endif
#ifdef CONFIG_MACH_D2NET_DT
void d2net_init(void);
#else
static inline void d2net_init(void) {}
#endif
/***************************************************************************** /*****************************************************************************
* Helpers to access Orion registers * Helpers to access Orion registers
****************************************************************************/ ****************************************************************************/

View File

@ -40,7 +40,7 @@ enum probes_insn checker_stack_use_imm_0xx(probes_opcode_t insn,
* Different from other insn uses imm8, the real addressing offset of * Different from other insn uses imm8, the real addressing offset of
* STRD in T32 encoding should be imm8 * 4. See ARMARM description. * STRD in T32 encoding should be imm8 * 4. See ARMARM description.
*/ */
enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn, static enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn,
struct arch_probes_insn *asi, struct arch_probes_insn *asi,
const struct decode_header *h) const struct decode_header *h)
{ {

View File

@ -231,7 +231,7 @@ singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb)
* kprobe, and that level is reserved for user kprobe handlers, so we can't * kprobe, and that level is reserved for user kprobe handlers, so we can't
* risk encountering a new kprobe in an interrupt handler. * risk encountering a new kprobe in an interrupt handler.
*/ */
void __kprobes kprobe_handler(struct pt_regs *regs) static void __kprobes kprobe_handler(struct pt_regs *regs)
{ {
struct kprobe *p, *cur; struct kprobe *p, *cur;
struct kprobe_ctlblk *kcb; struct kprobe_ctlblk *kcb;

View File

@ -145,8 +145,6 @@ __arch_remove_optimized_kprobe(struct optimized_kprobe *op, int dirty)
} }
} }
extern void kprobe_handler(struct pt_regs *regs);
static void static void
optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs) optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
{ {

View File

@ -720,7 +720,7 @@ static const char coverage_register_lookup[16] = {
[REG_TYPE_NOSPPCX] = COVERAGE_ANY_REG | COVERAGE_SP, [REG_TYPE_NOSPPCX] = COVERAGE_ANY_REG | COVERAGE_SP,
}; };
unsigned coverage_start_registers(const struct decode_header *h) static unsigned coverage_start_registers(const struct decode_header *h)
{ {
unsigned regs = 0; unsigned regs = 0;
int i; int i;

View File

@ -453,3 +453,7 @@ void kprobe_thumb32_test_cases(void);
#else #else
void kprobe_arm_test_cases(void); void kprobe_arm_test_cases(void);
#endif #endif
void __kprobes_test_case_start(void);
void __kprobes_test_case_end_16(void);
void __kprobes_test_case_end_32(void);

View File

@ -1451,7 +1451,7 @@
}; };
}; };
camss: camss@1b00000 { camss: camss@1b0ac00 {
compatible = "qcom,msm8916-camss"; compatible = "qcom,msm8916-camss";
reg = <0x1b0ac00 0x200>, reg = <0x1b0ac00 0x200>,
<0x1b00030 0x4>, <0x1b00030 0x4>,

View File

@ -269,7 +269,7 @@
}; };
scif1_pins: scif1 { scif1_pins: scif1 {
groups = "scif1_data_b", "scif1_ctrl"; groups = "scif1_data_b";
function = "scif1"; function = "scif1";
}; };
@ -329,7 +329,6 @@
&scif1 { &scif1 {
pinctrl-0 = <&scif1_pins>; pinctrl-0 = <&scif1_pins>;
pinctrl-names = "default"; pinctrl-names = "default";
uart-has-rtscts;
status = "okay"; status = "okay";
}; };

View File

@ -399,7 +399,7 @@ static phys_addr_t pgd_pgtable_alloc(int shift)
static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt, static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt,
phys_addr_t size, pgprot_t prot) phys_addr_t size, pgprot_t prot)
{ {
if ((virt >= PAGE_END) && (virt < VMALLOC_START)) { if (virt < PAGE_OFFSET) {
pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n", pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n",
&phys, virt); &phys, virt);
return; return;
@ -426,7 +426,7 @@ void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
static void update_mapping_prot(phys_addr_t phys, unsigned long virt, static void update_mapping_prot(phys_addr_t phys, unsigned long virt,
phys_addr_t size, pgprot_t prot) phys_addr_t size, pgprot_t prot)
{ {
if ((virt >= PAGE_END) && (virt < VMALLOC_START)) { if (virt < PAGE_OFFSET) {
pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n", pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n",
&phys, virt); &phys, virt);
return; return;

View File

@ -234,7 +234,7 @@ config PPC_EARLY_DEBUG_40x
config PPC_EARLY_DEBUG_CPM config PPC_EARLY_DEBUG_CPM
bool "Early serial debugging for Freescale CPM-based serial ports" bool "Early serial debugging for Freescale CPM-based serial ports"
depends on SERIAL_CPM depends on SERIAL_CPM=y
help help
Select this to enable early debugging for Freescale chips Select this to enable early debugging for Freescale chips
using a CPM-based serial port. This assumes that the bootwrapper using a CPM-based serial port. This assumes that the bootwrapper

View File

@ -425,3 +425,11 @@ checkbin:
echo -n '*** Please use a different binutils version.' ; \ echo -n '*** Please use a different binutils version.' ; \
false ; \ false ; \
fi fi
@if test "x${CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT}" = "xy" -a \
"x${CONFIG_LD_IS_BFD}" = "xy" -a \
"${CONFIG_LD_VERSION}" = "23700" ; then \
echo -n '*** binutils 2.37 drops unused section symbols, which recordmcount ' ; \
echo 'is unable to handle.' ; \
echo '*** Please use a different binutils version.' ; \
false ; \
fi

View File

@ -178,7 +178,7 @@ static bool altmap_cross_boundary(struct vmem_altmap *altmap, unsigned long star
unsigned long nr_pfn = page_size / sizeof(struct page); unsigned long nr_pfn = page_size / sizeof(struct page);
unsigned long start_pfn = page_to_pfn((struct page *)start); unsigned long start_pfn = page_to_pfn((struct page *)start);
if ((start_pfn + nr_pfn) > altmap->end_pfn) if ((start_pfn + nr_pfn - 1) > altmap->end_pfn)
return true; return true;
if (start_pfn < altmap->base_pfn) if (start_pfn < altmap->base_pfn)

View File

@ -1982,6 +1982,10 @@ static unsigned long kvm_s390_next_dirty_cmma(struct kvm_memslots *slots,
ms = slots->memslots + slotidx; ms = slots->memslots + slotidx;
ofs = 0; ofs = 0;
} }
if (cur_gfn < ms->base_gfn)
ofs = 0;
ofs = find_next_bit(kvm_second_dirty_bitmap(ms), ms->npages, ofs); ofs = find_next_bit(kvm_second_dirty_bitmap(ms), ms->npages, ofs);
while ((slotidx > 0) && (ofs >= ms->npages)) { while ((slotidx > 0) && (ofs >= ms->npages)) {
slotidx--; slotidx--;

View File

@ -168,7 +168,8 @@ static int setup_apcb00(struct kvm_vcpu *vcpu, unsigned long *apcb_s,
sizeof(struct kvm_s390_apcb0))) sizeof(struct kvm_s390_apcb0)))
return -EFAULT; return -EFAULT;
bitmap_and(apcb_s, apcb_s, apcb_h, sizeof(struct kvm_s390_apcb0)); bitmap_and(apcb_s, apcb_s, apcb_h,
BITS_PER_BYTE * sizeof(struct kvm_s390_apcb0));
return 0; return 0;
} }
@ -190,7 +191,8 @@ static int setup_apcb11(struct kvm_vcpu *vcpu, unsigned long *apcb_s,
sizeof(struct kvm_s390_apcb1))) sizeof(struct kvm_s390_apcb1)))
return -EFAULT; return -EFAULT;
bitmap_and(apcb_s, apcb_s, apcb_h, sizeof(struct kvm_s390_apcb1)); bitmap_and(apcb_s, apcb_s, apcb_h,
BITS_PER_BYTE * sizeof(struct kvm_s390_apcb1));
return 0; return 0;
} }

View File

@ -18,6 +18,18 @@
#include <cpu/dma-register.h> #include <cpu/dma-register.h>
#include <cpu/dma.h> #include <cpu/dma.h>
/*
* Some of the SoCs feature two DMAC modules. In such a case, the channels are
* distributed equally among them.
*/
#ifdef SH_DMAC_BASE1
#define SH_DMAC_NR_MD_CH (CONFIG_NR_ONCHIP_DMA_CHANNELS / 2)
#else
#define SH_DMAC_NR_MD_CH CONFIG_NR_ONCHIP_DMA_CHANNELS
#endif
#define SH_DMAC_CH_SZ 0x10
/* /*
* Define the default configuration for dual address memory-memory transfer. * Define the default configuration for dual address memory-memory transfer.
* The 0x400 value represents auto-request, external->external. * The 0x400 value represents auto-request, external->external.
@ -29,7 +41,7 @@ static unsigned long dma_find_base(unsigned int chan)
unsigned long base = SH_DMAC_BASE0; unsigned long base = SH_DMAC_BASE0;
#ifdef SH_DMAC_BASE1 #ifdef SH_DMAC_BASE1
if (chan >= 6) if (chan >= SH_DMAC_NR_MD_CH)
base = SH_DMAC_BASE1; base = SH_DMAC_BASE1;
#endif #endif
@ -40,13 +52,13 @@ static unsigned long dma_base_addr(unsigned int chan)
{ {
unsigned long base = dma_find_base(chan); unsigned long base = dma_find_base(chan);
/* Normalize offset calculation */ chan = (chan % SH_DMAC_NR_MD_CH) * SH_DMAC_CH_SZ;
if (chan >= 9)
chan -= 6;
if (chan >= 4)
base += 0x10;
return base + (chan * 0x10); /* DMAOR is placed inside the channel register space. Step over it. */
if (chan >= DMAOR)
base += SH_DMAC_CH_SZ;
return base + chan;
} }
#ifdef CONFIG_SH_DMA_IRQ_MULTI #ifdef CONFIG_SH_DMA_IRQ_MULTI
@ -250,12 +262,11 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan)
#define NR_DMAOR 1 #define NR_DMAOR 1
#endif #endif
/* #define dmaor_read_reg(n) __raw_readw(dma_find_base((n) * \
* DMAOR bases are broken out amongst channel groups. DMAOR0 manages SH_DMAC_NR_MD_CH) + DMAOR)
* channels 0 - 5, DMAOR1 6 - 11 (optional). #define dmaor_write_reg(n, data) __raw_writew(data, \
*/ dma_find_base((n) * \
#define dmaor_read_reg(n) __raw_readw(dma_find_base((n)*6)) SH_DMAC_NR_MD_CH) + DMAOR)
#define dmaor_write_reg(n, data) __raw_writew(data, dma_find_base(n)*6)
static inline int dmaor_reset(int no) static inline int dmaor_reset(int no)
{ {

View File

@ -21,7 +21,7 @@ static int __init scan_cache(unsigned long node, const char *uname,
if (!of_flat_dt_is_compatible(node, "jcore,cache")) if (!of_flat_dt_is_compatible(node, "jcore,cache"))
return 0; return 0;
j2_ccr_base = (u32 __iomem *)of_flat_dt_translate_address(node); j2_ccr_base = ioremap(of_flat_dt_translate_address(node), 4);
return 1; return 1;
} }

View File

@ -593,6 +593,18 @@ static int __rdtgroup_move_task(struct task_struct *tsk,
return 0; return 0;
} }
static bool is_closid_match(struct task_struct *t, struct rdtgroup *r)
{
return (rdt_alloc_capable &&
(r->type == RDTCTRL_GROUP) && (t->closid == r->closid));
}
static bool is_rmid_match(struct task_struct *t, struct rdtgroup *r)
{
return (rdt_mon_capable &&
(r->type == RDTMON_GROUP) && (t->rmid == r->mon.rmid));
}
/** /**
* rdtgroup_tasks_assigned - Test if tasks have been assigned to resource group * rdtgroup_tasks_assigned - Test if tasks have been assigned to resource group
* @r: Resource group * @r: Resource group
@ -608,8 +620,7 @@ int rdtgroup_tasks_assigned(struct rdtgroup *r)
rcu_read_lock(); rcu_read_lock();
for_each_process_thread(p, t) { for_each_process_thread(p, t) {
if ((r->type == RDTCTRL_GROUP && t->closid == r->closid) || if (is_closid_match(t, r) || is_rmid_match(t, r)) {
(r->type == RDTMON_GROUP && t->rmid == r->mon.rmid)) {
ret = 1; ret = 1;
break; break;
} }
@ -704,12 +715,15 @@ unlock:
static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s) static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s)
{ {
struct task_struct *p, *t; struct task_struct *p, *t;
pid_t pid;
rcu_read_lock(); rcu_read_lock();
for_each_process_thread(p, t) { for_each_process_thread(p, t) {
if ((r->type == RDTCTRL_GROUP && t->closid == r->closid) || if (is_closid_match(t, r) || is_rmid_match(t, r)) {
(r->type == RDTMON_GROUP && t->rmid == r->mon.rmid)) pid = task_pid_vnr(t);
seq_printf(s, "%d\n", t->pid); if (pid)
seq_printf(s, "%d\n", pid);
}
} }
rcu_read_unlock(); rcu_read_unlock();
} }
@ -2148,18 +2162,6 @@ static int reset_all_ctrls(struct rdt_resource *r)
return 0; return 0;
} }
static bool is_closid_match(struct task_struct *t, struct rdtgroup *r)
{
return (rdt_alloc_capable &&
(r->type == RDTCTRL_GROUP) && (t->closid == r->closid));
}
static bool is_rmid_match(struct task_struct *t, struct rdtgroup *r)
{
return (rdt_mon_capable &&
(r->type == RDTMON_GROUP) && (t->rmid == r->mon.rmid));
}
/* /*
* Move tasks from one to the other group. If @from is NULL, then all tasks * Move tasks from one to the other group. If @from is NULL, then all tasks
* in the systems are moved unconditionally (used for teardown). * in the systems are moved unconditionally (used for teardown).

View File

@ -99,6 +99,17 @@ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map);
DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info); DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
EXPORT_PER_CPU_SYMBOL(cpu_info); EXPORT_PER_CPU_SYMBOL(cpu_info);
struct mwait_cpu_dead {
unsigned int control;
unsigned int status;
};
/*
* Cache line aligned data for mwait_play_dead(). Separate on purpose so
* that it's unlikely to be touched by other CPUs.
*/
static DEFINE_PER_CPU_ALIGNED(struct mwait_cpu_dead, mwait_cpu_dead);
/* Logical package management. We might want to allocate that dynamically */ /* Logical package management. We might want to allocate that dynamically */
unsigned int __max_logical_packages __read_mostly; unsigned int __max_logical_packages __read_mostly;
EXPORT_SYMBOL(__max_logical_packages); EXPORT_SYMBOL(__max_logical_packages);
@ -1675,10 +1686,10 @@ static bool wakeup_cpu0(void)
*/ */
static inline void mwait_play_dead(void) static inline void mwait_play_dead(void)
{ {
struct mwait_cpu_dead *md = this_cpu_ptr(&mwait_cpu_dead);
unsigned int eax, ebx, ecx, edx; unsigned int eax, ebx, ecx, edx;
unsigned int highest_cstate = 0; unsigned int highest_cstate = 0;
unsigned int highest_subcstate = 0; unsigned int highest_subcstate = 0;
void *mwait_ptr;
int i; int i;
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
@ -1713,13 +1724,6 @@ static inline void mwait_play_dead(void)
(highest_subcstate - 1); (highest_subcstate - 1);
} }
/*
* This should be a memory location in a cache line which is
* unlikely to be touched by other processors. The actual
* content is immaterial as it is not actually modified in any way.
*/
mwait_ptr = &current_thread_info()->flags;
wbinvd(); wbinvd();
while (1) { while (1) {
@ -1731,9 +1735,9 @@ static inline void mwait_play_dead(void)
* case where we return around the loop. * case where we return around the loop.
*/ */
mb(); mb();
clflush(mwait_ptr); clflush(md);
mb(); mb();
__monitor(mwait_ptr, 0, 0); __monitor(md, 0, 0);
mb(); mb();
__mwait(eax, 0); __mwait(eax, 0);
/* /*

View File

@ -231,7 +231,7 @@ static int tuntap_probe(struct iss_net_private *lp, int index, char *init)
init += sizeof(TRANSPORT_TUNTAP_NAME) - 1; init += sizeof(TRANSPORT_TUNTAP_NAME) - 1;
if (*init == ',') { if (*init == ',') {
rem = split_if_spec(init + 1, &mac_str, &dev_name); rem = split_if_spec(init + 1, &mac_str, &dev_name, NULL);
if (rem != NULL) { if (rem != NULL) {
pr_err("%s: extra garbage on specification : '%s'\n", pr_err("%s: extra garbage on specification : '%s'\n",
dev->name, rem); dev->name, rem);

View File

@ -11,11 +11,19 @@
#define pr_fmt(fmt) fmt #define pr_fmt(fmt) fmt
#include <linux/types.h> #include <linux/types.h>
#include <linux/mm_types.h>
#include <linux/overflow.h>
#include <linux/affs_hardblocks.h> #include <linux/affs_hardblocks.h>
#include "check.h" #include "check.h"
#include "amiga.h" #include "amiga.h"
/* magic offsets in partition DosEnvVec */
#define NR_HD 3
#define NR_SECT 5
#define LO_CYL 9
#define HI_CYL 10
static __inline__ u32 static __inline__ u32
checksum_block(__be32 *m, int size) checksum_block(__be32 *m, int size)
{ {
@ -32,8 +40,12 @@ int amiga_partition(struct parsed_partitions *state)
unsigned char *data; unsigned char *data;
struct RigidDiskBlock *rdb; struct RigidDiskBlock *rdb;
struct PartitionBlock *pb; struct PartitionBlock *pb;
int start_sect, nr_sects, blk, part, res = 0; u64 start_sect, nr_sects;
int blksize = 1; /* Multiplier for disk block size */ sector_t blk, end_sect;
u32 cylblk; /* rdb_CylBlocks = nr_heads*sect_per_track */
u32 nr_hd, nr_sect, lo_cyl, hi_cyl;
int part, res = 0;
unsigned int blksize = 1; /* Multiplier for disk block size */
int slot = 1; int slot = 1;
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
@ -43,7 +55,7 @@ int amiga_partition(struct parsed_partitions *state)
data = read_part_sector(state, blk, &sect); data = read_part_sector(state, blk, &sect);
if (!data) { if (!data) {
if (warn_no_part) if (warn_no_part)
pr_err("Dev %s: unable to read RDB block %d\n", pr_err("Dev %s: unable to read RDB block %llu\n",
bdevname(state->bdev, b), blk); bdevname(state->bdev, b), blk);
res = -1; res = -1;
goto rdb_done; goto rdb_done;
@ -60,12 +72,12 @@ int amiga_partition(struct parsed_partitions *state)
*(__be32 *)(data+0xdc) = 0; *(__be32 *)(data+0xdc) = 0;
if (checksum_block((__be32 *)data, if (checksum_block((__be32 *)data,
be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)==0) { be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)==0) {
pr_err("Trashed word at 0xd0 in block %d ignored in checksum calculation\n", pr_err("Trashed word at 0xd0 in block %llu ignored in checksum calculation\n",
blk); blk);
break; break;
} }
pr_err("Dev %s: RDB in block %d has bad checksum\n", pr_err("Dev %s: RDB in block %llu has bad checksum\n",
bdevname(state->bdev, b), blk); bdevname(state->bdev, b), blk);
} }
@ -81,12 +93,17 @@ int amiga_partition(struct parsed_partitions *state)
} }
blk = be32_to_cpu(rdb->rdb_PartitionList); blk = be32_to_cpu(rdb->rdb_PartitionList);
put_dev_sector(sect); put_dev_sector(sect);
for (part = 1; blk>0 && part<=16; part++, put_dev_sector(sect)) { for (part = 1; (s32) blk>0 && part<=16; part++, put_dev_sector(sect)) {
blk *= blksize; /* Read in terms partition table understands */ /* Read in terms partition table understands */
if (check_mul_overflow(blk, (sector_t) blksize, &blk)) {
pr_err("Dev %s: overflow calculating partition block %llu! Skipping partitions %u and beyond\n",
bdevname(state->bdev, b), blk, part);
break;
}
data = read_part_sector(state, blk, &sect); data = read_part_sector(state, blk, &sect);
if (!data) { if (!data) {
if (warn_no_part) if (warn_no_part)
pr_err("Dev %s: unable to read partition block %d\n", pr_err("Dev %s: unable to read partition block %llu\n",
bdevname(state->bdev, b), blk); bdevname(state->bdev, b), blk);
res = -1; res = -1;
goto rdb_done; goto rdb_done;
@ -98,19 +115,70 @@ int amiga_partition(struct parsed_partitions *state)
if (checksum_block((__be32 *)pb, be32_to_cpu(pb->pb_SummedLongs) & 0x7F) != 0 ) if (checksum_block((__be32 *)pb, be32_to_cpu(pb->pb_SummedLongs) & 0x7F) != 0 )
continue; continue;
/* Tell Kernel about it */ /* RDB gives us more than enough rope to hang ourselves with,
* many times over (2^128 bytes if all fields max out).
* Some careful checks are in order, so check for potential
* overflows.
* We are multiplying four 32 bit numbers to one sector_t!
*/
nr_hd = be32_to_cpu(pb->pb_Environment[NR_HD]);
nr_sect = be32_to_cpu(pb->pb_Environment[NR_SECT]);
/* CylBlocks is total number of blocks per cylinder */
if (check_mul_overflow(nr_hd, nr_sect, &cylblk)) {
pr_err("Dev %s: heads*sects %u overflows u32, skipping partition!\n",
bdevname(state->bdev, b), cylblk);
continue;
}
/* check for consistency with RDB defined CylBlocks */
if (cylblk > be32_to_cpu(rdb->rdb_CylBlocks)) {
pr_warn("Dev %s: cylblk %u > rdb_CylBlocks %u!\n",
bdevname(state->bdev, b), cylblk,
be32_to_cpu(rdb->rdb_CylBlocks));
}
/* RDB allows for variable logical block size -
* normalize to 512 byte blocks and check result.
*/
if (check_mul_overflow(cylblk, blksize, &cylblk)) {
pr_err("Dev %s: partition %u bytes per cyl. overflows u32, skipping partition!\n",
bdevname(state->bdev, b), part);
continue;
}
/* Calculate partition start and end. Limit of 32 bit on cylblk
* guarantees no overflow occurs if LBD support is enabled.
*/
lo_cyl = be32_to_cpu(pb->pb_Environment[LO_CYL]);
start_sect = ((u64) lo_cyl * cylblk);
hi_cyl = be32_to_cpu(pb->pb_Environment[HI_CYL]);
nr_sects = (((u64) hi_cyl - lo_cyl + 1) * cylblk);
nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
be32_to_cpu(pb->pb_Environment[9])) *
be32_to_cpu(pb->pb_Environment[3]) *
be32_to_cpu(pb->pb_Environment[5]) *
blksize;
if (!nr_sects) if (!nr_sects)
continue; continue;
start_sect = be32_to_cpu(pb->pb_Environment[9]) *
be32_to_cpu(pb->pb_Environment[3]) * /* Warn user if partition end overflows u32 (AmigaDOS limit) */
be32_to_cpu(pb->pb_Environment[5]) *
blksize; if ((start_sect + nr_sects) > UINT_MAX) {
pr_warn("Dev %s: partition %u (%llu-%llu) needs 64 bit device support!\n",
bdevname(state->bdev, b), part,
start_sect, start_sect + nr_sects);
}
if (check_add_overflow(start_sect, nr_sects, &end_sect)) {
pr_err("Dev %s: partition %u (%llu-%llu) needs LBD device support, skipping partition!\n",
bdevname(state->bdev, b), part,
start_sect, end_sect);
continue;
}
/* Tell Kernel about it */
put_partition(state,slot++,start_sect,nr_sects); put_partition(state,slot++,start_sect,nr_sects);
{ {
/* Be even more informative to aid mounting */ /* Be even more informative to aid mounting */

View File

@ -2596,10 +2596,10 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,
err = of_property_read_u32(state_node, "min-residency-us", &residency); err = of_property_read_u32(state_node, "min-residency-us", &residency);
if (!err) if (!err)
genpd_state->residency_ns = 1000 * residency; genpd_state->residency_ns = 1000LL * residency;
genpd_state->power_on_latency_ns = 1000 * exit_latency; genpd_state->power_on_latency_ns = 1000LL * exit_latency;
genpd_state->power_off_latency_ns = 1000 * entry_latency; genpd_state->power_off_latency_ns = 1000LL * entry_latency;
genpd_state->fwnode = &state_node->fwnode; genpd_state->fwnode = &state_node->fwnode;
return 0; return 0;

View File

@ -1708,7 +1708,8 @@ static int nbd_dev_add(int index)
if (err == -ENOSPC) if (err == -ENOSPC)
err = -EEXIST; err = -EEXIST;
} else { } else {
err = idr_alloc(&nbd_index_idr, nbd, 0, 0, GFP_KERNEL); err = idr_alloc(&nbd_index_idr, nbd, 0,
(MINORMASK >> part_shift) + 1, GFP_KERNEL);
if (err >= 0) if (err >= 0)
index = err; index = err;
} }

View File

@ -99,7 +99,7 @@ static int imx_rngc_self_test(struct imx_rngc *rngc)
cmd = readl(rngc->base + RNGC_COMMAND); cmd = readl(rngc->base + RNGC_COMMAND);
writel(cmd | RNGC_CMD_SELF_TEST, rngc->base + RNGC_COMMAND); writel(cmd | RNGC_CMD_SELF_TEST, rngc->base + RNGC_COMMAND);
ret = wait_for_completion_timeout(&rngc->rng_op_done, RNGC_TIMEOUT); ret = wait_for_completion_timeout(&rngc->rng_op_done, msecs_to_jiffies(RNGC_TIMEOUT));
if (!ret) { if (!ret) {
imx_rngc_irq_mask_clear(rngc); imx_rngc_irq_mask_clear(rngc);
return -ETIMEDOUT; return -ETIMEDOUT;
@ -182,9 +182,7 @@ static int imx_rngc_init(struct hwrng *rng)
cmd = readl(rngc->base + RNGC_COMMAND); cmd = readl(rngc->base + RNGC_COMMAND);
writel(cmd | RNGC_CMD_SEED, rngc->base + RNGC_COMMAND); writel(cmd | RNGC_CMD_SEED, rngc->base + RNGC_COMMAND);
ret = wait_for_completion_timeout(&rngc->rng_op_done, ret = wait_for_completion_timeout(&rngc->rng_op_done, msecs_to_jiffies(RNGC_TIMEOUT));
RNGC_TIMEOUT);
if (!ret) { if (!ret) {
imx_rngc_irq_mask_clear(rngc); imx_rngc_irq_mask_clear(rngc);
return -ETIMEDOUT; return -ETIMEDOUT;

View File

@ -12,6 +12,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/hw_random.h> #include <linux/hw_random.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
@ -41,7 +42,6 @@
struct st_rng_data { struct st_rng_data {
void __iomem *base; void __iomem *base;
struct clk *clk;
struct hwrng ops; struct hwrng ops;
}; };
@ -86,26 +86,18 @@ static int st_rng_probe(struct platform_device *pdev)
if (IS_ERR(base)) if (IS_ERR(base))
return PTR_ERR(base); return PTR_ERR(base);
clk = devm_clk_get(&pdev->dev, NULL); clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(clk)) if (IS_ERR(clk))
return PTR_ERR(clk); return PTR_ERR(clk);
ret = clk_prepare_enable(clk);
if (ret)
return ret;
ddata->ops.priv = (unsigned long)ddata; ddata->ops.priv = (unsigned long)ddata;
ddata->ops.read = st_rng_read; ddata->ops.read = st_rng_read;
ddata->ops.name = pdev->name; ddata->ops.name = pdev->name;
ddata->base = base; ddata->base = base;
ddata->clk = clk;
dev_set_drvdata(&pdev->dev, ddata);
ret = devm_hwrng_register(&pdev->dev, &ddata->ops); ret = devm_hwrng_register(&pdev->dev, &ddata->ops);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Failed to register HW RNG\n"); dev_err(&pdev->dev, "Failed to register HW RNG\n");
clk_disable_unprepare(clk);
return ret; return ret;
} }
@ -114,16 +106,7 @@ static int st_rng_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int st_rng_remove(struct platform_device *pdev) static const struct of_device_id st_rng_match[] __maybe_unused = {
{
struct st_rng_data *ddata = dev_get_drvdata(&pdev->dev);
clk_disable_unprepare(ddata->clk);
return 0;
}
static const struct of_device_id st_rng_match[] = {
{ .compatible = "st,rng" }, { .compatible = "st,rng" },
{}, {},
}; };
@ -135,7 +118,6 @@ static struct platform_driver st_rng_driver = {
.of_match_table = of_match_ptr(st_rng_match), .of_match_table = of_match_ptr(st_rng_match),
}, },
.probe = st_rng_probe, .probe = st_rng_probe,
.remove = st_rng_remove
}; };
module_platform_driver(st_rng_driver); module_platform_driver(st_rng_driver);

View File

@ -4,6 +4,7 @@
* Copyright (C) 2007, 2008 Rusty Russell IBM Corporation * Copyright (C) 2007, 2008 Rusty Russell IBM Corporation
*/ */
#include <asm/barrier.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/hw_random.h> #include <linux/hw_random.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
@ -19,12 +20,12 @@ struct virtrng_info {
struct virtqueue *vq; struct virtqueue *vq;
char name[25]; char name[25];
int index; int index;
bool busy;
bool hwrng_register_done; bool hwrng_register_done;
bool hwrng_removed; bool hwrng_removed;
/* data transfer */ /* data transfer */
struct completion have_data; struct completion have_data;
unsigned int data_avail; unsigned int data_avail;
unsigned int data_idx;
/* minimal size returned by rng_buffer_size() */ /* minimal size returned by rng_buffer_size() */
#if SMP_CACHE_BYTES < 32 #if SMP_CACHE_BYTES < 32
u8 data[32]; u8 data[32];
@ -36,19 +37,23 @@ struct virtrng_info {
static void random_recv_done(struct virtqueue *vq) static void random_recv_done(struct virtqueue *vq)
{ {
struct virtrng_info *vi = vq->vdev->priv; struct virtrng_info *vi = vq->vdev->priv;
unsigned int len;
/* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */ /* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */
if (!virtqueue_get_buf(vi->vq, &vi->data_avail)) if (!virtqueue_get_buf(vi->vq, &len))
return; return;
smp_store_release(&vi->data_avail, len);
complete(&vi->have_data); complete(&vi->have_data);
} }
/* The host will fill any buffer we give it with sweet, sweet randomness. */ static void request_entropy(struct virtrng_info *vi)
static void register_buffer(struct virtrng_info *vi)
{ {
struct scatterlist sg; struct scatterlist sg;
reinit_completion(&vi->have_data);
vi->data_idx = 0;
sg_init_one(&sg, vi->data, sizeof(vi->data)); sg_init_one(&sg, vi->data, sizeof(vi->data));
/* There should always be room for one buffer. */ /* There should always be room for one buffer. */
@ -57,6 +62,18 @@ static void register_buffer(struct virtrng_info *vi)
virtqueue_kick(vi->vq); virtqueue_kick(vi->vq);
} }
static unsigned int copy_data(struct virtrng_info *vi, void *buf,
unsigned int size)
{
size = min_t(unsigned int, size, vi->data_avail);
memcpy(buf, vi->data + vi->data_idx, size);
vi->data_idx += size;
vi->data_avail -= size;
if (vi->data_avail == 0)
request_entropy(vi);
return size;
}
static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
{ {
int ret; int ret;
@ -67,35 +84,37 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
if (vi->hwrng_removed) if (vi->hwrng_removed)
return -ENODEV; return -ENODEV;
if (!vi->busy) { read = 0;
vi->busy = true;
reinit_completion(&vi->have_data); /* copy available data */
register_buffer(vi); if (smp_load_acquire(&vi->data_avail)) {
chunk = copy_data(vi, buf, size);
size -= chunk;
read += chunk;
} }
if (!wait) if (!wait)
return 0; return read;
read = 0; /* We have already copied available entropy,
* so either size is 0 or data_avail is 0
*/
while (size != 0) { while (size != 0) {
/* data_avail is 0 but a request is pending */
ret = wait_for_completion_killable(&vi->have_data); ret = wait_for_completion_killable(&vi->have_data);
if (ret < 0) if (ret < 0)
return ret; return ret;
/* if vi->data_avail is 0, we have been interrupted
* by a cleanup, but buffer stays in the queue
*/
if (vi->data_avail == 0)
return read;
chunk = min_t(unsigned int, size, vi->data_avail); chunk = copy_data(vi, buf + read, size);
memcpy(buf + read, vi->data, chunk);
read += chunk;
size -= chunk; size -= chunk;
vi->data_avail = 0; read += chunk;
if (size != 0) {
reinit_completion(&vi->have_data);
register_buffer(vi);
}
} }
vi->busy = false;
return read; return read;
} }
@ -103,8 +122,7 @@ static void virtio_cleanup(struct hwrng *rng)
{ {
struct virtrng_info *vi = (struct virtrng_info *)rng->priv; struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
if (vi->busy) complete(&vi->have_data);
wait_for_completion(&vi->have_data);
} }
static int probe_common(struct virtio_device *vdev) static int probe_common(struct virtio_device *vdev)
@ -140,6 +158,9 @@ static int probe_common(struct virtio_device *vdev)
goto err_find; goto err_find;
} }
/* we always have a pending entropy request */
request_entropy(vi);
return 0; return 0;
err_find: err_find:
@ -155,9 +176,9 @@ static void remove_common(struct virtio_device *vdev)
vi->hwrng_removed = true; vi->hwrng_removed = true;
vi->data_avail = 0; vi->data_avail = 0;
vi->data_idx = 0;
complete(&vi->have_data); complete(&vi->have_data);
vdev->config->reset(vdev); vdev->config->reset(vdev);
vi->busy = false;
if (vi->hwrng_register_done) if (vi->hwrng_register_done)
hwrng_unregister(&vi->hwrng); hwrng_unregister(&vi->hwrng);
vdev->config->del_vqs(vdev); vdev->config->del_vqs(vdev);

View File

@ -693,37 +693,21 @@ static struct miscdevice vtpmx_miscdev = {
.fops = &vtpmx_fops, .fops = &vtpmx_fops,
}; };
static int vtpmx_init(void)
{
return misc_register(&vtpmx_miscdev);
}
static void vtpmx_cleanup(void)
{
misc_deregister(&vtpmx_miscdev);
}
static int __init vtpm_module_init(void) static int __init vtpm_module_init(void)
{ {
int rc; int rc;
rc = vtpmx_init();
if (rc) {
pr_err("couldn't create vtpmx device\n");
return rc;
}
workqueue = create_workqueue("tpm-vtpm"); workqueue = create_workqueue("tpm-vtpm");
if (!workqueue) { if (!workqueue) {
pr_err("couldn't create workqueue\n"); pr_err("couldn't create workqueue\n");
rc = -ENOMEM; return -ENOMEM;
goto err_vtpmx_cleanup;
} }
return 0; rc = misc_register(&vtpmx_miscdev);
if (rc) {
err_vtpmx_cleanup: pr_err("couldn't create vtpmx device\n");
vtpmx_cleanup(); destroy_workqueue(workqueue);
}
return rc; return rc;
} }
@ -731,7 +715,7 @@ err_vtpmx_cleanup:
static void __exit vtpm_module_exit(void) static void __exit vtpm_module_exit(void)
{ {
destroy_workqueue(workqueue); destroy_workqueue(workqueue);
vtpmx_cleanup(); misc_deregister(&vtpmx_miscdev);
} }
module_init(vtpm_module_init); module_init(vtpm_module_init);

View File

@ -705,6 +705,10 @@ static int cdce925_probe(struct i2c_client *client,
for (i = 0; i < data->chip_info->num_plls; ++i) { for (i = 0; i < data->chip_info->num_plls; ++i) {
pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d", pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d",
client->dev.of_node, i); client->dev.of_node, i);
if (!pll_clk_name[i]) {
err = -ENOMEM;
goto error;
}
init.name = pll_clk_name[i]; init.name = pll_clk_name[i];
data->pll[i].chip = data; data->pll[i].chip = data;
data->pll[i].hw.init = &init; data->pll[i].hw.init = &init;
@ -746,6 +750,10 @@ static int cdce925_probe(struct i2c_client *client,
init.num_parents = 1; init.num_parents = 1;
init.parent_names = &parent_name; /* Mux Y1 to input */ init.parent_names = &parent_name; /* Mux Y1 to input */
init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node); init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node);
if (!init.name) {
err = -ENOMEM;
goto error;
}
data->clk[0].chip = data; data->clk[0].chip = data;
data->clk[0].hw.init = &init; data->clk[0].hw.init = &init;
data->clk[0].index = 0; data->clk[0].index = 0;
@ -764,6 +772,10 @@ static int cdce925_probe(struct i2c_client *client,
for (i = 1; i < data->chip_info->num_outputs; ++i) { for (i = 1; i < data->chip_info->num_outputs; ++i) {
init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d", init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d",
client->dev.of_node, i+1); client->dev.of_node, i+1);
if (!init.name) {
err = -ENOMEM;
goto error;
}
data->clk[i].chip = data; data->clk[i].chip = data;
data->clk[i].hw.init = &init; data->clk[i].hw.init = &init;
data->clk[i].index = i; data->clk[i].index = i;

View File

@ -287,6 +287,8 @@ static int _sci_clk_build(struct sci_clk_provider *provider,
name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id, name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id,
sci_clk->clk_id); sci_clk->clk_id);
if (!name)
return -ENOMEM;
init.name = name; init.name = name;

View File

@ -459,6 +459,7 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
err = load_one_timing_from_dt(tegra, timing, child); err = load_one_timing_from_dt(tegra, timing, child);
if (err) { if (err) {
of_node_put(child); of_node_put(child);
kfree(tegra->timings);
return err; return err;
} }
@ -510,6 +511,7 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
err = load_timings_from_dt(tegra, node, node_ram_code); err = load_timings_from_dt(tegra, node, node_ram_code);
if (err) { if (err) {
of_node_put(node); of_node_put(node);
kfree(tegra);
return ERR_PTR(err); return ERR_PTR(err);
} }
} }

View File

@ -15,6 +15,8 @@
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/sched_clock.h> #include <linux/sched_clock.h>
#include <linux/module.h>
#include <linux/of_platform.h>
/* /*
* This driver configures the 2 16/32-bit count-up timers as follows: * This driver configures the 2 16/32-bit count-up timers as follows:
@ -464,13 +466,7 @@ out_kfree:
return err; return err;
} }
/** static int __init ttc_timer_probe(struct platform_device *pdev)
* ttc_timer_init - Initialize the timer
*
* Initializes the timer hardware and register the clock source and clock event
* timers with Linux kernal timer framework
*/
static int __init ttc_timer_init(struct device_node *timer)
{ {
unsigned int irq; unsigned int irq;
void __iomem *timer_baseaddr; void __iomem *timer_baseaddr;
@ -478,6 +474,7 @@ static int __init ttc_timer_init(struct device_node *timer)
static int initialized; static int initialized;
int clksel, ret; int clksel, ret;
u32 timer_width = 16; u32 timer_width = 16;
struct device_node *timer = pdev->dev.of_node;
if (initialized) if (initialized)
return 0; return 0;
@ -489,10 +486,10 @@ static int __init ttc_timer_init(struct device_node *timer)
* and use it. Note that the event timer uses the interrupt and it's the * and use it. Note that the event timer uses the interrupt and it's the
* 2nd TTC hence the irq_of_parse_and_map(,1) * 2nd TTC hence the irq_of_parse_and_map(,1)
*/ */
timer_baseaddr = of_iomap(timer, 0); timer_baseaddr = devm_of_iomap(&pdev->dev, timer, 0, NULL);
if (!timer_baseaddr) { if (IS_ERR(timer_baseaddr)) {
pr_err("ERROR: invalid timer base address\n"); pr_err("ERROR: invalid timer base address\n");
return -ENXIO; return PTR_ERR(timer_baseaddr);
} }
irq = irq_of_parse_and_map(timer, 1); irq = irq_of_parse_and_map(timer, 1);
@ -516,20 +513,40 @@ static int __init ttc_timer_init(struct device_node *timer)
clk_ce = of_clk_get(timer, clksel); clk_ce = of_clk_get(timer, clksel);
if (IS_ERR(clk_ce)) { if (IS_ERR(clk_ce)) {
pr_err("ERROR: timer input clock not found\n"); pr_err("ERROR: timer input clock not found\n");
return PTR_ERR(clk_ce); ret = PTR_ERR(clk_ce);
goto put_clk_cs;
} }
ret = ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width); ret = ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width);
if (ret) if (ret)
return ret; goto put_clk_ce;
ret = ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq); ret = ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq);
if (ret) if (ret)
return ret; goto put_clk_ce;
pr_info("%pOFn #0 at %p, irq=%d\n", timer, timer_baseaddr, irq); pr_info("%pOFn #0 at %p, irq=%d\n", timer, timer_baseaddr, irq);
return 0; return 0;
put_clk_ce:
clk_put(clk_ce);
put_clk_cs:
clk_put(clk_cs);
return ret;
} }
TIMER_OF_DECLARE(ttc, "cdns,ttc", ttc_timer_init); static const struct of_device_id ttc_timer_of_match[] = {
{.compatible = "cdns,ttc"},
{},
};
MODULE_DEVICE_TABLE(of, ttc_timer_of_match);
static struct platform_driver ttc_timer_driver = {
.driver = {
.name = "cdns_ttc_timer",
.of_match_table = ttc_timer_of_match,
},
};
builtin_platform_driver_probe(ttc_timer_driver, ttc_timer_probe);

View File

@ -287,7 +287,7 @@ static int mv_cesa_des_setkey(struct crypto_skcipher *cipher, const u8 *key,
static int mv_cesa_des3_ede_setkey(struct crypto_skcipher *cipher, static int mv_cesa_des3_ede_setkey(struct crypto_skcipher *cipher,
const u8 *key, unsigned int len) const u8 *key, unsigned int len)
{ {
struct mv_cesa_des_ctx *ctx = crypto_skcipher_ctx(cipher); struct mv_cesa_des3_ctx *ctx = crypto_skcipher_ctx(cipher);
int err; int err;
err = verify_skcipher_des3_key(cipher, key); err = verify_skcipher_des3_key(cipher, key);

View File

@ -1,7 +1,6 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_CRYPTO_DEV_NX_ENCRYPT) += nx-crypto.o obj-$(CONFIG_CRYPTO_DEV_NX_ENCRYPT) += nx-crypto.o
nx-crypto-objs := nx.o \ nx-crypto-objs := nx.o \
nx_debugfs.o \
nx-aes-cbc.o \ nx-aes-cbc.o \
nx-aes-ecb.o \ nx-aes-ecb.o \
nx-aes-gcm.o \ nx-aes-gcm.o \
@ -11,6 +10,7 @@ nx-crypto-objs := nx.o \
nx-sha256.o \ nx-sha256.o \
nx-sha512.o nx-sha512.o
nx-crypto-$(CONFIG_DEBUG_FS) += nx_debugfs.o
obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o nx-compress.o obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o nx-compress.o
obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o nx-compress.o obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o nx-compress.o
nx-compress-objs := nx-842.o nx-compress-objs := nx-842.o

View File

@ -169,8 +169,8 @@ struct nx_sg *nx_walk_and_build(struct nx_sg *, unsigned int,
void nx_debugfs_init(struct nx_crypto_driver *); void nx_debugfs_init(struct nx_crypto_driver *);
void nx_debugfs_fini(struct nx_crypto_driver *); void nx_debugfs_fini(struct nx_crypto_driver *);
#else #else
#define NX_DEBUGFS_INIT(drv) (0) #define NX_DEBUGFS_INIT(drv) do {} while (0)
#define NX_DEBUGFS_FINI(drv) (0) #define NX_DEBUGFS_FINI(drv) do {} while (0)
#endif #endif
#define NX_PAGE_NUM(x) ((u64)(x) & 0xfffffffffffff000ULL) #define NX_PAGE_NUM(x) ((u64)(x) & 0xfffffffffffff000ULL)

View File

@ -196,6 +196,14 @@ static const struct __extcon_info {
* @attr_name: "name" sysfs entry * @attr_name: "name" sysfs entry
* @attr_state: "state" sysfs entry * @attr_state: "state" sysfs entry
* @attrs: the array pointing to attr_name and attr_state for attr_g * @attrs: the array pointing to attr_name and attr_state for attr_g
* @usb_propval: the array of USB connector properties
* @chg_propval: the array of charger connector properties
* @jack_propval: the array of jack connector properties
* @disp_propval: the array of display connector properties
* @usb_bits: the bit array of the USB connector property capabilities
* @chg_bits: the bit array of the charger connector property capabilities
* @jack_bits: the bit array of the jack connector property capabilities
* @disp_bits: the bit array of the display connector property capabilities
*/ */
struct extcon_cable { struct extcon_cable {
struct extcon_dev *edev; struct extcon_dev *edev;

View File

@ -615,7 +615,7 @@ svc_create_memory_pool(struct platform_device *pdev,
end = rounddown(sh_memory->addr + sh_memory->size, PAGE_SIZE); end = rounddown(sh_memory->addr + sh_memory->size, PAGE_SIZE);
paddr = begin; paddr = begin;
size = end - begin; size = end - begin;
va = memremap(paddr, size, MEMREMAP_WC); va = devm_memremap(dev, paddr, size, MEMREMAP_WC);
if (!va) { if (!va) {
dev_err(dev, "fail to remap shared memory\n"); dev_err(dev, "fail to remap shared memory\n");
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);

View File

@ -3076,6 +3076,10 @@ int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
struct amdgpu_fpriv *fpriv = filp->driver_priv; struct amdgpu_fpriv *fpriv = filp->driver_priv;
int r; int r;
/* No valid flags defined yet */
if (args->in.flags)
return -EINVAL;
switch (args->in.op) { switch (args->in.op) {
case AMDGPU_VM_OP_RESERVE_VMID: case AMDGPU_VM_OP_RESERVE_VMID:
/* current, we only have requirement to reserve vmid from gfxhub */ /* current, we only have requirement to reserve vmid from gfxhub */

View File

@ -101,18 +101,19 @@ static struct kfd_mem_obj *allocate_mqd(struct kfd_dev *kfd,
&(mqd_mem_obj->gtt_mem), &(mqd_mem_obj->gtt_mem),
&(mqd_mem_obj->gpu_addr), &(mqd_mem_obj->gpu_addr),
(void *)&(mqd_mem_obj->cpu_ptr), true); (void *)&(mqd_mem_obj->cpu_ptr), true);
if (retval) {
kfree(mqd_mem_obj);
return NULL;
}
} else { } else {
retval = kfd_gtt_sa_allocate(kfd, sizeof(struct v9_mqd), retval = kfd_gtt_sa_allocate(kfd, sizeof(struct v9_mqd),
&mqd_mem_obj); &mqd_mem_obj);
} if (retval)
return NULL;
if (retval) {
kfree(mqd_mem_obj);
return NULL;
} }
return mqd_mem_obj; return mqd_mem_obj;
} }
static void init_mqd(struct mqd_manager *mm, void **mqd, static void init_mqd(struct mqd_manager *mm, void **mqd,

View File

@ -97,6 +97,12 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
if (!state->planes) if (!state->planes)
goto fail; goto fail;
/*
* Because drm_atomic_state can be committed asynchronously we need our
* own reference and cannot rely on the on implied by drm_file in the
* ioctl call.
*/
drm_dev_get(dev);
state->dev = dev; state->dev = dev;
DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state); DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
@ -256,7 +262,8 @@ EXPORT_SYMBOL(drm_atomic_state_clear);
void __drm_atomic_state_free(struct kref *ref) void __drm_atomic_state_free(struct kref *ref)
{ {
struct drm_atomic_state *state = container_of(ref, typeof(*state), ref); struct drm_atomic_state *state = container_of(ref, typeof(*state), ref);
struct drm_mode_config *config = &state->dev->mode_config; struct drm_device *dev = state->dev;
struct drm_mode_config *config = &dev->mode_config;
drm_atomic_state_clear(state); drm_atomic_state_clear(state);
@ -268,6 +275,8 @@ void __drm_atomic_state_free(struct kref *ref)
drm_atomic_state_default_release(state); drm_atomic_state_default_release(state);
kfree(state); kfree(state);
} }
drm_dev_put(dev);
} }
EXPORT_SYMBOL(__drm_atomic_state_free); EXPORT_SYMBOL(__drm_atomic_state_free);

View File

@ -1078,7 +1078,16 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
continue; continue;
ret = drm_crtc_vblank_get(crtc); ret = drm_crtc_vblank_get(crtc);
WARN_ONCE(ret != -EINVAL, "driver forgot to call drm_crtc_vblank_off()\n"); /*
* Self-refresh is not a true "disable"; ensure vblank remains
* enabled.
*/
if (new_crtc_state->self_refresh_active)
WARN_ONCE(ret != 0,
"driver disabled vblank in self-refresh\n");
else
WARN_ONCE(ret != -EINVAL,
"driver forgot to call drm_crtc_vblank_off()\n");
if (ret == 0) if (ret == 0)
drm_crtc_vblank_put(crtc); drm_crtc_vblank_put(crtc);
} }

View File

@ -281,6 +281,9 @@ static bool drm_client_target_cloned(struct drm_device *dev,
can_clone = true; can_clone = true;
dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false); dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false);
if (!dmt_mode)
goto fail;
for (i = 0; i < connector_count; i++) { for (i = 0; i < connector_count; i++) {
if (!enabled[i]) if (!enabled[i])
continue; continue;
@ -296,11 +299,13 @@ static bool drm_client_target_cloned(struct drm_device *dev,
if (!modes[i]) if (!modes[i])
can_clone = false; can_clone = false;
} }
kfree(dmt_mode);
if (can_clone) { if (can_clone) {
DRM_DEBUG_KMS("can clone using 1024x768\n"); DRM_DEBUG_KMS("can clone using 1024x768\n");
return true; return true;
} }
fail:
DRM_INFO("kms: can't enable cloning when we probably wanted to.\n"); DRM_INFO("kms: can't enable cloning when we probably wanted to.\n");
return false; return false;
} }
@ -785,6 +790,7 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width,
break; break;
} }
kfree(modeset->mode);
modeset->mode = drm_mode_duplicate(dev, mode); modeset->mode = drm_mode_duplicate(dev, mode);
drm_connector_get(connector); drm_connector_get(connector);
modeset->connectors[modeset->num_connectors++] = connector; modeset->connectors[modeset->num_connectors++] = connector;

View File

@ -44,14 +44,22 @@ static LIST_HEAD(panel_list);
/** /**
* drm_panel_init - initialize a panel * drm_panel_init - initialize a panel
* @panel: DRM panel * @panel: DRM panel
* @dev: parent device of the panel
* @funcs: panel operations
* @connector_type: the connector type (DRM_MODE_CONNECTOR_*) corresponding to
* the panel interface
* *
* Sets up internal fields of the panel so that it can subsequently be added * Initialize the panel structure for subsequent registration with
* to the registry. * drm_panel_add().
*/ */
void drm_panel_init(struct drm_panel *panel) void drm_panel_init(struct drm_panel *panel, struct device *dev,
const struct drm_panel_funcs *funcs, int connector_type)
{ {
INIT_LIST_HEAD(&panel->list); INIT_LIST_HEAD(&panel->list);
BLOCKING_INIT_NOTIFIER_HEAD(&panel->nh); BLOCKING_INIT_NOTIFIER_HEAD(&panel->nh);
panel->dev = dev;
panel->funcs = funcs;
panel->connector_type = connector_type;
} }
EXPORT_SYMBOL(drm_panel_init); EXPORT_SYMBOL(drm_panel_init);

View File

@ -1926,13 +1926,14 @@ int __intel_wait_for_register_fw(struct intel_uncore *uncore,
unsigned int slow_timeout_ms, unsigned int slow_timeout_ms,
u32 *out_value) u32 *out_value)
{ {
u32 reg_value; u32 reg_value = 0;
#define done (((reg_value = intel_uncore_read_fw(uncore, reg)) & mask) == value) #define done (((reg_value = intel_uncore_read_fw(uncore, reg)) & mask) == value)
int ret; int ret;
/* Catch any overuse of this function */ /* Catch any overuse of this function */
might_sleep_if(slow_timeout_ms); might_sleep_if(slow_timeout_ms);
GEM_BUG_ON(fast_timeout_us > 20000); GEM_BUG_ON(fast_timeout_us > 20000);
GEM_BUG_ON(!fast_timeout_us && !slow_timeout_ms);
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
if (fast_timeout_us && fast_timeout_us <= 20000) if (fast_timeout_us && fast_timeout_us <= 20000)

View File

@ -350,9 +350,8 @@ static int versatile_panel_probe(struct platform_device *pdev)
dev_info(dev, "panel mounted on IB2 daughterboard\n"); dev_info(dev, "panel mounted on IB2 daughterboard\n");
} }
drm_panel_init(&vpanel->panel); drm_panel_init(&vpanel->panel, dev, &versatile_panel_drm_funcs,
vpanel->panel.dev = dev; DRM_MODE_CONNECTOR_DPI);
vpanel->panel.funcs = &versatile_panel_drm_funcs;
return drm_panel_add(&vpanel->panel); return drm_panel_add(&vpanel->panel);
} }

View File

@ -204,9 +204,8 @@ static int feiyang_dsi_probe(struct mipi_dsi_device *dsi)
mipi_dsi_set_drvdata(dsi, ctx); mipi_dsi_set_drvdata(dsi, ctx);
ctx->dsi = dsi; ctx->dsi = dsi;
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, &dsi->dev, &feiyang_funcs,
ctx->panel.dev = &dsi->dev; DRM_MODE_CONNECTOR_DSI);
ctx->panel.funcs = &feiyang_funcs;
ctx->dvdd = devm_regulator_get(&dsi->dev, "dvdd"); ctx->dvdd = devm_regulator_get(&dsi->dev, "dvdd");
if (IS_ERR(ctx->dvdd)) { if (IS_ERR(ctx->dvdd)) {

View File

@ -895,9 +895,8 @@ static int ili9322_probe(struct spi_device *spi)
ili->input = ili->conf->input; ili->input = ili->conf->input;
} }
drm_panel_init(&ili->panel); drm_panel_init(&ili->panel, dev, &ili9322_drm_funcs,
ili->panel.dev = dev; DRM_MODE_CONNECTOR_DPI);
ili->panel.funcs = &ili9322_drm_funcs;
return drm_panel_add(&ili->panel); return drm_panel_add(&ili->panel);
} }

View File

@ -433,9 +433,8 @@ static int ili9881c_dsi_probe(struct mipi_dsi_device *dsi)
mipi_dsi_set_drvdata(dsi, ctx); mipi_dsi_set_drvdata(dsi, ctx);
ctx->dsi = dsi; ctx->dsi = dsi;
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, &dsi->dev, &ili9881c_funcs,
ctx->panel.dev = &dsi->dev; DRM_MODE_CONNECTOR_DSI);
ctx->panel.funcs = &ili9881c_funcs;
ctx->power = devm_regulator_get(&dsi->dev, "power"); ctx->power = devm_regulator_get(&dsi->dev, "power");
if (IS_ERR(ctx->power)) { if (IS_ERR(ctx->power)) {

View File

@ -487,9 +487,8 @@ static int innolux_panel_add(struct mipi_dsi_device *dsi,
if (IS_ERR(innolux->backlight)) if (IS_ERR(innolux->backlight))
return PTR_ERR(innolux->backlight); return PTR_ERR(innolux->backlight);
drm_panel_init(&innolux->base); drm_panel_init(&innolux->base, dev, &innolux_panel_funcs,
innolux->base.funcs = &innolux_panel_funcs; DRM_MODE_CONNECTOR_DSI);
innolux->base.dev = dev;
err = drm_panel_add(&innolux->base); err = drm_panel_add(&innolux->base);
if (err < 0) if (err < 0)

View File

@ -437,9 +437,8 @@ static int jdi_panel_add(struct jdi_panel *jdi)
return ret; return ret;
} }
drm_panel_init(&jdi->base); drm_panel_init(&jdi->base, &jdi->dsi->dev, &jdi_panel_funcs,
jdi->base.funcs = &jdi_panel_funcs; DRM_MODE_CONNECTOR_DSI);
jdi->base.dev = &jdi->dsi->dev;
ret = drm_panel_add(&jdi->base); ret = drm_panel_add(&jdi->base);

View File

@ -391,9 +391,8 @@ static int kingdisplay_panel_add(struct kingdisplay_panel *kingdisplay)
if (IS_ERR(kingdisplay->backlight)) if (IS_ERR(kingdisplay->backlight))
return PTR_ERR(kingdisplay->backlight); return PTR_ERR(kingdisplay->backlight);
drm_panel_init(&kingdisplay->base); drm_panel_init(&kingdisplay->base, &kingdisplay->link->dev,
kingdisplay->base.funcs = &kingdisplay_panel_funcs; &kingdisplay_panel_funcs, DRM_MODE_CONNECTOR_DSI);
kingdisplay->base.dev = &kingdisplay->link->dev;
return drm_panel_add(&kingdisplay->base); return drm_panel_add(&kingdisplay->base);
} }

View File

@ -196,9 +196,8 @@ static int lb035q02_probe(struct spi_device *spi)
if (ret < 0) if (ret < 0)
return ret; return ret;
drm_panel_init(&lcd->panel); drm_panel_init(&lcd->panel, &lcd->spi->dev, &lb035q02_funcs,
lcd->panel.dev = &lcd->spi->dev; DRM_MODE_CONNECTOR_DPI);
lcd->panel.funcs = &lb035q02_funcs;
return drm_panel_add(&lcd->panel); return drm_panel_add(&lcd->panel);
} }

View File

@ -259,9 +259,8 @@ static int lg4573_probe(struct spi_device *spi)
return ret; return ret;
} }
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, &spi->dev, &lg4573_drm_funcs,
ctx->panel.dev = &spi->dev; DRM_MODE_CONNECTOR_DPI);
ctx->panel.funcs = &lg4573_drm_funcs;
return drm_panel_add(&ctx->panel); return drm_panel_add(&ctx->panel);
} }

View File

@ -254,9 +254,8 @@ static int panel_lvds_probe(struct platform_device *pdev)
*/ */
/* Register the panel. */ /* Register the panel. */
drm_panel_init(&lvds->panel); drm_panel_init(&lvds->panel, lvds->dev, &panel_lvds_funcs,
lvds->panel.dev = lvds->dev; DRM_MODE_CONNECTOR_LVDS);
lvds->panel.funcs = &panel_lvds_funcs;
ret = drm_panel_add(&lvds->panel); ret = drm_panel_add(&lvds->panel);
if (ret < 0) if (ret < 0)

View File

@ -205,9 +205,8 @@ static int nl8048_probe(struct spi_device *spi)
if (ret < 0) if (ret < 0)
return ret; return ret;
drm_panel_init(&lcd->panel); drm_panel_init(&lcd->panel, &lcd->spi->dev, &nl8048_funcs,
lcd->panel.dev = &lcd->spi->dev; DRM_MODE_CONNECTOR_DPI);
lcd->panel.funcs = &nl8048_funcs;
return drm_panel_add(&lcd->panel); return drm_panel_add(&lcd->panel);
} }

View File

@ -292,9 +292,8 @@ static int nt39016_probe(struct spi_device *spi)
return err; return err;
} }
drm_panel_init(&panel->drm_panel); drm_panel_init(&panel->drm_panel, dev, &nt39016_funcs,
panel->drm_panel.dev = dev; DRM_MODE_CONNECTOR_DPI);
panel->drm_panel.funcs = &nt39016_funcs;
err = drm_panel_add(&panel->drm_panel); err = drm_panel_add(&panel->drm_panel);
if (err < 0) { if (err < 0) {

View File

@ -288,9 +288,8 @@ static int lcd_olinuxino_probe(struct i2c_client *client,
if (IS_ERR(lcd->backlight)) if (IS_ERR(lcd->backlight))
return PTR_ERR(lcd->backlight); return PTR_ERR(lcd->backlight);
drm_panel_init(&lcd->panel); drm_panel_init(&lcd->panel, dev, &lcd_olinuxino_funcs,
lcd->panel.dev = dev; DRM_MODE_CONNECTOR_DPI);
lcd->panel.funcs = &lcd_olinuxino_funcs;
return drm_panel_add(&lcd->panel); return drm_panel_add(&lcd->panel);
} }

View File

@ -455,9 +455,8 @@ static int otm8009a_probe(struct mipi_dsi_device *dsi)
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
MIPI_DSI_MODE_LPM; MIPI_DSI_MODE_LPM;
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, dev, &otm8009a_drm_funcs,
ctx->panel.dev = dev; DRM_MODE_CONNECTOR_DSI);
ctx->panel.funcs = &otm8009a_drm_funcs;
ctx->bl_dev = devm_backlight_device_register(dev, dev_name(dev), ctx->bl_dev = devm_backlight_device_register(dev, dev_name(dev),
dev, ctx, dev, ctx,

View File

@ -166,9 +166,8 @@ static int osd101t2587_panel_add(struct osd101t2587_panel *osd101t2587)
if (IS_ERR(osd101t2587->backlight)) if (IS_ERR(osd101t2587->backlight))
return PTR_ERR(osd101t2587->backlight); return PTR_ERR(osd101t2587->backlight);
drm_panel_init(&osd101t2587->base); drm_panel_init(&osd101t2587->base, &osd101t2587->dsi->dev,
osd101t2587->base.funcs = &osd101t2587_panel_funcs; &osd101t2587_panel_funcs, DRM_MODE_CONNECTOR_DSI);
osd101t2587->base.dev = &osd101t2587->dsi->dev;
return drm_panel_add(&osd101t2587->base); return drm_panel_add(&osd101t2587->base);
} }

View File

@ -223,9 +223,8 @@ static int wuxga_nt_panel_add(struct wuxga_nt_panel *wuxga_nt)
return -EPROBE_DEFER; return -EPROBE_DEFER;
} }
drm_panel_init(&wuxga_nt->base); drm_panel_init(&wuxga_nt->base, &wuxga_nt->dsi->dev,
wuxga_nt->base.funcs = &wuxga_nt_panel_funcs; &wuxga_nt_panel_funcs, DRM_MODE_CONNECTOR_DSI);
wuxga_nt->base.dev = &wuxga_nt->dsi->dev;
ret = drm_panel_add(&wuxga_nt->base); ret = drm_panel_add(&wuxga_nt->base);
if (ret < 0) if (ret < 0)

View File

@ -433,9 +433,8 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c,
return PTR_ERR(ts->dsi); return PTR_ERR(ts->dsi);
} }
drm_panel_init(&ts->base); drm_panel_init(&ts->base, dev, &rpi_touchscreen_funcs,
ts->base.dev = dev; DRM_MODE_CONNECTOR_DSI);
ts->base.funcs = &rpi_touchscreen_funcs;
/* This appears last, as it's what will unblock the DSI host /* This appears last, as it's what will unblock the DSI host
* driver's component bind function. * driver's component bind function.

View File

@ -606,9 +606,8 @@ static int rad_panel_probe(struct mipi_dsi_device *dsi)
if (ret) if (ret)
return ret; return ret;
drm_panel_init(&panel->panel); drm_panel_init(&panel->panel, dev, &rad_panel_funcs,
panel->panel.funcs = &rad_panel_funcs; DRM_MODE_CONNECTOR_DSI);
panel->panel.dev = dev;
dev_set_drvdata(dev, panel); dev_set_drvdata(dev, panel);
ret = drm_panel_add(&panel->panel); ret = drm_panel_add(&panel->panel);

View File

@ -404,9 +404,8 @@ static int rm68200_probe(struct mipi_dsi_device *dsi)
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
MIPI_DSI_MODE_LPM; MIPI_DSI_MODE_LPM;
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, dev, &rm68200_drm_funcs,
ctx->panel.dev = dev; DRM_MODE_CONNECTOR_DSI);
ctx->panel.funcs = &rm68200_drm_funcs;
drm_panel_add(&ctx->panel); drm_panel_add(&ctx->panel);

View File

@ -343,9 +343,8 @@ static int jh057n_probe(struct mipi_dsi_device *dsi)
return ret; return ret;
} }
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, dev, &jh057n_drm_funcs,
ctx->panel.dev = dev; DRM_MODE_CONNECTOR_DSI);
ctx->panel.funcs = &jh057n_drm_funcs;
drm_panel_add(&ctx->panel); drm_panel_add(&ctx->panel);

View File

@ -173,9 +173,8 @@ static int rb070d30_panel_dsi_probe(struct mipi_dsi_device *dsi)
mipi_dsi_set_drvdata(dsi, ctx); mipi_dsi_set_drvdata(dsi, ctx);
ctx->dsi = dsi; ctx->dsi = dsi;
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, &dsi->dev, &rb070d30_panel_funcs,
ctx->panel.dev = &dsi->dev; DRM_MODE_CONNECTOR_DSI);
ctx->panel.funcs = &rb070d30_panel_funcs;
ctx->gpios.reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW); ctx->gpios.reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(ctx->gpios.reset)) { if (IS_ERR(ctx->gpios.reset)) {

View File

@ -351,9 +351,8 @@ static int ld9040_probe(struct spi_device *spi)
return ret; return ret;
} }
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, dev, &ld9040_drm_funcs,
ctx->panel.dev = dev; DRM_MODE_CONNECTOR_DPI);
ctx->panel.funcs = &ld9040_drm_funcs;
return drm_panel_add(&ctx->panel); return drm_panel_add(&ctx->panel);
} }

View File

@ -215,9 +215,8 @@ static int s6d16d0_probe(struct mipi_dsi_device *dsi)
return ret; return ret;
} }
drm_panel_init(&s6->panel); drm_panel_init(&s6->panel, dev, &s6d16d0_drm_funcs,
s6->panel.dev = dev; DRM_MODE_CONNECTOR_DSI);
s6->panel.funcs = &s6d16d0_drm_funcs;
ret = drm_panel_add(&s6->panel); ret = drm_panel_add(&s6->panel);
if (ret < 0) if (ret < 0)

View File

@ -732,9 +732,8 @@ static int s6e3ha2_probe(struct mipi_dsi_device *dsi)
ctx->bl_dev->props.brightness = S6E3HA2_DEFAULT_BRIGHTNESS; ctx->bl_dev->props.brightness = S6E3HA2_DEFAULT_BRIGHTNESS;
ctx->bl_dev->props.power = FB_BLANK_POWERDOWN; ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, dev, &s6e3ha2_drm_funcs,
ctx->panel.dev = dev; DRM_MODE_CONNECTOR_DSI);
ctx->panel.funcs = &s6e3ha2_drm_funcs;
ret = drm_panel_add(&ctx->panel); ret = drm_panel_add(&ctx->panel);
if (ret < 0) if (ret < 0)

View File

@ -466,9 +466,8 @@ static int s6e63j0x03_probe(struct mipi_dsi_device *dsi)
return PTR_ERR(ctx->reset_gpio); return PTR_ERR(ctx->reset_gpio);
} }
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, dev, &s6e63j0x03_funcs,
ctx->panel.dev = dev; DRM_MODE_CONNECTOR_DSI);
ctx->panel.funcs = &s6e63j0x03_funcs;
ctx->bl_dev = backlight_device_register("s6e63j0x03", dev, ctx, ctx->bl_dev = backlight_device_register("s6e63j0x03", dev, ctx,
&s6e63j0x03_bl_ops, NULL); &s6e63j0x03_bl_ops, NULL);

View File

@ -473,9 +473,8 @@ static int s6e63m0_probe(struct spi_device *spi)
return ret; return ret;
} }
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, dev, &s6e63m0_drm_funcs,
ctx->panel.dev = dev; DRM_MODE_CONNECTOR_DPI);
ctx->panel.funcs = &s6e63m0_drm_funcs;
ret = s6e63m0_backlight_register(ctx); ret = s6e63m0_backlight_register(ctx);
if (ret < 0) if (ret < 0)

View File

@ -1017,9 +1017,8 @@ static int s6e8aa0_probe(struct mipi_dsi_device *dsi)
ctx->brightness = GAMMA_LEVEL_NUM - 1; ctx->brightness = GAMMA_LEVEL_NUM - 1;
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, dev, &s6e8aa0_drm_funcs,
ctx->panel.dev = dev; DRM_MODE_CONNECTOR_DSI);
ctx->panel.funcs = &s6e8aa0_drm_funcs;
ret = drm_panel_add(&ctx->panel); ret = drm_panel_add(&ctx->panel);
if (ret < 0) if (ret < 0)

View File

@ -274,9 +274,8 @@ static int seiko_panel_probe(struct device *dev,
return -EPROBE_DEFER; return -EPROBE_DEFER;
} }
drm_panel_init(&panel->base); drm_panel_init(&panel->base, dev, &seiko_panel_funcs,
panel->base.dev = dev; DRM_MODE_CONNECTOR_DPI);
panel->base.funcs = &seiko_panel_funcs;
err = drm_panel_add(&panel->base); err = drm_panel_add(&panel->base);
if (err < 0) if (err < 0)

View File

@ -329,9 +329,8 @@ static int sharp_panel_add(struct sharp_panel *sharp)
if (IS_ERR(sharp->backlight)) if (IS_ERR(sharp->backlight))
return PTR_ERR(sharp->backlight); return PTR_ERR(sharp->backlight);
drm_panel_init(&sharp->base); drm_panel_init(&sharp->base, &sharp->link1->dev, &sharp_panel_funcs,
sharp->base.funcs = &sharp_panel_funcs; DRM_MODE_CONNECTOR_DSI);
sharp->base.dev = &sharp->link1->dev;
return drm_panel_add(&sharp->base); return drm_panel_add(&sharp->base);
} }

View File

@ -185,9 +185,8 @@ static int ls037v7dw01_probe(struct platform_device *pdev)
return PTR_ERR(lcd->ud_gpio); return PTR_ERR(lcd->ud_gpio);
} }
drm_panel_init(&lcd->panel); drm_panel_init(&lcd->panel, &pdev->dev, &ls037v7dw01_funcs,
lcd->panel.dev = &pdev->dev; DRM_MODE_CONNECTOR_DPI);
lcd->panel.funcs = &ls037v7dw01_funcs;
return drm_panel_add(&lcd->panel); return drm_panel_add(&lcd->panel);
} }

View File

@ -264,9 +264,8 @@ static int sharp_nt_panel_add(struct sharp_nt_panel *sharp_nt)
if (IS_ERR(sharp_nt->backlight)) if (IS_ERR(sharp_nt->backlight))
return PTR_ERR(sharp_nt->backlight); return PTR_ERR(sharp_nt->backlight);
drm_panel_init(&sharp_nt->base); drm_panel_init(&sharp_nt->base, &sharp_nt->dsi->dev,
sharp_nt->base.funcs = &sharp_nt_panel_funcs; &sharp_nt_panel_funcs, DRM_MODE_CONNECTOR_DSI);
sharp_nt->base.dev = &sharp_nt->dsi->dev;
return drm_panel_add(&sharp_nt->base); return drm_panel_add(&sharp_nt->base);
} }

View File

@ -94,6 +94,7 @@ struct panel_desc {
u32 bus_format; u32 bus_format;
u32 bus_flags; u32 bus_flags;
int connector_type;
}; };
struct panel_simple { struct panel_simple {
@ -464,9 +465,8 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
if (!of_get_display_timing(dev->of_node, "panel-timing", &dt)) if (!of_get_display_timing(dev->of_node, "panel-timing", &dt))
panel_simple_parse_panel_timing_node(dev, panel, &dt); panel_simple_parse_panel_timing_node(dev, panel, &dt);
drm_panel_init(&panel->base); drm_panel_init(&panel->base, dev, &panel_simple_funcs,
panel->base.dev = dev; desc->connector_type);
panel->base.funcs = &panel_simple_funcs;
err = drm_panel_add(&panel->base); err = drm_panel_add(&panel->base);
if (err < 0) if (err < 0)
@ -531,8 +531,8 @@ static const struct panel_desc ampire_am_480272h3tmqw_t01h = {
.num_modes = 1, .num_modes = 1,
.bpc = 8, .bpc = 8,
.size = { .size = {
.width = 105, .width = 99,
.height = 67, .height = 58,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X24, .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
}; };
@ -833,6 +833,7 @@ static const struct panel_desc auo_g133han01 = {
.unprepare = 1000, .unprepare = 1000,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct display_timing auo_g185han01_timings = { static const struct display_timing auo_g185han01_timings = {
@ -862,6 +863,7 @@ static const struct panel_desc auo_g185han01 = {
.unprepare = 1000, .unprepare = 1000,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct display_timing auo_p320hvn03_timings = { static const struct display_timing auo_p320hvn03_timings = {
@ -890,6 +892,7 @@ static const struct panel_desc auo_p320hvn03 = {
.unprepare = 500, .unprepare = 500,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct drm_display_mode auo_t215hvn01_mode = { static const struct drm_display_mode auo_t215hvn01_mode = {
@ -1205,6 +1208,7 @@ static const struct panel_desc dlc_dlc0700yzg_1 = {
.disable = 200, .disable = 200,
}, },
.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct display_timing dlc_dlc1010gig_timing = { static const struct display_timing dlc_dlc1010gig_timing = {
@ -1235,6 +1239,7 @@ static const struct panel_desc dlc_dlc1010gig = {
.unprepare = 60, .unprepare = 60,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct drm_display_mode edt_et035012dm6_mode = { static const struct drm_display_mode edt_et035012dm6_mode = {
@ -1501,6 +1506,7 @@ static const struct panel_desc hannstar_hsd070pww1 = {
.height = 94, .height = 94,
}, },
.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct display_timing hannstar_hsd100pxn1_timing = { static const struct display_timing hannstar_hsd100pxn1_timing = {
@ -1525,6 +1531,7 @@ static const struct panel_desc hannstar_hsd100pxn1 = {
.height = 152, .height = 152,
}, },
.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct drm_display_mode hitachi_tx23d38vm0caa_mode = { static const struct drm_display_mode hitachi_tx23d38vm0caa_mode = {
@ -1577,6 +1584,7 @@ static const struct panel_desc innolux_at043tn24 = {
.height = 54, .height = 54,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X24, .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
.connector_type = DRM_MODE_CONNECTOR_DPI,
.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
}; };
@ -1631,6 +1639,7 @@ static const struct panel_desc innolux_g070y2_l01 = {
.unprepare = 800, .unprepare = 800,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct display_timing innolux_g101ice_l01_timing = { static const struct display_timing innolux_g101ice_l01_timing = {
@ -1659,6 +1668,7 @@ static const struct panel_desc innolux_g101ice_l01 = {
.disable = 200, .disable = 200,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct display_timing innolux_g121i1_l01_timing = { static const struct display_timing innolux_g121i1_l01_timing = {
@ -1686,6 +1696,7 @@ static const struct panel_desc innolux_g121i1_l01 = {
.disable = 20, .disable = 20,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct drm_display_mode innolux_g121x1_l03_mode = { static const struct drm_display_mode innolux_g121x1_l03_mode = {
@ -1869,6 +1880,7 @@ static const struct panel_desc koe_tx31d200vm0baa = {
.height = 109, .height = 109,
}, },
.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct display_timing kyo_tcg121xglp_timing = { static const struct display_timing kyo_tcg121xglp_timing = {
@ -1893,6 +1905,7 @@ static const struct panel_desc kyo_tcg121xglp = {
.height = 184, .height = 184,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct drm_display_mode lemaker_bl035_rgb_002_mode = { static const struct drm_display_mode lemaker_bl035_rgb_002_mode = {
@ -1941,6 +1954,7 @@ static const struct panel_desc lg_lb070wv8 = {
.height = 91, .height = 91,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct drm_display_mode lg_lp079qx1_sp0v_mode = { static const struct drm_display_mode lg_lp079qx1_sp0v_mode = {
@ -2097,6 +2111,7 @@ static const struct panel_desc mitsubishi_aa070mc01 = {
.disable = 400, .disable = 400,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
.bus_flags = DRM_BUS_FLAG_DE_HIGH, .bus_flags = DRM_BUS_FLAG_DE_HIGH,
}; };
@ -2125,6 +2140,7 @@ static const struct panel_desc nec_nl12880bc20_05 = {
.disable = 50, .disable = 50,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct drm_display_mode nec_nl4827hc19_05b_mode = { static const struct drm_display_mode nec_nl4827hc19_05b_mode = {
@ -2227,6 +2243,7 @@ static const struct panel_desc nlt_nl192108ac18_02d = {
.unprepare = 500, .unprepare = 500,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct drm_display_mode nvd_9128_mode = { static const struct drm_display_mode nvd_9128_mode = {
@ -2250,6 +2267,7 @@ static const struct panel_desc nvd_9128 = {
.height = 88, .height = 88,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct display_timing okaya_rs800480t_7x0gp_timing = { static const struct display_timing okaya_rs800480t_7x0gp_timing = {
@ -2662,6 +2680,7 @@ static const struct panel_desc sharp_lq101k1ly04 = {
.height = 136, .height = 136,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct display_timing sharp_lq123p1jx31_timing = { static const struct display_timing sharp_lq123p1jx31_timing = {
@ -2841,6 +2860,7 @@ static const struct panel_desc tianma_tm070jdhg30 = {
.height = 95, .height = 95,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct display_timing tianma_tm070rvhg71_timing = { static const struct display_timing tianma_tm070rvhg71_timing = {
@ -2865,6 +2885,7 @@ static const struct panel_desc tianma_tm070rvhg71 = {
.height = 86, .height = 86,
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct drm_display_mode ti_nspire_cx_lcd_mode[] = { static const struct drm_display_mode ti_nspire_cx_lcd_mode[] = {
@ -2947,6 +2968,7 @@ static const struct panel_desc toshiba_lt089ac29000 = {
}, },
.bus_format = MEDIA_BUS_FMT_RGB888_1X24, .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct drm_display_mode tpk_f07a_0102_mode = { static const struct drm_display_mode tpk_f07a_0102_mode = {
@ -3017,6 +3039,7 @@ static const struct panel_desc urt_umsh_8596md_lvds = {
.height = 91, .height = 91,
}, },
.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct panel_desc urt_umsh_8596md_parallel = { static const struct panel_desc urt_umsh_8596md_parallel = {

View File

@ -369,7 +369,8 @@ static int st7701_dsi_probe(struct mipi_dsi_device *dsi)
if (IS_ERR(st7701->backlight)) if (IS_ERR(st7701->backlight))
return PTR_ERR(st7701->backlight); return PTR_ERR(st7701->backlight);
drm_panel_init(&st7701->panel); drm_panel_init(&st7701->panel, &dsi->dev, &st7701_funcs,
DRM_MODE_CONNECTOR_DSI);
/** /**
* Once sleep out has been issued, ST7701 IC required to wait 120ms * Once sleep out has been issued, ST7701 IC required to wait 120ms
@ -381,8 +382,6 @@ static int st7701_dsi_probe(struct mipi_dsi_device *dsi)
* ts8550b and there is no valid documentation for that. * ts8550b and there is no valid documentation for that.
*/ */
st7701->sleep_delay = 120 + desc->panel_sleep_delay; st7701->sleep_delay = 120 + desc->panel_sleep_delay;
st7701->panel.funcs = &st7701_funcs;
st7701->panel.dev = &dsi->dev;
ret = drm_panel_add(&st7701->panel); ret = drm_panel_add(&st7701->panel);
if (ret < 0) if (ret < 0)

View File

@ -381,9 +381,8 @@ static int st7789v_probe(struct spi_device *spi)
spi_set_drvdata(spi, ctx); spi_set_drvdata(spi, ctx);
ctx->spi = spi; ctx->spi = spi;
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, &spi->dev, &st7789v_drm_funcs,
ctx->panel.dev = &spi->dev; DRM_MODE_CONNECTOR_DPI);
ctx->panel.funcs = &st7789v_drm_funcs;
ctx->power = devm_regulator_get(&spi->dev, "power"); ctx->power = devm_regulator_get(&spi->dev, "power");
if (IS_ERR(ctx->power)) if (IS_ERR(ctx->power))

View File

@ -648,9 +648,8 @@ static int acx565akm_probe(struct spi_device *spi)
return ret; return ret;
} }
drm_panel_init(&lcd->panel); drm_panel_init(&lcd->panel, &lcd->spi->dev, &acx565akm_funcs,
lcd->panel.dev = &lcd->spi->dev; DRM_MODE_CONNECTOR_DPI);
lcd->panel.funcs = &acx565akm_funcs;
ret = drm_panel_add(&lcd->panel); ret = drm_panel_add(&lcd->panel);
if (ret < 0) { if (ret < 0) {

View File

@ -347,9 +347,8 @@ static int td028ttec1_probe(struct spi_device *spi)
return ret; return ret;
} }
drm_panel_init(&lcd->panel); drm_panel_init(&lcd->panel, &lcd->spi->dev, &td028ttec1_funcs,
lcd->panel.dev = &lcd->spi->dev; DRM_MODE_CONNECTOR_DPI);
lcd->panel.funcs = &td028ttec1_funcs;
return drm_panel_add(&lcd->panel); return drm_panel_add(&lcd->panel);
} }

View File

@ -458,9 +458,8 @@ static int td043mtea1_probe(struct spi_device *spi)
return ret; return ret;
} }
drm_panel_init(&lcd->panel); drm_panel_init(&lcd->panel, &lcd->spi->dev, &td043mtea1_funcs,
lcd->panel.dev = &lcd->spi->dev; DRM_MODE_CONNECTOR_DPI);
lcd->panel.funcs = &td043mtea1_funcs;
ret = drm_panel_add(&lcd->panel); ret = drm_panel_add(&lcd->panel);
if (ret < 0) { if (ret < 0) {

View File

@ -457,9 +457,8 @@ static int tpg110_probe(struct spi_device *spi)
if (ret) if (ret)
return ret; return ret;
drm_panel_init(&tpg->panel); drm_panel_init(&tpg->panel, dev, &tpg110_drm_funcs,
tpg->panel.dev = dev; DRM_MODE_CONNECTOR_DPI);
tpg->panel.funcs = &tpg110_drm_funcs;
spi_set_drvdata(spi, tpg); spi_set_drvdata(spi, tpg);
return drm_panel_add(&tpg->panel); return drm_panel_add(&tpg->panel);

View File

@ -518,9 +518,8 @@ static int truly_nt35597_panel_add(struct truly_nt35597 *ctx)
/* dual port */ /* dual port */
gpiod_set_value(ctx->mode_gpio, 0); gpiod_set_value(ctx->mode_gpio, 0);
drm_panel_init(&ctx->panel); drm_panel_init(&ctx->panel, dev, &truly_nt35597_drm_funcs,
ctx->panel.dev = dev; DRM_MODE_CONNECTOR_DSI);
ctx->panel.funcs = &truly_nt35597_drm_funcs;
drm_panel_add(&ctx->panel); drm_panel_add(&ctx->panel);
return 0; return 0;

View File

@ -5556,6 +5556,7 @@ static int ci_parse_power_table(struct radeon_device *rdev)
u8 frev, crev; u8 frev, crev;
u8 *power_state_offset; u8 *power_state_offset;
struct ci_ps *ps; struct ci_ps *ps;
int ret;
if (!atom_parse_data_header(mode_info->atom_context, index, NULL, if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
&frev, &crev, &data_offset)) &frev, &crev, &data_offset))
@ -5585,11 +5586,15 @@ static int ci_parse_power_table(struct radeon_device *rdev)
non_clock_array_index = power_state->v2.nonClockInfoIndex; non_clock_array_index = power_state->v2.nonClockInfoIndex;
non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
&non_clock_info_array->nonClockInfo[non_clock_array_index]; &non_clock_info_array->nonClockInfo[non_clock_array_index];
if (!rdev->pm.power_state[i].clock_info) if (!rdev->pm.power_state[i].clock_info) {
return -EINVAL; ret = -EINVAL;
goto err_free_ps;
}
ps = kzalloc(sizeof(struct ci_ps), GFP_KERNEL); ps = kzalloc(sizeof(struct ci_ps), GFP_KERNEL);
if (ps == NULL) if (ps == NULL) {
return -ENOMEM; ret = -ENOMEM;
goto err_free_ps;
}
rdev->pm.dpm.ps[i].ps_priv = ps; rdev->pm.dpm.ps[i].ps_priv = ps;
ci_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i], ci_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
non_clock_info, non_clock_info,
@ -5629,6 +5634,12 @@ static int ci_parse_power_table(struct radeon_device *rdev)
} }
return 0; return 0;
err_free_ps:
for (i = 0; i < rdev->pm.dpm.num_ps; i++)
kfree(rdev->pm.dpm.ps[i].ps_priv);
kfree(rdev->pm.dpm.ps);
return ret;
} }
static int ci_get_vbios_boot_values(struct radeon_device *rdev, static int ci_get_vbios_boot_values(struct radeon_device *rdev,
@ -5717,25 +5728,26 @@ int ci_dpm_init(struct radeon_device *rdev)
ret = ci_get_vbios_boot_values(rdev, &pi->vbios_boot_state); ret = ci_get_vbios_boot_values(rdev, &pi->vbios_boot_state);
if (ret) { if (ret) {
ci_dpm_fini(rdev); kfree(rdev->pm.dpm.priv);
return ret; return ret;
} }
ret = r600_get_platform_caps(rdev); ret = r600_get_platform_caps(rdev);
if (ret) { if (ret) {
ci_dpm_fini(rdev); kfree(rdev->pm.dpm.priv);
return ret; return ret;
} }
ret = r600_parse_extended_power_table(rdev); ret = r600_parse_extended_power_table(rdev);
if (ret) { if (ret) {
ci_dpm_fini(rdev); kfree(rdev->pm.dpm.priv);
return ret; return ret;
} }
ret = ci_parse_power_table(rdev); ret = ci_parse_power_table(rdev);
if (ret) { if (ret) {
ci_dpm_fini(rdev); kfree(rdev->pm.dpm.priv);
r600_free_extended_power_table(rdev);
return ret; return ret;
} }

View File

@ -559,8 +559,12 @@ static int cypress_populate_mclk_value(struct radeon_device *rdev,
ASIC_INTERNAL_MEMORY_SS, vco_freq)) { ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
u32 reference_clock = rdev->clock.mpll.reference_freq; u32 reference_clock = rdev->clock.mpll.reference_freq;
u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); u32 clk_s, clk_v;
u32 clk_v = ss.percentage *
if (!decoded_ref)
return -EINVAL;
clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
clk_v = ss.percentage *
(0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625); (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
mpll_ss1 &= ~CLKV_MASK; mpll_ss1 &= ~CLKV_MASK;

View File

@ -2241,8 +2241,12 @@ static int ni_populate_mclk_value(struct radeon_device *rdev,
ASIC_INTERNAL_MEMORY_SS, vco_freq)) { ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
u32 reference_clock = rdev->clock.mpll.reference_freq; u32 reference_clock = rdev->clock.mpll.reference_freq;
u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); u32 clk_s, clk_v;
u32 clk_v = ss.percentage *
if (!decoded_ref)
return -EINVAL;
clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
clk_v = ss.percentage *
(0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625); (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
mpll_ss1 &= ~CLKV_MASK; mpll_ss1 &= ~CLKV_MASK;

View File

@ -250,8 +250,12 @@ int rv740_populate_mclk_value(struct radeon_device *rdev,
ASIC_INTERNAL_MEMORY_SS, vco_freq)) { ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
u32 reference_clock = rdev->clock.mpll.reference_freq; u32 reference_clock = rdev->clock.mpll.reference_freq;
u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); u32 clk_s, clk_v;
u32 clk_v = 0x40000 * ss.percentage *
if (!decoded_ref)
return -EINVAL;
clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
clk_v = 0x40000 * ss.percentage *
(dividers.whole_fb_div + (dividers.frac_fb_div / 8)) / (clk_s * 10000); (dividers.whole_fb_div + (dividers.frac_fb_div / 8)) / (clk_s * 10000);
mpll_ss1 &= ~CLKV_MASK; mpll_ss1 &= ~CLKV_MASK;

View File

@ -654,13 +654,13 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
if (crtc->state->self_refresh_active) if (crtc->state->self_refresh_active)
rockchip_drm_set_win_enabled(crtc, false); rockchip_drm_set_win_enabled(crtc, false);
if (crtc->state->self_refresh_active)
goto out;
mutex_lock(&vop->vop_lock); mutex_lock(&vop->vop_lock);
drm_crtc_vblank_off(crtc); drm_crtc_vblank_off(crtc);
if (crtc->state->self_refresh_active)
goto out;
/* /*
* Vop standby will take effect at end of current frame, * Vop standby will take effect at end of current frame,
* if dsp hold valid irq happen, it means standby complete. * if dsp hold valid irq happen, it means standby complete.
@ -692,9 +692,9 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
vop_core_clks_disable(vop); vop_core_clks_disable(vop);
pm_runtime_put(vop->dev); pm_runtime_put(vop->dev);
out:
mutex_unlock(&vop->vop_lock); mutex_unlock(&vop->vop_lock);
out:
if (crtc->state->event && !crtc->state->active) { if (crtc->state->event && !crtc->state->active) {
spin_lock_irq(&crtc->dev->event_lock); spin_lock_irq(&crtc->dev->event_lock);
drm_crtc_send_vblank_event(crtc, crtc->state->event); drm_crtc_send_vblank_event(crtc, crtc->state->event);

View File

@ -753,21 +753,19 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private)
static int sun4i_tcon_init_clocks(struct device *dev, static int sun4i_tcon_init_clocks(struct device *dev,
struct sun4i_tcon *tcon) struct sun4i_tcon *tcon)
{ {
tcon->clk = devm_clk_get(dev, "ahb"); tcon->clk = devm_clk_get_enabled(dev, "ahb");
if (IS_ERR(tcon->clk)) { if (IS_ERR(tcon->clk)) {
dev_err(dev, "Couldn't get the TCON bus clock\n"); dev_err(dev, "Couldn't get the TCON bus clock\n");
return PTR_ERR(tcon->clk); return PTR_ERR(tcon->clk);
} }
clk_prepare_enable(tcon->clk);
if (tcon->quirks->has_channel_0) { if (tcon->quirks->has_channel_0) {
tcon->sclk0 = devm_clk_get(dev, "tcon-ch0"); tcon->sclk0 = devm_clk_get_enabled(dev, "tcon-ch0");
if (IS_ERR(tcon->sclk0)) { if (IS_ERR(tcon->sclk0)) {
dev_err(dev, "Couldn't get the TCON channel 0 clock\n"); dev_err(dev, "Couldn't get the TCON channel 0 clock\n");
return PTR_ERR(tcon->sclk0); return PTR_ERR(tcon->sclk0);
} }
} }
clk_prepare_enable(tcon->sclk0);
if (tcon->quirks->has_channel_1) { if (tcon->quirks->has_channel_1) {
tcon->sclk1 = devm_clk_get(dev, "tcon-ch1"); tcon->sclk1 = devm_clk_get(dev, "tcon-ch1");
@ -780,12 +778,6 @@ static int sun4i_tcon_init_clocks(struct device *dev,
return 0; return 0;
} }
static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon)
{
clk_disable_unprepare(tcon->sclk0);
clk_disable_unprepare(tcon->clk);
}
static int sun4i_tcon_init_irq(struct device *dev, static int sun4i_tcon_init_irq(struct device *dev,
struct sun4i_tcon *tcon) struct sun4i_tcon *tcon)
{ {
@ -1202,14 +1194,14 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
ret = sun4i_tcon_init_regmap(dev, tcon); ret = sun4i_tcon_init_regmap(dev, tcon);
if (ret) { if (ret) {
dev_err(dev, "Couldn't init our TCON regmap\n"); dev_err(dev, "Couldn't init our TCON regmap\n");
goto err_free_clocks; goto err_assert_reset;
} }
if (tcon->quirks->has_channel_0) { if (tcon->quirks->has_channel_0) {
ret = sun4i_dclk_create(dev, tcon); ret = sun4i_dclk_create(dev, tcon);
if (ret) { if (ret) {
dev_err(dev, "Couldn't create our TCON dot clock\n"); dev_err(dev, "Couldn't create our TCON dot clock\n");
goto err_free_clocks; goto err_assert_reset;
} }
} }
@ -1272,8 +1264,6 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
err_free_dotclock: err_free_dotclock:
if (tcon->quirks->has_channel_0) if (tcon->quirks->has_channel_0)
sun4i_dclk_free(tcon); sun4i_dclk_free(tcon);
err_free_clocks:
sun4i_tcon_free_clocks(tcon);
err_assert_reset: err_assert_reset:
reset_control_assert(tcon->lcd_rst); reset_control_assert(tcon->lcd_rst);
return ret; return ret;
@ -1287,7 +1277,6 @@ static void sun4i_tcon_unbind(struct device *dev, struct device *master,
list_del(&tcon->list); list_del(&tcon->list);
if (tcon->quirks->has_channel_0) if (tcon->quirks->has_channel_0)
sun4i_dclk_free(tcon); sun4i_dclk_free(tcon);
sun4i_tcon_free_clocks(tcon);
} }
static const struct component_ops sun4i_tcon_ops = { static const struct component_ops sun4i_tcon_ops = {

View File

@ -1307,7 +1307,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
struct input_dev *pen_input = wacom->pen_input; struct input_dev *pen_input = wacom->pen_input;
unsigned char *data = wacom->data; unsigned char *data = wacom->data;
int number_of_valid_frames = 0; int number_of_valid_frames = 0;
int time_interval = 15000000; ktime_t time_interval = 15000000;
ktime_t time_packet_received = ktime_get(); ktime_t time_packet_received = ktime_get();
int i; int i;
@ -1341,7 +1341,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
if (number_of_valid_frames) { if (number_of_valid_frames) {
if (wacom->hid_data.time_delayed) if (wacom->hid_data.time_delayed)
time_interval = ktime_get() - wacom->hid_data.time_delayed; time_interval = ktime_get() - wacom->hid_data.time_delayed;
time_interval /= number_of_valid_frames; time_interval = div_u64(time_interval, number_of_valid_frames);
wacom->hid_data.time_delayed = time_packet_received; wacom->hid_data.time_delayed = time_packet_received;
} }
@ -1352,7 +1352,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
bool range = frame[0] & 0x20; bool range = frame[0] & 0x20;
bool invert = frame[0] & 0x10; bool invert = frame[0] & 0x10;
int frames_number_reversed = number_of_valid_frames - i - 1; int frames_number_reversed = number_of_valid_frames - i - 1;
int event_timestamp = time_packet_received - frames_number_reversed * time_interval; ktime_t event_timestamp = time_packet_received - frames_number_reversed * time_interval;
if (!valid) if (!valid)
continue; continue;

View File

@ -320,7 +320,7 @@ struct hid_data {
int bat_connected; int bat_connected;
int ps_connected; int ps_connected;
bool pad_input_event_flag; bool pad_input_event_flag;
int time_delayed; ktime_t time_delayed;
}; };
struct wacom_remote_data { struct wacom_remote_data {

View File

@ -353,6 +353,9 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
struct xiic_i2c *i2c = dev_id; struct xiic_i2c *i2c = dev_id;
u32 pend, isr, ier; u32 pend, isr, ier;
u32 clr = 0; u32 clr = 0;
int xfer_more = 0;
int wakeup_req = 0;
int wakeup_code = 0;
/* Get the interrupt Status from the IPIF. There is no clearing of /* Get the interrupt Status from the IPIF. There is no clearing of
* interrupts in the IPIF. Interrupts must be cleared at the source. * interrupts in the IPIF. Interrupts must be cleared at the source.
@ -389,10 +392,16 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
*/ */
xiic_reinit(i2c); xiic_reinit(i2c);
if (i2c->rx_msg) if (i2c->rx_msg) {
xiic_wakeup(i2c, STATE_ERROR); wakeup_req = 1;
if (i2c->tx_msg) wakeup_code = STATE_ERROR;
xiic_wakeup(i2c, STATE_ERROR); }
if (i2c->tx_msg) {
wakeup_req = 1;
wakeup_code = STATE_ERROR;
}
/* don't try to handle other events */
goto out;
} }
if (pend & XIIC_INTR_RX_FULL_MASK) { if (pend & XIIC_INTR_RX_FULL_MASK) {
/* Receive register/FIFO is full */ /* Receive register/FIFO is full */
@ -426,8 +435,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
i2c->tx_msg++; i2c->tx_msg++;
dev_dbg(i2c->adap.dev.parent, dev_dbg(i2c->adap.dev.parent,
"%s will start next...\n", __func__); "%s will start next...\n", __func__);
xfer_more = 1;
__xiic_start_xfer(i2c);
} }
} }
} }
@ -441,11 +449,13 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
if (!i2c->tx_msg) if (!i2c->tx_msg)
goto out; goto out;
if ((i2c->nmsgs == 1) && !i2c->rx_msg && wakeup_req = 1;
xiic_tx_space(i2c) == 0)
xiic_wakeup(i2c, STATE_DONE); if (i2c->nmsgs == 1 && !i2c->rx_msg &&
xiic_tx_space(i2c) == 0)
wakeup_code = STATE_DONE;
else else
xiic_wakeup(i2c, STATE_ERROR); wakeup_code = STATE_ERROR;
} }
if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) { if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) {
/* Transmit register/FIFO is empty or ½ empty */ /* Transmit register/FIFO is empty or ½ empty */
@ -469,7 +479,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
if (i2c->nmsgs > 1) { if (i2c->nmsgs > 1) {
i2c->nmsgs--; i2c->nmsgs--;
i2c->tx_msg++; i2c->tx_msg++;
__xiic_start_xfer(i2c); xfer_more = 1;
} else { } else {
xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK); xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
@ -487,6 +497,13 @@ out:
dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr); dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);
xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr); xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr);
if (xfer_more)
__xiic_start_xfer(i2c);
if (wakeup_req)
xiic_wakeup(i2c, wakeup_code);
WARN_ON(xfer_more && wakeup_req);
mutex_unlock(&i2c->lock); mutex_unlock(&i2c->lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View File

@ -71,7 +71,7 @@
#define MESON_SAR_ADC_REG3_PANEL_DETECT_COUNT_MASK GENMASK(20, 18) #define MESON_SAR_ADC_REG3_PANEL_DETECT_COUNT_MASK GENMASK(20, 18)
#define MESON_SAR_ADC_REG3_PANEL_DETECT_FILTER_TB_MASK GENMASK(17, 16) #define MESON_SAR_ADC_REG3_PANEL_DETECT_FILTER_TB_MASK GENMASK(17, 16)
#define MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT 10 #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT 10
#define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 5 #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 6
#define MESON_SAR_ADC_REG3_BLOCK_DLY_SEL_MASK GENMASK(9, 8) #define MESON_SAR_ADC_REG3_BLOCK_DLY_SEL_MASK GENMASK(9, 8)
#define MESON_SAR_ADC_REG3_BLOCK_DLY_MASK GENMASK(7, 0) #define MESON_SAR_ADC_REG3_BLOCK_DLY_MASK GENMASK(7, 0)

View File

@ -2606,11 +2606,8 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq,
qp = (struct bnxt_qplib_qp *)((unsigned long) qp = (struct bnxt_qplib_qp *)((unsigned long)
le64_to_cpu(hwcqe->qp_handle)); le64_to_cpu(hwcqe->qp_handle));
if (!qp) { if (!qp)
dev_err(&cq->hwq.pdev->dev,
"FP: CQ Process terminal qp is NULL\n");
return -EINVAL; return -EINVAL;
}
/* Must block new posting of SQ and RQ */ /* Must block new posting of SQ and RQ */
qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;

Some files were not shown because too many files have changed in this diff Show More