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:
commit
34df0a4c54
@ -22,12 +22,11 @@ exclusive.
|
||||
3) object removal. Locking rules: caller locks parent, finds victim,
|
||||
locks victim and calls the method. Locks are exclusive.
|
||||
|
||||
4) rename() that is _not_ cross-directory. Locking rules: caller locks
|
||||
the parent and finds source and target. In case of exchange (with
|
||||
RENAME_EXCHANGE in flags argument) lock both. In any case,
|
||||
if the target already exists, lock it. If the source is a non-directory,
|
||||
lock it. If we need to lock both, lock them in inode pointer order.
|
||||
Then call the method. All locks are exclusive.
|
||||
4) rename() that is _not_ cross-directory. Locking rules: caller locks the
|
||||
parent and finds source and target. We lock both (provided they exist). If we
|
||||
need to lock two inodes of different type (dir vs non-dir), we lock directory
|
||||
first. If we need to lock two inodes of the same type, lock them in inode
|
||||
pointer order. Then call the method. All locks are exclusive.
|
||||
NB: we might get away with locking the the source (and target in exchange
|
||||
case) shared.
|
||||
|
||||
@ -44,15 +43,17 @@ All locks are exclusive.
|
||||
rules:
|
||||
|
||||
* 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.
|
||||
* if old parent is equal to or is a descendent of target
|
||||
fail with -ENOTEMPTY
|
||||
* if new parent is equal to or is a descendent of source
|
||||
fail with -ELOOP
|
||||
* If it's an exchange, lock both the source and the target.
|
||||
* If the target exists, lock it. If the source is a non-directory,
|
||||
lock it. If we need to lock both, do so in inode pointer order.
|
||||
* Lock both the source and the target provided they exist. If we
|
||||
need to lock two inodes of different type (dir vs non-dir), we lock
|
||||
the directory first. If we need to lock two inodes of the same type,
|
||||
lock them in inode pointer order.
|
||||
* call the method.
|
||||
|
||||
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:
|
||||
|
||||
First of all, at any moment we have a partial ordering of the
|
||||
objects - A < B iff A is an ancestor of B.
|
||||
First of all, at any moment we have a linear ordering of the
|
||||
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:
|
||||
|
||||
|
@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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,
|
||||
"Accelerating networking with AF_XDP". It can be found at
|
||||
https://lwn.net/Articles/750845/.
|
||||
For an overview on how AF_XDP works, you can also take a look at the
|
||||
Linux Plumbers paper from 2018 on the subject:
|
||||
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
|
||||
----
|
||||
@ -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
|
||||
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
|
||||
user-space application.
|
||||
|
||||
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
|
||||
application need explicit synchronization of multiple
|
||||
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
|
||||
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
|
||||
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
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
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
|
||||
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.
|
||||
@ -164,8 +169,8 @@ chunks mode, then the incoming addr will be left untouched.
|
||||
UMEM Completion Ring
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Completion Ring is used transfer ownership of UMEM frames from
|
||||
kernel-space to user-space. Just like the Fill ring, UMEM indicies are
|
||||
The COMPLETION Ring is used transfer ownership of UMEM frames from
|
||||
kernel-space to user-space. Just like the FILL ring, UMEM indices are
|
||||
used.
|
||||
|
||||
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
|
||||
(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.
|
||||
|
||||
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
|
||||
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
|
||||
----------------------------
|
||||
============================
|
||||
|
||||
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
|
||||
@ -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
|
||||
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
|
||||
=====
|
||||
|
||||
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
|
||||
usage example, please refer to the sample application. The user-space
|
||||
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)
|
||||
{
|
||||
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.
|
||||
if (bpf_map_lookup_elem(&xsks_map, &index))
|
||||
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;
|
||||
}
|
||||
|
||||
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 {
|
||||
// __u32 *producer;
|
||||
@ -287,17 +483,16 @@ Naive ring dequeue and enqueue could look like this::
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
For a more optimized version, please refer to the sample application.
|
||||
But please use the libbpf functions as they are optimized and ready to
|
||||
use. Will make your life easier.
|
||||
|
||||
Sample application
|
||||
==================
|
||||
|
||||
There is a xdpsock benchmarking/test application included that
|
||||
demonstrates how to use AF_XDP sockets with both private and shared
|
||||
UMEMs. Say that you would like your UDP traffic from port 4242 to end
|
||||
up in queue 16, that we will enable AF_XDP on. Here, we use ethtool
|
||||
for this::
|
||||
demonstrates how to use AF_XDP sockets with private UMEMs. Say that
|
||||
you would like your UDP traffic from port 4242 to end up in queue 16,
|
||||
that we will enable AF_XDP on. Here, we use ethtool for this::
|
||||
|
||||
ethtool -N p3p2 rx-flow-hash udp4 fn
|
||||
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
|
||||
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
|
||||
=======
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
@ -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 \
|
||||
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.
|
||||
|
||||
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
|
||||
=======
|
||||
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 250
|
||||
SUBLEVEL = 251
|
||||
EXTRAVERSION =
|
||||
NAME = Kleptomaniac Octopus
|
||||
|
||||
|
@ -8,6 +8,10 @@
|
||||
|
||||
#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__
|
||||
|
||||
.macro ST2 e, o, off
|
||||
@ -28,10 +32,6 @@
|
||||
#endif
|
||||
.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 */
|
||||
.macro ARCFP_DATA nm
|
||||
#ifdef CONFIG_ARC_HAS_DCCM
|
||||
|
@ -511,7 +511,6 @@
|
||||
"spi_lr_session_done",
|
||||
"spi_lr_overread";
|
||||
clocks = <&iprocmed>;
|
||||
clock-names = "iprocmed";
|
||||
num-cs = <2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
@ -5,9 +5,11 @@
|
||||
|
||||
#include "omap3-gta04a5.dts"
|
||||
|
||||
&omap3_pmx_core {
|
||||
/ {
|
||||
model = "Goldelico GTA04A5/Letux 2804 with OneNAND";
|
||||
};
|
||||
|
||||
&omap3_pmx_core {
|
||||
gpmc_pins: pinmux_gpmc_pins {
|
||||
pinctrl-single,pins = <
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include "soc.h"
|
||||
#include "platform.h"
|
||||
|
||||
/*************************************************************************
|
||||
* Timer handling for EP93xx
|
||||
@ -60,7 +61,7 @@ static u64 notrace ep93xx_read_sched_clock(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
u64 ep93xx_clocksource_read(struct clocksource *c)
|
||||
static u64 ep93xx_clocksource_read(struct clocksource *c)
|
||||
{
|
||||
u64 ret;
|
||||
|
||||
|
@ -63,6 +63,9 @@ static void __init orion5x_dt_init(void)
|
||||
if (of_machine_is_compatible("maxtor,shared-storage-2"))
|
||||
mss2_init();
|
||||
|
||||
if (of_machine_is_compatible("lacie,d2-network"))
|
||||
d2net_init();
|
||||
|
||||
of_platform_default_populate(NULL, orion5x_auxdata_lookup, NULL);
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,12 @@ extern void mss2_init(void);
|
||||
static inline void mss2_init(void) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MACH_D2NET_DT
|
||||
void d2net_init(void);
|
||||
#else
|
||||
static inline void d2net_init(void) {}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Helpers to access Orion registers
|
||||
****************************************************************************/
|
||||
|
@ -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
|
||||
* 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,
|
||||
const struct decode_header *h)
|
||||
{
|
||||
|
@ -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
|
||||
* 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_ctlblk *kcb;
|
||||
|
@ -145,8 +145,6 @@ __arch_remove_optimized_kprobe(struct optimized_kprobe *op, int dirty)
|
||||
}
|
||||
}
|
||||
|
||||
extern void kprobe_handler(struct pt_regs *regs);
|
||||
|
||||
static void
|
||||
optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
|
||||
{
|
||||
|
@ -720,7 +720,7 @@ static const char coverage_register_lookup[16] = {
|
||||
[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;
|
||||
int i;
|
||||
|
@ -453,3 +453,7 @@ void kprobe_thumb32_test_cases(void);
|
||||
#else
|
||||
void kprobe_arm_test_cases(void);
|
||||
#endif
|
||||
|
||||
void __kprobes_test_case_start(void);
|
||||
void __kprobes_test_case_end_16(void);
|
||||
void __kprobes_test_case_end_32(void);
|
||||
|
@ -1451,7 +1451,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
camss: camss@1b00000 {
|
||||
camss: camss@1b0ac00 {
|
||||
compatible = "qcom,msm8916-camss";
|
||||
reg = <0x1b0ac00 0x200>,
|
||||
<0x1b00030 0x4>,
|
||||
|
@ -269,7 +269,7 @@
|
||||
};
|
||||
|
||||
scif1_pins: scif1 {
|
||||
groups = "scif1_data_b", "scif1_ctrl";
|
||||
groups = "scif1_data_b";
|
||||
function = "scif1";
|
||||
};
|
||||
|
||||
@ -329,7 +329,6 @@
|
||||
&scif1 {
|
||||
pinctrl-0 = <&scif1_pins>;
|
||||
pinctrl-names = "default";
|
||||
uart-has-rtscts;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -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,
|
||||
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",
|
||||
&phys, virt);
|
||||
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,
|
||||
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",
|
||||
&phys, virt);
|
||||
return;
|
||||
|
@ -234,7 +234,7 @@ config PPC_EARLY_DEBUG_40x
|
||||
|
||||
config PPC_EARLY_DEBUG_CPM
|
||||
bool "Early serial debugging for Freescale CPM-based serial ports"
|
||||
depends on SERIAL_CPM
|
||||
depends on SERIAL_CPM=y
|
||||
help
|
||||
Select this to enable early debugging for Freescale chips
|
||||
using a CPM-based serial port. This assumes that the bootwrapper
|
||||
|
@ -425,3 +425,11 @@ checkbin:
|
||||
echo -n '*** Please use a different binutils version.' ; \
|
||||
false ; \
|
||||
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
|
||||
|
@ -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 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;
|
||||
|
||||
if (start_pfn < altmap->base_pfn)
|
||||
|
@ -1982,6 +1982,10 @@ static unsigned long kvm_s390_next_dirty_cmma(struct kvm_memslots *slots,
|
||||
ms = slots->memslots + slotidx;
|
||||
ofs = 0;
|
||||
}
|
||||
|
||||
if (cur_gfn < ms->base_gfn)
|
||||
ofs = 0;
|
||||
|
||||
ofs = find_next_bit(kvm_second_dirty_bitmap(ms), ms->npages, ofs);
|
||||
while ((slotidx > 0) && (ofs >= ms->npages)) {
|
||||
slotidx--;
|
||||
|
@ -168,7 +168,8 @@ static int setup_apcb00(struct kvm_vcpu *vcpu, unsigned long *apcb_s,
|
||||
sizeof(struct kvm_s390_apcb0)))
|
||||
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;
|
||||
}
|
||||
@ -190,7 +191,8 @@ static int setup_apcb11(struct kvm_vcpu *vcpu, unsigned long *apcb_s,
|
||||
sizeof(struct kvm_s390_apcb1)))
|
||||
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;
|
||||
}
|
||||
|
@ -18,6 +18,18 @@
|
||||
#include <cpu/dma-register.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.
|
||||
* 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;
|
||||
|
||||
#ifdef SH_DMAC_BASE1
|
||||
if (chan >= 6)
|
||||
if (chan >= SH_DMAC_NR_MD_CH)
|
||||
base = SH_DMAC_BASE1;
|
||||
#endif
|
||||
|
||||
@ -40,13 +52,13 @@ static unsigned long dma_base_addr(unsigned int chan)
|
||||
{
|
||||
unsigned long base = dma_find_base(chan);
|
||||
|
||||
/* Normalize offset calculation */
|
||||
if (chan >= 9)
|
||||
chan -= 6;
|
||||
if (chan >= 4)
|
||||
base += 0x10;
|
||||
chan = (chan % SH_DMAC_NR_MD_CH) * SH_DMAC_CH_SZ;
|
||||
|
||||
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
|
||||
@ -250,12 +262,11 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan)
|
||||
#define NR_DMAOR 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DMAOR bases are broken out amongst channel groups. DMAOR0 manages
|
||||
* channels 0 - 5, DMAOR1 6 - 11 (optional).
|
||||
*/
|
||||
#define dmaor_read_reg(n) __raw_readw(dma_find_base((n)*6))
|
||||
#define dmaor_write_reg(n, data) __raw_writew(data, dma_find_base(n)*6)
|
||||
#define dmaor_read_reg(n) __raw_readw(dma_find_base((n) * \
|
||||
SH_DMAC_NR_MD_CH) + DMAOR)
|
||||
#define dmaor_write_reg(n, data) __raw_writew(data, \
|
||||
dma_find_base((n) * \
|
||||
SH_DMAC_NR_MD_CH) + DMAOR)
|
||||
|
||||
static inline int dmaor_reset(int no)
|
||||
{
|
||||
|
@ -21,7 +21,7 @@ static int __init scan_cache(unsigned long node, const char *uname,
|
||||
if (!of_flat_dt_is_compatible(node, "jcore,cache"))
|
||||
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;
|
||||
}
|
||||
|
@ -593,6 +593,18 @@ static int __rdtgroup_move_task(struct task_struct *tsk,
|
||||
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
|
||||
* @r: Resource group
|
||||
@ -608,8 +620,7 @@ int rdtgroup_tasks_assigned(struct rdtgroup *r)
|
||||
|
||||
rcu_read_lock();
|
||||
for_each_process_thread(p, t) {
|
||||
if ((r->type == RDTCTRL_GROUP && t->closid == r->closid) ||
|
||||
(r->type == RDTMON_GROUP && t->rmid == r->mon.rmid)) {
|
||||
if (is_closid_match(t, r) || is_rmid_match(t, r)) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
@ -704,12 +715,15 @@ unlock:
|
||||
static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s)
|
||||
{
|
||||
struct task_struct *p, *t;
|
||||
pid_t pid;
|
||||
|
||||
rcu_read_lock();
|
||||
for_each_process_thread(p, t) {
|
||||
if ((r->type == RDTCTRL_GROUP && t->closid == r->closid) ||
|
||||
(r->type == RDTMON_GROUP && t->rmid == r->mon.rmid))
|
||||
seq_printf(s, "%d\n", t->pid);
|
||||
if (is_closid_match(t, r) || is_rmid_match(t, r)) {
|
||||
pid = task_pid_vnr(t);
|
||||
if (pid)
|
||||
seq_printf(s, "%d\n", pid);
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
@ -2148,18 +2162,6 @@ static int reset_all_ctrls(struct rdt_resource *r)
|
||||
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
|
||||
* in the systems are moved unconditionally (used for teardown).
|
||||
|
@ -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);
|
||||
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 */
|
||||
unsigned int __max_logical_packages __read_mostly;
|
||||
EXPORT_SYMBOL(__max_logical_packages);
|
||||
@ -1675,10 +1686,10 @@ static bool wakeup_cpu0(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 highest_cstate = 0;
|
||||
unsigned int highest_subcstate = 0;
|
||||
void *mwait_ptr;
|
||||
int i;
|
||||
|
||||
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
|
||||
@ -1713,13 +1724,6 @@ static inline void mwait_play_dead(void)
|
||||
(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 = ¤t_thread_info()->flags;
|
||||
|
||||
wbinvd();
|
||||
|
||||
while (1) {
|
||||
@ -1731,9 +1735,9 @@ static inline void mwait_play_dead(void)
|
||||
* case where we return around the loop.
|
||||
*/
|
||||
mb();
|
||||
clflush(mwait_ptr);
|
||||
clflush(md);
|
||||
mb();
|
||||
__monitor(mwait_ptr, 0, 0);
|
||||
__monitor(md, 0, 0);
|
||||
mb();
|
||||
__mwait(eax, 0);
|
||||
/*
|
||||
|
@ -231,7 +231,7 @@ static int tuntap_probe(struct iss_net_private *lp, int index, char *init)
|
||||
|
||||
init += sizeof(TRANSPORT_TUNTAP_NAME) - 1;
|
||||
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) {
|
||||
pr_err("%s: extra garbage on specification : '%s'\n",
|
||||
dev->name, rem);
|
||||
|
@ -11,11 +11,19 @@
|
||||
#define pr_fmt(fmt) fmt
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/mm_types.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <linux/affs_hardblocks.h>
|
||||
|
||||
#include "check.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
|
||||
checksum_block(__be32 *m, int size)
|
||||
{
|
||||
@ -32,8 +40,12 @@ int amiga_partition(struct parsed_partitions *state)
|
||||
unsigned char *data;
|
||||
struct RigidDiskBlock *rdb;
|
||||
struct PartitionBlock *pb;
|
||||
int start_sect, nr_sects, blk, part, res = 0;
|
||||
int blksize = 1; /* Multiplier for disk block size */
|
||||
u64 start_sect, nr_sects;
|
||||
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;
|
||||
char b[BDEVNAME_SIZE];
|
||||
|
||||
@ -43,7 +55,7 @@ int amiga_partition(struct parsed_partitions *state)
|
||||
data = read_part_sector(state, blk, §);
|
||||
if (!data) {
|
||||
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);
|
||||
res = -1;
|
||||
goto rdb_done;
|
||||
@ -60,12 +72,12 @@ int amiga_partition(struct parsed_partitions *state)
|
||||
*(__be32 *)(data+0xdc) = 0;
|
||||
if (checksum_block((__be32 *)data,
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -81,12 +93,17 @@ int amiga_partition(struct parsed_partitions *state)
|
||||
}
|
||||
blk = be32_to_cpu(rdb->rdb_PartitionList);
|
||||
put_dev_sector(sect);
|
||||
for (part = 1; blk>0 && part<=16; part++, put_dev_sector(sect)) {
|
||||
blk *= blksize; /* Read in terms partition table understands */
|
||||
for (part = 1; (s32) blk>0 && part<=16; part++, put_dev_sector(sect)) {
|
||||
/* 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, §);
|
||||
if (!data) {
|
||||
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);
|
||||
res = -1;
|
||||
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 )
|
||||
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)
|
||||
continue;
|
||||
start_sect = be32_to_cpu(pb->pb_Environment[9]) *
|
||||
be32_to_cpu(pb->pb_Environment[3]) *
|
||||
be32_to_cpu(pb->pb_Environment[5]) *
|
||||
blksize;
|
||||
|
||||
/* Warn user if partition end overflows u32 (AmigaDOS limit) */
|
||||
|
||||
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);
|
||||
{
|
||||
/* Be even more informative to aid mounting */
|
||||
|
@ -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);
|
||||
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_off_latency_ns = 1000 * entry_latency;
|
||||
genpd_state->power_on_latency_ns = 1000LL * exit_latency;
|
||||
genpd_state->power_off_latency_ns = 1000LL * entry_latency;
|
||||
genpd_state->fwnode = &state_node->fwnode;
|
||||
|
||||
return 0;
|
||||
|
@ -1708,7 +1708,8 @@ static int nbd_dev_add(int index)
|
||||
if (err == -ENOSPC)
|
||||
err = -EEXIST;
|
||||
} 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)
|
||||
index = err;
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ static int imx_rngc_self_test(struct imx_rngc *rngc)
|
||||
cmd = readl(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) {
|
||||
imx_rngc_irq_mask_clear(rngc);
|
||||
return -ETIMEDOUT;
|
||||
@ -182,9 +182,7 @@ static int imx_rngc_init(struct hwrng *rng)
|
||||
cmd = readl(rngc->base + RNGC_COMMAND);
|
||||
writel(cmd | RNGC_CMD_SEED, 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) {
|
||||
imx_rngc_irq_mask_clear(rngc);
|
||||
return -ETIMEDOUT;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/hw_random.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
@ -41,7 +42,6 @@
|
||||
|
||||
struct st_rng_data {
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
struct hwrng ops;
|
||||
};
|
||||
|
||||
@ -86,26 +86,18 @@ static int st_rng_probe(struct platform_device *pdev)
|
||||
if (IS_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))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
ret = clk_prepare_enable(clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ddata->ops.priv = (unsigned long)ddata;
|
||||
ddata->ops.read = st_rng_read;
|
||||
ddata->ops.name = pdev->name;
|
||||
ddata->base = base;
|
||||
ddata->clk = clk;
|
||||
|
||||
dev_set_drvdata(&pdev->dev, ddata);
|
||||
|
||||
ret = devm_hwrng_register(&pdev->dev, &ddata->ops);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register HW RNG\n");
|
||||
clk_disable_unprepare(clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -114,16 +106,7 @@ static int st_rng_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st_rng_remove(struct platform_device *pdev)
|
||||
{
|
||||
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[] = {
|
||||
static const struct of_device_id st_rng_match[] __maybe_unused = {
|
||||
{ .compatible = "st,rng" },
|
||||
{},
|
||||
};
|
||||
@ -135,7 +118,6 @@ static struct platform_driver st_rng_driver = {
|
||||
.of_match_table = of_match_ptr(st_rng_match),
|
||||
},
|
||||
.probe = st_rng_probe,
|
||||
.remove = st_rng_remove
|
||||
};
|
||||
|
||||
module_platform_driver(st_rng_driver);
|
||||
|
@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2007, 2008 Rusty Russell IBM Corporation
|
||||
*/
|
||||
|
||||
#include <asm/barrier.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/hw_random.h>
|
||||
#include <linux/scatterlist.h>
|
||||
@ -19,12 +20,12 @@ struct virtrng_info {
|
||||
struct virtqueue *vq;
|
||||
char name[25];
|
||||
int index;
|
||||
bool busy;
|
||||
bool hwrng_register_done;
|
||||
bool hwrng_removed;
|
||||
/* data transfer */
|
||||
struct completion have_data;
|
||||
unsigned int data_avail;
|
||||
unsigned int data_idx;
|
||||
/* minimal size returned by rng_buffer_size() */
|
||||
#if SMP_CACHE_BYTES < 32
|
||||
u8 data[32];
|
||||
@ -36,19 +37,23 @@ struct virtrng_info {
|
||||
static void random_recv_done(struct virtqueue *vq)
|
||||
{
|
||||
struct virtrng_info *vi = vq->vdev->priv;
|
||||
unsigned int len;
|
||||
|
||||
/* 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;
|
||||
|
||||
smp_store_release(&vi->data_avail, len);
|
||||
complete(&vi->have_data);
|
||||
}
|
||||
|
||||
/* The host will fill any buffer we give it with sweet, sweet randomness. */
|
||||
static void register_buffer(struct virtrng_info *vi)
|
||||
static void request_entropy(struct virtrng_info *vi)
|
||||
{
|
||||
struct scatterlist sg;
|
||||
|
||||
reinit_completion(&vi->have_data);
|
||||
vi->data_idx = 0;
|
||||
|
||||
sg_init_one(&sg, vi->data, sizeof(vi->data));
|
||||
|
||||
/* There should always be room for one buffer. */
|
||||
@ -57,6 +62,18 @@ static void register_buffer(struct virtrng_info *vi)
|
||||
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)
|
||||
{
|
||||
int ret;
|
||||
@ -67,35 +84,37 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
|
||||
if (vi->hwrng_removed)
|
||||
return -ENODEV;
|
||||
|
||||
if (!vi->busy) {
|
||||
vi->busy = true;
|
||||
reinit_completion(&vi->have_data);
|
||||
register_buffer(vi);
|
||||
read = 0;
|
||||
|
||||
/* copy available data */
|
||||
if (smp_load_acquire(&vi->data_avail)) {
|
||||
chunk = copy_data(vi, buf, size);
|
||||
size -= chunk;
|
||||
read += chunk;
|
||||
}
|
||||
|
||||
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) {
|
||||
/* data_avail is 0 but a request is pending */
|
||||
ret = wait_for_completion_killable(&vi->have_data);
|
||||
if (ret < 0)
|
||||
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);
|
||||
memcpy(buf + read, vi->data, chunk);
|
||||
read += chunk;
|
||||
chunk = copy_data(vi, buf + read, size);
|
||||
size -= chunk;
|
||||
vi->data_avail = 0;
|
||||
|
||||
if (size != 0) {
|
||||
reinit_completion(&vi->have_data);
|
||||
register_buffer(vi);
|
||||
}
|
||||
read += chunk;
|
||||
}
|
||||
|
||||
vi->busy = false;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
@ -103,8 +122,7 @@ static void virtio_cleanup(struct hwrng *rng)
|
||||
{
|
||||
struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
|
||||
|
||||
if (vi->busy)
|
||||
wait_for_completion(&vi->have_data);
|
||||
complete(&vi->have_data);
|
||||
}
|
||||
|
||||
static int probe_common(struct virtio_device *vdev)
|
||||
@ -140,6 +158,9 @@ static int probe_common(struct virtio_device *vdev)
|
||||
goto err_find;
|
||||
}
|
||||
|
||||
/* we always have a pending entropy request */
|
||||
request_entropy(vi);
|
||||
|
||||
return 0;
|
||||
|
||||
err_find:
|
||||
@ -155,9 +176,9 @@ static void remove_common(struct virtio_device *vdev)
|
||||
|
||||
vi->hwrng_removed = true;
|
||||
vi->data_avail = 0;
|
||||
vi->data_idx = 0;
|
||||
complete(&vi->have_data);
|
||||
vdev->config->reset(vdev);
|
||||
vi->busy = false;
|
||||
if (vi->hwrng_register_done)
|
||||
hwrng_unregister(&vi->hwrng);
|
||||
vdev->config->del_vqs(vdev);
|
||||
|
@ -693,37 +693,21 @@ static struct miscdevice vtpmx_miscdev = {
|
||||
.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)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = vtpmx_init();
|
||||
if (rc) {
|
||||
pr_err("couldn't create vtpmx device\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
workqueue = create_workqueue("tpm-vtpm");
|
||||
if (!workqueue) {
|
||||
pr_err("couldn't create workqueue\n");
|
||||
rc = -ENOMEM;
|
||||
goto err_vtpmx_cleanup;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_vtpmx_cleanup:
|
||||
vtpmx_cleanup();
|
||||
rc = misc_register(&vtpmx_miscdev);
|
||||
if (rc) {
|
||||
pr_err("couldn't create vtpmx device\n");
|
||||
destroy_workqueue(workqueue);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -731,7 +715,7 @@ err_vtpmx_cleanup:
|
||||
static void __exit vtpm_module_exit(void)
|
||||
{
|
||||
destroy_workqueue(workqueue);
|
||||
vtpmx_cleanup();
|
||||
misc_deregister(&vtpmx_miscdev);
|
||||
}
|
||||
|
||||
module_init(vtpm_module_init);
|
||||
|
@ -705,6 +705,10 @@ static int cdce925_probe(struct i2c_client *client,
|
||||
for (i = 0; i < data->chip_info->num_plls; ++i) {
|
||||
pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d",
|
||||
client->dev.of_node, i);
|
||||
if (!pll_clk_name[i]) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
init.name = pll_clk_name[i];
|
||||
data->pll[i].chip = data;
|
||||
data->pll[i].hw.init = &init;
|
||||
@ -746,6 +750,10 @@ static int cdce925_probe(struct i2c_client *client,
|
||||
init.num_parents = 1;
|
||||
init.parent_names = &parent_name; /* Mux Y1 to input */
|
||||
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].hw.init = &init;
|
||||
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) {
|
||||
init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d",
|
||||
client->dev.of_node, i+1);
|
||||
if (!init.name) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
data->clk[i].chip = data;
|
||||
data->clk[i].hw.init = &init;
|
||||
data->clk[i].index = i;
|
||||
|
@ -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,
|
||||
sci_clk->clk_id);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
init.name = name;
|
||||
|
||||
|
@ -459,6 +459,7 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
|
||||
err = load_one_timing_from_dt(tegra, timing, child);
|
||||
if (err) {
|
||||
of_node_put(child);
|
||||
kfree(tegra->timings);
|
||||
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);
|
||||
if (err) {
|
||||
of_node_put(node);
|
||||
kfree(tegra);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/slab.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:
|
||||
@ -464,13 +466,7 @@ out_kfree:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
static int __init ttc_timer_probe(struct platform_device *pdev)
|
||||
{
|
||||
unsigned int irq;
|
||||
void __iomem *timer_baseaddr;
|
||||
@ -478,6 +474,7 @@ static int __init ttc_timer_init(struct device_node *timer)
|
||||
static int initialized;
|
||||
int clksel, ret;
|
||||
u32 timer_width = 16;
|
||||
struct device_node *timer = pdev->dev.of_node;
|
||||
|
||||
if (initialized)
|
||||
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
|
||||
* 2nd TTC hence the irq_of_parse_and_map(,1)
|
||||
*/
|
||||
timer_baseaddr = of_iomap(timer, 0);
|
||||
if (!timer_baseaddr) {
|
||||
timer_baseaddr = devm_of_iomap(&pdev->dev, timer, 0, NULL);
|
||||
if (IS_ERR(timer_baseaddr)) {
|
||||
pr_err("ERROR: invalid timer base address\n");
|
||||
return -ENXIO;
|
||||
return PTR_ERR(timer_baseaddr);
|
||||
}
|
||||
|
||||
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);
|
||||
if (IS_ERR(clk_ce)) {
|
||||
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);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto put_clk_ce;
|
||||
|
||||
ret = ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto put_clk_ce;
|
||||
|
||||
pr_info("%pOFn #0 at %p, irq=%d\n", timer, timer_baseaddr, irq);
|
||||
|
||||
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);
|
||||
|
@ -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,
|
||||
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;
|
||||
|
||||
err = verify_skcipher_des3_key(cipher, key);
|
||||
|
@ -1,7 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_CRYPTO_DEV_NX_ENCRYPT) += nx-crypto.o
|
||||
nx-crypto-objs := nx.o \
|
||||
nx_debugfs.o \
|
||||
nx-aes-cbc.o \
|
||||
nx-aes-ecb.o \
|
||||
nx-aes-gcm.o \
|
||||
@ -11,6 +10,7 @@ nx-crypto-objs := nx.o \
|
||||
nx-sha256.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_POWERNV) += nx-compress-powernv.o nx-compress.o
|
||||
nx-compress-objs := nx-842.o
|
||||
|
@ -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_fini(struct nx_crypto_driver *);
|
||||
#else
|
||||
#define NX_DEBUGFS_INIT(drv) (0)
|
||||
#define NX_DEBUGFS_FINI(drv) (0)
|
||||
#define NX_DEBUGFS_INIT(drv) do {} while (0)
|
||||
#define NX_DEBUGFS_FINI(drv) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define NX_PAGE_NUM(x) ((u64)(x) & 0xfffffffffffff000ULL)
|
||||
|
@ -196,6 +196,14 @@ static const struct __extcon_info {
|
||||
* @attr_name: "name" sysfs entry
|
||||
* @attr_state: "state" sysfs entry
|
||||
* @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_dev *edev;
|
||||
|
@ -615,7 +615,7 @@ svc_create_memory_pool(struct platform_device *pdev,
|
||||
end = rounddown(sh_memory->addr + sh_memory->size, PAGE_SIZE);
|
||||
paddr = begin;
|
||||
size = end - begin;
|
||||
va = memremap(paddr, size, MEMREMAP_WC);
|
||||
va = devm_memremap(dev, paddr, size, MEMREMAP_WC);
|
||||
if (!va) {
|
||||
dev_err(dev, "fail to remap shared memory\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
@ -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;
|
||||
int r;
|
||||
|
||||
/* No valid flags defined yet */
|
||||
if (args->in.flags)
|
||||
return -EINVAL;
|
||||
|
||||
switch (args->in.op) {
|
||||
case AMDGPU_VM_OP_RESERVE_VMID:
|
||||
/* current, we only have requirement to reserve vmid from gfxhub */
|
||||
|
@ -101,18 +101,19 @@ static struct kfd_mem_obj *allocate_mqd(struct kfd_dev *kfd,
|
||||
&(mqd_mem_obj->gtt_mem),
|
||||
&(mqd_mem_obj->gpu_addr),
|
||||
(void *)&(mqd_mem_obj->cpu_ptr), true);
|
||||
|
||||
if (retval) {
|
||||
kfree(mqd_mem_obj);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
retval = kfd_gtt_sa_allocate(kfd, sizeof(struct v9_mqd),
|
||||
&mqd_mem_obj);
|
||||
}
|
||||
|
||||
if (retval) {
|
||||
kfree(mqd_mem_obj);
|
||||
return NULL;
|
||||
if (retval)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mqd_mem_obj;
|
||||
|
||||
}
|
||||
|
||||
static void init_mqd(struct mqd_manager *mm, void **mqd,
|
||||
|
@ -97,6 +97,12 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
|
||||
if (!state->planes)
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
@ -268,6 +275,8 @@ void __drm_atomic_state_free(struct kref *ref)
|
||||
drm_atomic_state_default_release(state);
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
drm_dev_put(dev);
|
||||
}
|
||||
EXPORT_SYMBOL(__drm_atomic_state_free);
|
||||
|
||||
|
@ -1078,7 +1078,16 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
|
||||
continue;
|
||||
|
||||
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)
|
||||
drm_crtc_vblank_put(crtc);
|
||||
}
|
||||
|
@ -281,6 +281,9 @@ static bool drm_client_target_cloned(struct drm_device *dev,
|
||||
can_clone = true;
|
||||
dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false);
|
||||
|
||||
if (!dmt_mode)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < connector_count; i++) {
|
||||
if (!enabled[i])
|
||||
continue;
|
||||
@ -296,11 +299,13 @@ static bool drm_client_target_cloned(struct drm_device *dev,
|
||||
if (!modes[i])
|
||||
can_clone = false;
|
||||
}
|
||||
kfree(dmt_mode);
|
||||
|
||||
if (can_clone) {
|
||||
DRM_DEBUG_KMS("can clone using 1024x768\n");
|
||||
return true;
|
||||
}
|
||||
fail:
|
||||
DRM_INFO("kms: can't enable cloning when we probably wanted to.\n");
|
||||
return false;
|
||||
}
|
||||
@ -785,6 +790,7 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width,
|
||||
break;
|
||||
}
|
||||
|
||||
kfree(modeset->mode);
|
||||
modeset->mode = drm_mode_duplicate(dev, mode);
|
||||
drm_connector_get(connector);
|
||||
modeset->connectors[modeset->num_connectors++] = connector;
|
||||
|
@ -44,14 +44,22 @@ static LIST_HEAD(panel_list);
|
||||
/**
|
||||
* drm_panel_init - initialize a 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
|
||||
* to the registry.
|
||||
* Initialize the panel structure for subsequent registration with
|
||||
* 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);
|
||||
BLOCKING_INIT_NOTIFIER_HEAD(&panel->nh);
|
||||
panel->dev = dev;
|
||||
panel->funcs = funcs;
|
||||
panel->connector_type = connector_type;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_panel_init);
|
||||
|
||||
|
@ -1926,13 +1926,14 @@ int __intel_wait_for_register_fw(struct intel_uncore *uncore,
|
||||
unsigned int slow_timeout_ms,
|
||||
u32 *out_value)
|
||||
{
|
||||
u32 reg_value;
|
||||
u32 reg_value = 0;
|
||||
#define done (((reg_value = intel_uncore_read_fw(uncore, reg)) & mask) == value)
|
||||
int ret;
|
||||
|
||||
/* Catch any overuse of this function */
|
||||
might_sleep_if(slow_timeout_ms);
|
||||
GEM_BUG_ON(fast_timeout_us > 20000);
|
||||
GEM_BUG_ON(!fast_timeout_us && !slow_timeout_ms);
|
||||
|
||||
ret = -ETIMEDOUT;
|
||||
if (fast_timeout_us && fast_timeout_us <= 20000)
|
||||
|
@ -350,9 +350,8 @@ static int versatile_panel_probe(struct platform_device *pdev)
|
||||
dev_info(dev, "panel mounted on IB2 daughterboard\n");
|
||||
}
|
||||
|
||||
drm_panel_init(&vpanel->panel);
|
||||
vpanel->panel.dev = dev;
|
||||
vpanel->panel.funcs = &versatile_panel_drm_funcs;
|
||||
drm_panel_init(&vpanel->panel, dev, &versatile_panel_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
return drm_panel_add(&vpanel->panel);
|
||||
}
|
||||
|
@ -204,9 +204,8 @@ static int feiyang_dsi_probe(struct mipi_dsi_device *dsi)
|
||||
mipi_dsi_set_drvdata(dsi, ctx);
|
||||
ctx->dsi = dsi;
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = &dsi->dev;
|
||||
ctx->panel.funcs = &feiyang_funcs;
|
||||
drm_panel_init(&ctx->panel, &dsi->dev, &feiyang_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ctx->dvdd = devm_regulator_get(&dsi->dev, "dvdd");
|
||||
if (IS_ERR(ctx->dvdd)) {
|
||||
|
@ -895,9 +895,8 @@ static int ili9322_probe(struct spi_device *spi)
|
||||
ili->input = ili->conf->input;
|
||||
}
|
||||
|
||||
drm_panel_init(&ili->panel);
|
||||
ili->panel.dev = dev;
|
||||
ili->panel.funcs = &ili9322_drm_funcs;
|
||||
drm_panel_init(&ili->panel, dev, &ili9322_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
return drm_panel_add(&ili->panel);
|
||||
}
|
||||
|
@ -433,9 +433,8 @@ static int ili9881c_dsi_probe(struct mipi_dsi_device *dsi)
|
||||
mipi_dsi_set_drvdata(dsi, ctx);
|
||||
ctx->dsi = dsi;
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = &dsi->dev;
|
||||
ctx->panel.funcs = &ili9881c_funcs;
|
||||
drm_panel_init(&ctx->panel, &dsi->dev, &ili9881c_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ctx->power = devm_regulator_get(&dsi->dev, "power");
|
||||
if (IS_ERR(ctx->power)) {
|
||||
|
@ -487,9 +487,8 @@ static int innolux_panel_add(struct mipi_dsi_device *dsi,
|
||||
if (IS_ERR(innolux->backlight))
|
||||
return PTR_ERR(innolux->backlight);
|
||||
|
||||
drm_panel_init(&innolux->base);
|
||||
innolux->base.funcs = &innolux_panel_funcs;
|
||||
innolux->base.dev = dev;
|
||||
drm_panel_init(&innolux->base, dev, &innolux_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
err = drm_panel_add(&innolux->base);
|
||||
if (err < 0)
|
||||
|
@ -437,9 +437,8 @@ static int jdi_panel_add(struct jdi_panel *jdi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_panel_init(&jdi->base);
|
||||
jdi->base.funcs = &jdi_panel_funcs;
|
||||
jdi->base.dev = &jdi->dsi->dev;
|
||||
drm_panel_init(&jdi->base, &jdi->dsi->dev, &jdi_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ret = drm_panel_add(&jdi->base);
|
||||
|
||||
|
@ -391,9 +391,8 @@ static int kingdisplay_panel_add(struct kingdisplay_panel *kingdisplay)
|
||||
if (IS_ERR(kingdisplay->backlight))
|
||||
return PTR_ERR(kingdisplay->backlight);
|
||||
|
||||
drm_panel_init(&kingdisplay->base);
|
||||
kingdisplay->base.funcs = &kingdisplay_panel_funcs;
|
||||
kingdisplay->base.dev = &kingdisplay->link->dev;
|
||||
drm_panel_init(&kingdisplay->base, &kingdisplay->link->dev,
|
||||
&kingdisplay_panel_funcs, DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
return drm_panel_add(&kingdisplay->base);
|
||||
}
|
||||
|
@ -196,9 +196,8 @@ static int lb035q02_probe(struct spi_device *spi)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
drm_panel_init(&lcd->panel);
|
||||
lcd->panel.dev = &lcd->spi->dev;
|
||||
lcd->panel.funcs = &lb035q02_funcs;
|
||||
drm_panel_init(&lcd->panel, &lcd->spi->dev, &lb035q02_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
return drm_panel_add(&lcd->panel);
|
||||
}
|
||||
|
@ -259,9 +259,8 @@ static int lg4573_probe(struct spi_device *spi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = &spi->dev;
|
||||
ctx->panel.funcs = &lg4573_drm_funcs;
|
||||
drm_panel_init(&ctx->panel, &spi->dev, &lg4573_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
return drm_panel_add(&ctx->panel);
|
||||
}
|
||||
|
@ -254,9 +254,8 @@ static int panel_lvds_probe(struct platform_device *pdev)
|
||||
*/
|
||||
|
||||
/* Register the panel. */
|
||||
drm_panel_init(&lvds->panel);
|
||||
lvds->panel.dev = lvds->dev;
|
||||
lvds->panel.funcs = &panel_lvds_funcs;
|
||||
drm_panel_init(&lvds->panel, lvds->dev, &panel_lvds_funcs,
|
||||
DRM_MODE_CONNECTOR_LVDS);
|
||||
|
||||
ret = drm_panel_add(&lvds->panel);
|
||||
if (ret < 0)
|
||||
|
@ -205,9 +205,8 @@ static int nl8048_probe(struct spi_device *spi)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
drm_panel_init(&lcd->panel);
|
||||
lcd->panel.dev = &lcd->spi->dev;
|
||||
lcd->panel.funcs = &nl8048_funcs;
|
||||
drm_panel_init(&lcd->panel, &lcd->spi->dev, &nl8048_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
return drm_panel_add(&lcd->panel);
|
||||
}
|
||||
|
@ -292,9 +292,8 @@ static int nt39016_probe(struct spi_device *spi)
|
||||
return err;
|
||||
}
|
||||
|
||||
drm_panel_init(&panel->drm_panel);
|
||||
panel->drm_panel.dev = dev;
|
||||
panel->drm_panel.funcs = &nt39016_funcs;
|
||||
drm_panel_init(&panel->drm_panel, dev, &nt39016_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
err = drm_panel_add(&panel->drm_panel);
|
||||
if (err < 0) {
|
||||
|
@ -288,9 +288,8 @@ static int lcd_olinuxino_probe(struct i2c_client *client,
|
||||
if (IS_ERR(lcd->backlight))
|
||||
return PTR_ERR(lcd->backlight);
|
||||
|
||||
drm_panel_init(&lcd->panel);
|
||||
lcd->panel.dev = dev;
|
||||
lcd->panel.funcs = &lcd_olinuxino_funcs;
|
||||
drm_panel_init(&lcd->panel, dev, &lcd_olinuxino_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
return drm_panel_add(&lcd->panel);
|
||||
}
|
||||
|
@ -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 |
|
||||
MIPI_DSI_MODE_LPM;
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = dev;
|
||||
ctx->panel.funcs = &otm8009a_drm_funcs;
|
||||
drm_panel_init(&ctx->panel, dev, &otm8009a_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ctx->bl_dev = devm_backlight_device_register(dev, dev_name(dev),
|
||||
dev, ctx,
|
||||
|
@ -166,9 +166,8 @@ static int osd101t2587_panel_add(struct osd101t2587_panel *osd101t2587)
|
||||
if (IS_ERR(osd101t2587->backlight))
|
||||
return PTR_ERR(osd101t2587->backlight);
|
||||
|
||||
drm_panel_init(&osd101t2587->base);
|
||||
osd101t2587->base.funcs = &osd101t2587_panel_funcs;
|
||||
osd101t2587->base.dev = &osd101t2587->dsi->dev;
|
||||
drm_panel_init(&osd101t2587->base, &osd101t2587->dsi->dev,
|
||||
&osd101t2587_panel_funcs, DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
return drm_panel_add(&osd101t2587->base);
|
||||
}
|
||||
|
@ -223,9 +223,8 @@ static int wuxga_nt_panel_add(struct wuxga_nt_panel *wuxga_nt)
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
drm_panel_init(&wuxga_nt->base);
|
||||
wuxga_nt->base.funcs = &wuxga_nt_panel_funcs;
|
||||
wuxga_nt->base.dev = &wuxga_nt->dsi->dev;
|
||||
drm_panel_init(&wuxga_nt->base, &wuxga_nt->dsi->dev,
|
||||
&wuxga_nt_panel_funcs, DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ret = drm_panel_add(&wuxga_nt->base);
|
||||
if (ret < 0)
|
||||
|
@ -433,9 +433,8 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c,
|
||||
return PTR_ERR(ts->dsi);
|
||||
}
|
||||
|
||||
drm_panel_init(&ts->base);
|
||||
ts->base.dev = dev;
|
||||
ts->base.funcs = &rpi_touchscreen_funcs;
|
||||
drm_panel_init(&ts->base, dev, &rpi_touchscreen_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
/* This appears last, as it's what will unblock the DSI host
|
||||
* driver's component bind function.
|
||||
|
@ -606,9 +606,8 @@ static int rad_panel_probe(struct mipi_dsi_device *dsi)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
drm_panel_init(&panel->panel);
|
||||
panel->panel.funcs = &rad_panel_funcs;
|
||||
panel->panel.dev = dev;
|
||||
drm_panel_init(&panel->panel, dev, &rad_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
dev_set_drvdata(dev, panel);
|
||||
|
||||
ret = drm_panel_add(&panel->panel);
|
||||
|
@ -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 |
|
||||
MIPI_DSI_MODE_LPM;
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = dev;
|
||||
ctx->panel.funcs = &rm68200_drm_funcs;
|
||||
drm_panel_init(&ctx->panel, dev, &rm68200_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
drm_panel_add(&ctx->panel);
|
||||
|
||||
|
@ -343,9 +343,8 @@ static int jh057n_probe(struct mipi_dsi_device *dsi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = dev;
|
||||
ctx->panel.funcs = &jh057n_drm_funcs;
|
||||
drm_panel_init(&ctx->panel, dev, &jh057n_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
drm_panel_add(&ctx->panel);
|
||||
|
||||
|
@ -173,9 +173,8 @@ static int rb070d30_panel_dsi_probe(struct mipi_dsi_device *dsi)
|
||||
mipi_dsi_set_drvdata(dsi, ctx);
|
||||
ctx->dsi = dsi;
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = &dsi->dev;
|
||||
ctx->panel.funcs = &rb070d30_panel_funcs;
|
||||
drm_panel_init(&ctx->panel, &dsi->dev, &rb070d30_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ctx->gpios.reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(ctx->gpios.reset)) {
|
||||
|
@ -351,9 +351,8 @@ static int ld9040_probe(struct spi_device *spi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = dev;
|
||||
ctx->panel.funcs = &ld9040_drm_funcs;
|
||||
drm_panel_init(&ctx->panel, dev, &ld9040_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
return drm_panel_add(&ctx->panel);
|
||||
}
|
||||
|
@ -215,9 +215,8 @@ static int s6d16d0_probe(struct mipi_dsi_device *dsi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_panel_init(&s6->panel);
|
||||
s6->panel.dev = dev;
|
||||
s6->panel.funcs = &s6d16d0_drm_funcs;
|
||||
drm_panel_init(&s6->panel, dev, &s6d16d0_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ret = drm_panel_add(&s6->panel);
|
||||
if (ret < 0)
|
||||
|
@ -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.power = FB_BLANK_POWERDOWN;
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = dev;
|
||||
ctx->panel.funcs = &s6e3ha2_drm_funcs;
|
||||
drm_panel_init(&ctx->panel, dev, &s6e3ha2_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ret = drm_panel_add(&ctx->panel);
|
||||
if (ret < 0)
|
||||
|
@ -466,9 +466,8 @@ static int s6e63j0x03_probe(struct mipi_dsi_device *dsi)
|
||||
return PTR_ERR(ctx->reset_gpio);
|
||||
}
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = dev;
|
||||
ctx->panel.funcs = &s6e63j0x03_funcs;
|
||||
drm_panel_init(&ctx->panel, dev, &s6e63j0x03_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ctx->bl_dev = backlight_device_register("s6e63j0x03", dev, ctx,
|
||||
&s6e63j0x03_bl_ops, NULL);
|
||||
|
@ -473,9 +473,8 @@ static int s6e63m0_probe(struct spi_device *spi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = dev;
|
||||
ctx->panel.funcs = &s6e63m0_drm_funcs;
|
||||
drm_panel_init(&ctx->panel, dev, &s6e63m0_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
ret = s6e63m0_backlight_register(ctx);
|
||||
if (ret < 0)
|
||||
|
@ -1017,9 +1017,8 @@ static int s6e8aa0_probe(struct mipi_dsi_device *dsi)
|
||||
|
||||
ctx->brightness = GAMMA_LEVEL_NUM - 1;
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = dev;
|
||||
ctx->panel.funcs = &s6e8aa0_drm_funcs;
|
||||
drm_panel_init(&ctx->panel, dev, &s6e8aa0_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ret = drm_panel_add(&ctx->panel);
|
||||
if (ret < 0)
|
||||
|
@ -274,9 +274,8 @@ static int seiko_panel_probe(struct device *dev,
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
drm_panel_init(&panel->base);
|
||||
panel->base.dev = dev;
|
||||
panel->base.funcs = &seiko_panel_funcs;
|
||||
drm_panel_init(&panel->base, dev, &seiko_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
err = drm_panel_add(&panel->base);
|
||||
if (err < 0)
|
||||
|
@ -329,9 +329,8 @@ static int sharp_panel_add(struct sharp_panel *sharp)
|
||||
if (IS_ERR(sharp->backlight))
|
||||
return PTR_ERR(sharp->backlight);
|
||||
|
||||
drm_panel_init(&sharp->base);
|
||||
sharp->base.funcs = &sharp_panel_funcs;
|
||||
sharp->base.dev = &sharp->link1->dev;
|
||||
drm_panel_init(&sharp->base, &sharp->link1->dev, &sharp_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
return drm_panel_add(&sharp->base);
|
||||
}
|
||||
|
@ -185,9 +185,8 @@ static int ls037v7dw01_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(lcd->ud_gpio);
|
||||
}
|
||||
|
||||
drm_panel_init(&lcd->panel);
|
||||
lcd->panel.dev = &pdev->dev;
|
||||
lcd->panel.funcs = &ls037v7dw01_funcs;
|
||||
drm_panel_init(&lcd->panel, &pdev->dev, &ls037v7dw01_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
return drm_panel_add(&lcd->panel);
|
||||
}
|
||||
|
@ -264,9 +264,8 @@ static int sharp_nt_panel_add(struct sharp_nt_panel *sharp_nt)
|
||||
if (IS_ERR(sharp_nt->backlight))
|
||||
return PTR_ERR(sharp_nt->backlight);
|
||||
|
||||
drm_panel_init(&sharp_nt->base);
|
||||
sharp_nt->base.funcs = &sharp_nt_panel_funcs;
|
||||
sharp_nt->base.dev = &sharp_nt->dsi->dev;
|
||||
drm_panel_init(&sharp_nt->base, &sharp_nt->dsi->dev,
|
||||
&sharp_nt_panel_funcs, DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
return drm_panel_add(&sharp_nt->base);
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ struct panel_desc {
|
||||
|
||||
u32 bus_format;
|
||||
u32 bus_flags;
|
||||
int connector_type;
|
||||
};
|
||||
|
||||
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))
|
||||
panel_simple_parse_panel_timing_node(dev, panel, &dt);
|
||||
|
||||
drm_panel_init(&panel->base);
|
||||
panel->base.dev = dev;
|
||||
panel->base.funcs = &panel_simple_funcs;
|
||||
drm_panel_init(&panel->base, dev, &panel_simple_funcs,
|
||||
desc->connector_type);
|
||||
|
||||
err = drm_panel_add(&panel->base);
|
||||
if (err < 0)
|
||||
@ -531,8 +531,8 @@ static const struct panel_desc ampire_am_480272h3tmqw_t01h = {
|
||||
.num_modes = 1,
|
||||
.bpc = 8,
|
||||
.size = {
|
||||
.width = 105,
|
||||
.height = 67,
|
||||
.width = 99,
|
||||
.height = 58,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
|
||||
};
|
||||
@ -833,6 +833,7 @@ static const struct panel_desc auo_g133han01 = {
|
||||
.unprepare = 1000,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct display_timing auo_g185han01_timings = {
|
||||
@ -862,6 +863,7 @@ static const struct panel_desc auo_g185han01 = {
|
||||
.unprepare = 1000,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct display_timing auo_p320hvn03_timings = {
|
||||
@ -890,6 +892,7 @@ static const struct panel_desc auo_p320hvn03 = {
|
||||
.unprepare = 500,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode auo_t215hvn01_mode = {
|
||||
@ -1205,6 +1208,7 @@ static const struct panel_desc dlc_dlc0700yzg_1 = {
|
||||
.disable = 200,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct display_timing dlc_dlc1010gig_timing = {
|
||||
@ -1235,6 +1239,7 @@ static const struct panel_desc dlc_dlc1010gig = {
|
||||
.unprepare = 60,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode edt_et035012dm6_mode = {
|
||||
@ -1501,6 +1506,7 @@ static const struct panel_desc hannstar_hsd070pww1 = {
|
||||
.height = 94,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct display_timing hannstar_hsd100pxn1_timing = {
|
||||
@ -1525,6 +1531,7 @@ static const struct panel_desc hannstar_hsd100pxn1 = {
|
||||
.height = 152,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode hitachi_tx23d38vm0caa_mode = {
|
||||
@ -1577,6 +1584,7 @@ static const struct panel_desc innolux_at043tn24 = {
|
||||
.height = 54,
|
||||
},
|
||||
.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,
|
||||
};
|
||||
|
||||
@ -1631,6 +1639,7 @@ static const struct panel_desc innolux_g070y2_l01 = {
|
||||
.unprepare = 800,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct display_timing innolux_g101ice_l01_timing = {
|
||||
@ -1659,6 +1668,7 @@ static const struct panel_desc innolux_g101ice_l01 = {
|
||||
.disable = 200,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct display_timing innolux_g121i1_l01_timing = {
|
||||
@ -1686,6 +1696,7 @@ static const struct panel_desc innolux_g121i1_l01 = {
|
||||
.disable = 20,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode innolux_g121x1_l03_mode = {
|
||||
@ -1869,6 +1880,7 @@ static const struct panel_desc koe_tx31d200vm0baa = {
|
||||
.height = 109,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct display_timing kyo_tcg121xglp_timing = {
|
||||
@ -1893,6 +1905,7 @@ static const struct panel_desc kyo_tcg121xglp = {
|
||||
.height = 184,
|
||||
},
|
||||
.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 = {
|
||||
@ -1941,6 +1954,7 @@ static const struct panel_desc lg_lb070wv8 = {
|
||||
.height = 91,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode lg_lp079qx1_sp0v_mode = {
|
||||
@ -2097,6 +2111,7 @@ static const struct panel_desc mitsubishi_aa070mc01 = {
|
||||
.disable = 400,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
.bus_flags = DRM_BUS_FLAG_DE_HIGH,
|
||||
};
|
||||
|
||||
@ -2125,6 +2140,7 @@ static const struct panel_desc nec_nl12880bc20_05 = {
|
||||
.disable = 50,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode nec_nl4827hc19_05b_mode = {
|
||||
@ -2227,6 +2243,7 @@ static const struct panel_desc nlt_nl192108ac18_02d = {
|
||||
.unprepare = 500,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode nvd_9128_mode = {
|
||||
@ -2250,6 +2267,7 @@ static const struct panel_desc nvd_9128 = {
|
||||
.height = 88,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct display_timing okaya_rs800480t_7x0gp_timing = {
|
||||
@ -2662,6 +2680,7 @@ static const struct panel_desc sharp_lq101k1ly04 = {
|
||||
.height = 136,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct display_timing sharp_lq123p1jx31_timing = {
|
||||
@ -2841,6 +2860,7 @@ static const struct panel_desc tianma_tm070jdhg30 = {
|
||||
.height = 95,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct display_timing tianma_tm070rvhg71_timing = {
|
||||
@ -2865,6 +2885,7 @@ static const struct panel_desc tianma_tm070rvhg71 = {
|
||||
.height = 86,
|
||||
},
|
||||
.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[] = {
|
||||
@ -2947,6 +2968,7 @@ static const struct panel_desc toshiba_lt089ac29000 = {
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
|
||||
.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 = {
|
||||
@ -3017,6 +3039,7 @@ static const struct panel_desc urt_umsh_8596md_lvds = {
|
||||
.height = 91,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct panel_desc urt_umsh_8596md_parallel = {
|
||||
|
@ -369,7 +369,8 @@ static int st7701_dsi_probe(struct mipi_dsi_device *dsi)
|
||||
if (IS_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
|
||||
@ -381,8 +382,6 @@ static int st7701_dsi_probe(struct mipi_dsi_device *dsi)
|
||||
* ts8550b and there is no valid documentation for that.
|
||||
*/
|
||||
st7701->sleep_delay = 120 + desc->panel_sleep_delay;
|
||||
st7701->panel.funcs = &st7701_funcs;
|
||||
st7701->panel.dev = &dsi->dev;
|
||||
|
||||
ret = drm_panel_add(&st7701->panel);
|
||||
if (ret < 0)
|
||||
|
@ -381,9 +381,8 @@ static int st7789v_probe(struct spi_device *spi)
|
||||
spi_set_drvdata(spi, ctx);
|
||||
ctx->spi = spi;
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = &spi->dev;
|
||||
ctx->panel.funcs = &st7789v_drm_funcs;
|
||||
drm_panel_init(&ctx->panel, &spi->dev, &st7789v_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
ctx->power = devm_regulator_get(&spi->dev, "power");
|
||||
if (IS_ERR(ctx->power))
|
||||
|
@ -648,9 +648,8 @@ static int acx565akm_probe(struct spi_device *spi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_panel_init(&lcd->panel);
|
||||
lcd->panel.dev = &lcd->spi->dev;
|
||||
lcd->panel.funcs = &acx565akm_funcs;
|
||||
drm_panel_init(&lcd->panel, &lcd->spi->dev, &acx565akm_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
ret = drm_panel_add(&lcd->panel);
|
||||
if (ret < 0) {
|
||||
|
@ -347,9 +347,8 @@ static int td028ttec1_probe(struct spi_device *spi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_panel_init(&lcd->panel);
|
||||
lcd->panel.dev = &lcd->spi->dev;
|
||||
lcd->panel.funcs = &td028ttec1_funcs;
|
||||
drm_panel_init(&lcd->panel, &lcd->spi->dev, &td028ttec1_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
return drm_panel_add(&lcd->panel);
|
||||
}
|
||||
|
@ -458,9 +458,8 @@ static int td043mtea1_probe(struct spi_device *spi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_panel_init(&lcd->panel);
|
||||
lcd->panel.dev = &lcd->spi->dev;
|
||||
lcd->panel.funcs = &td043mtea1_funcs;
|
||||
drm_panel_init(&lcd->panel, &lcd->spi->dev, &td043mtea1_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
ret = drm_panel_add(&lcd->panel);
|
||||
if (ret < 0) {
|
||||
|
@ -457,9 +457,8 @@ static int tpg110_probe(struct spi_device *spi)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
drm_panel_init(&tpg->panel);
|
||||
tpg->panel.dev = dev;
|
||||
tpg->panel.funcs = &tpg110_drm_funcs;
|
||||
drm_panel_init(&tpg->panel, dev, &tpg110_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
spi_set_drvdata(spi, tpg);
|
||||
|
||||
return drm_panel_add(&tpg->panel);
|
||||
|
@ -518,9 +518,8 @@ static int truly_nt35597_panel_add(struct truly_nt35597 *ctx)
|
||||
/* dual port */
|
||||
gpiod_set_value(ctx->mode_gpio, 0);
|
||||
|
||||
drm_panel_init(&ctx->panel);
|
||||
ctx->panel.dev = dev;
|
||||
ctx->panel.funcs = &truly_nt35597_drm_funcs;
|
||||
drm_panel_init(&ctx->panel, dev, &truly_nt35597_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
drm_panel_add(&ctx->panel);
|
||||
|
||||
return 0;
|
||||
|
@ -5556,6 +5556,7 @@ static int ci_parse_power_table(struct radeon_device *rdev)
|
||||
u8 frev, crev;
|
||||
u8 *power_state_offset;
|
||||
struct ci_ps *ps;
|
||||
int ret;
|
||||
|
||||
if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&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_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
|
||||
&non_clock_info_array->nonClockInfo[non_clock_array_index];
|
||||
if (!rdev->pm.power_state[i].clock_info)
|
||||
return -EINVAL;
|
||||
if (!rdev->pm.power_state[i].clock_info) {
|
||||
ret = -EINVAL;
|
||||
goto err_free_ps;
|
||||
}
|
||||
ps = kzalloc(sizeof(struct ci_ps), GFP_KERNEL);
|
||||
if (ps == NULL)
|
||||
return -ENOMEM;
|
||||
if (ps == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_ps;
|
||||
}
|
||||
rdev->pm.dpm.ps[i].ps_priv = ps;
|
||||
ci_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
|
||||
non_clock_info,
|
||||
@ -5629,6 +5634,12 @@ static int ci_parse_power_table(struct radeon_device *rdev)
|
||||
}
|
||||
|
||||
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,
|
||||
@ -5717,25 +5728,26 @@ int ci_dpm_init(struct radeon_device *rdev)
|
||||
|
||||
ret = ci_get_vbios_boot_values(rdev, &pi->vbios_boot_state);
|
||||
if (ret) {
|
||||
ci_dpm_fini(rdev);
|
||||
kfree(rdev->pm.dpm.priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = r600_get_platform_caps(rdev);
|
||||
if (ret) {
|
||||
ci_dpm_fini(rdev);
|
||||
kfree(rdev->pm.dpm.priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = r600_parse_extended_power_table(rdev);
|
||||
if (ret) {
|
||||
ci_dpm_fini(rdev);
|
||||
kfree(rdev->pm.dpm.priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ci_parse_power_table(rdev);
|
||||
if (ret) {
|
||||
ci_dpm_fini(rdev);
|
||||
kfree(rdev->pm.dpm.priv);
|
||||
r600_free_extended_power_table(rdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -559,8 +559,12 @@ static int cypress_populate_mclk_value(struct radeon_device *rdev,
|
||||
ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
|
||||
u32 reference_clock = rdev->clock.mpll.reference_freq;
|
||||
u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
|
||||
u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
|
||||
u32 clk_v = ss.percentage *
|
||||
u32 clk_s, clk_v;
|
||||
|
||||
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);
|
||||
|
||||
mpll_ss1 &= ~CLKV_MASK;
|
||||
|
@ -2241,8 +2241,12 @@ static int ni_populate_mclk_value(struct radeon_device *rdev,
|
||||
ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
|
||||
u32 reference_clock = rdev->clock.mpll.reference_freq;
|
||||
u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
|
||||
u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
|
||||
u32 clk_v = ss.percentage *
|
||||
u32 clk_s, clk_v;
|
||||
|
||||
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);
|
||||
|
||||
mpll_ss1 &= ~CLKV_MASK;
|
||||
|
@ -250,8 +250,12 @@ int rv740_populate_mclk_value(struct radeon_device *rdev,
|
||||
ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
|
||||
u32 reference_clock = rdev->clock.mpll.reference_freq;
|
||||
u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
|
||||
u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
|
||||
u32 clk_v = 0x40000 * ss.percentage *
|
||||
u32 clk_s, clk_v;
|
||||
|
||||
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);
|
||||
|
||||
mpll_ss1 &= ~CLKV_MASK;
|
||||
|
@ -654,13 +654,13 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||
if (crtc->state->self_refresh_active)
|
||||
rockchip_drm_set_win_enabled(crtc, false);
|
||||
|
||||
if (crtc->state->self_refresh_active)
|
||||
goto out;
|
||||
|
||||
mutex_lock(&vop->vop_lock);
|
||||
|
||||
drm_crtc_vblank_off(crtc);
|
||||
|
||||
if (crtc->state->self_refresh_active)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Vop standby will take effect at end of current frame,
|
||||
* 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);
|
||||
pm_runtime_put(vop->dev);
|
||||
|
||||
out:
|
||||
mutex_unlock(&vop->vop_lock);
|
||||
|
||||
out:
|
||||
if (crtc->state->event && !crtc->state->active) {
|
||||
spin_lock_irq(&crtc->dev->event_lock);
|
||||
drm_crtc_send_vblank_event(crtc, crtc->state->event);
|
||||
|
@ -753,21 +753,19 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private)
|
||||
static int sun4i_tcon_init_clocks(struct device *dev,
|
||||
struct sun4i_tcon *tcon)
|
||||
{
|
||||
tcon->clk = devm_clk_get(dev, "ahb");
|
||||
tcon->clk = devm_clk_get_enabled(dev, "ahb");
|
||||
if (IS_ERR(tcon->clk)) {
|
||||
dev_err(dev, "Couldn't get the TCON bus clock\n");
|
||||
return PTR_ERR(tcon->clk);
|
||||
}
|
||||
clk_prepare_enable(tcon->clk);
|
||||
|
||||
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)) {
|
||||
dev_err(dev, "Couldn't get the TCON channel 0 clock\n");
|
||||
return PTR_ERR(tcon->sclk0);
|
||||
}
|
||||
}
|
||||
clk_prepare_enable(tcon->sclk0);
|
||||
|
||||
if (tcon->quirks->has_channel_1) {
|
||||
tcon->sclk1 = devm_clk_get(dev, "tcon-ch1");
|
||||
@ -780,12 +778,6 @@ static int sun4i_tcon_init_clocks(struct device *dev,
|
||||
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,
|
||||
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);
|
||||
if (ret) {
|
||||
dev_err(dev, "Couldn't init our TCON regmap\n");
|
||||
goto err_free_clocks;
|
||||
goto err_assert_reset;
|
||||
}
|
||||
|
||||
if (tcon->quirks->has_channel_0) {
|
||||
ret = sun4i_dclk_create(dev, tcon);
|
||||
if (ret) {
|
||||
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:
|
||||
if (tcon->quirks->has_channel_0)
|
||||
sun4i_dclk_free(tcon);
|
||||
err_free_clocks:
|
||||
sun4i_tcon_free_clocks(tcon);
|
||||
err_assert_reset:
|
||||
reset_control_assert(tcon->lcd_rst);
|
||||
return ret;
|
||||
@ -1287,7 +1277,6 @@ static void sun4i_tcon_unbind(struct device *dev, struct device *master,
|
||||
list_del(&tcon->list);
|
||||
if (tcon->quirks->has_channel_0)
|
||||
sun4i_dclk_free(tcon);
|
||||
sun4i_tcon_free_clocks(tcon);
|
||||
}
|
||||
|
||||
static const struct component_ops sun4i_tcon_ops = {
|
||||
|
@ -1307,7 +1307,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
|
||||
struct input_dev *pen_input = wacom->pen_input;
|
||||
unsigned char *data = wacom->data;
|
||||
int number_of_valid_frames = 0;
|
||||
int time_interval = 15000000;
|
||||
ktime_t time_interval = 15000000;
|
||||
ktime_t time_packet_received = ktime_get();
|
||||
int i;
|
||||
|
||||
@ -1341,7 +1341,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
|
||||
if (number_of_valid_frames) {
|
||||
if (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;
|
||||
}
|
||||
|
||||
@ -1352,7 +1352,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
|
||||
bool range = frame[0] & 0x20;
|
||||
bool invert = frame[0] & 0x10;
|
||||
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)
|
||||
continue;
|
||||
|
@ -320,7 +320,7 @@ struct hid_data {
|
||||
int bat_connected;
|
||||
int ps_connected;
|
||||
bool pad_input_event_flag;
|
||||
int time_delayed;
|
||||
ktime_t time_delayed;
|
||||
};
|
||||
|
||||
struct wacom_remote_data {
|
||||
|
@ -353,6 +353,9 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
|
||||
struct xiic_i2c *i2c = dev_id;
|
||||
u32 pend, isr, ier;
|
||||
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
|
||||
* 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);
|
||||
|
||||
if (i2c->rx_msg)
|
||||
xiic_wakeup(i2c, STATE_ERROR);
|
||||
if (i2c->tx_msg)
|
||||
xiic_wakeup(i2c, STATE_ERROR);
|
||||
if (i2c->rx_msg) {
|
||||
wakeup_req = 1;
|
||||
wakeup_code = 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) {
|
||||
/* Receive register/FIFO is full */
|
||||
@ -426,8 +435,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
|
||||
i2c->tx_msg++;
|
||||
dev_dbg(i2c->adap.dev.parent,
|
||||
"%s will start next...\n", __func__);
|
||||
|
||||
__xiic_start_xfer(i2c);
|
||||
xfer_more = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -441,11 +449,13 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
|
||||
if (!i2c->tx_msg)
|
||||
goto out;
|
||||
|
||||
if ((i2c->nmsgs == 1) && !i2c->rx_msg &&
|
||||
xiic_tx_space(i2c) == 0)
|
||||
xiic_wakeup(i2c, STATE_DONE);
|
||||
wakeup_req = 1;
|
||||
|
||||
if (i2c->nmsgs == 1 && !i2c->rx_msg &&
|
||||
xiic_tx_space(i2c) == 0)
|
||||
wakeup_code = STATE_DONE;
|
||||
else
|
||||
xiic_wakeup(i2c, STATE_ERROR);
|
||||
wakeup_code = STATE_ERROR;
|
||||
}
|
||||
if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) {
|
||||
/* 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) {
|
||||
i2c->nmsgs--;
|
||||
i2c->tx_msg++;
|
||||
__xiic_start_xfer(i2c);
|
||||
xfer_more = 1;
|
||||
} else {
|
||||
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);
|
||||
|
||||
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);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -71,7 +71,7 @@
|
||||
#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_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_MASK GENMASK(7, 0)
|
||||
|
||||
|
@ -2606,11 +2606,8 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq,
|
||||
|
||||
qp = (struct bnxt_qplib_qp *)((unsigned long)
|
||||
le64_to_cpu(hwcqe->qp_handle));
|
||||
if (!qp) {
|
||||
dev_err(&cq->hwq.pdev->dev,
|
||||
"FP: CQ Process terminal qp is NULL\n");
|
||||
if (!qp)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Must block new posting of SQ and RQ */
|
||||
qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user