Merge tag 'ASB-2022-01-05_4.19-stable' of https://android.googlesource.com/kernel/common into lineage-21
https://source.android.com/security/bulletin/2022-01-01 CVE-2020-14305 CVE-2020-29368 CVE-2021-39633 CVE-2021-39634 * tag 'ASB-2022-01-05_4.19-stable' of https://android.googlesource.com/kernel/common: Linux 4.19.224 net: fix use-after-free in tw_timer_handler Input: spaceball - fix parsing of movement data packets Input: appletouch - initialize work before device registration scsi: vmw_pvscsi: Set residual data length conditionally binder: fix async_free_space accounting for empty parcels usb: mtu3: set interval of FS intr and isoc endpoint usb: gadget: f_fs: Clear ffs_eventfd in ffs_data_clear. xhci: Fresco FL1100 controller should not have BROKEN_MSI quirk set. uapi: fix linux/nfc.h userspace compilation errors nfc: uapi: use kernel size_t to fix user-space builds i2c: validate user data in compat ioctl fsl/fman: Fix missing put_device() call in fman_port_probe selftests/net: udpgso_bench_tx: fix dst ip argument net/mlx5e: Fix wrong features assignment in case of error NFC: st21nfca: Fix memory leak in device probe and remove net: usb: pegasus: Do not drop long Ethernet frames sctp: use call_rcu to free endpoint selftests: Calculate udpgso segment count without header adjustment udp: using datalen to cap ipv6 udp max gso segments scsi: lpfc: Terminate string in lpfc_debugfs_nvmeio_trc_write() selinux: initialize proto variable in selinux_ip_postroute_compat() recordmcount.pl: fix typo in s390 mcount regex platform/x86: apple-gmux: use resource_size() with res Input: i8042 - enable deferred probe quirk for ASUS UM325UA Input: i8042 - add deferred probe support tee: handle lookup of shm with reference count 0 HID: asus: Add depends on USB_HID to HID_ASUS Kconfig option Linux 4.19.223 phonet/pep: refuse to enable an unbound pipe hamradio: improve the incomplete fix to avoid NPD hamradio: defer ax25 kfree after unregister_netdev ax25: NPD bug when detaching AX25 device hwmon: (lm90) Do not report 'busy' status bit as alarm KVM: VMX: Fix stale docs for kvm-intel.emulate_invalid_guest_state usb: gadget: u_ether: fix race in setting MAC address in setup phase f2fs: fix to do sanity check on last xattr entry in __f2fs_setxattr() ARM: 9169/1: entry: fix Thumb2 bug in iWMMXt exception handling pinctrl: stm32: consider the GPIO offset to expose all the GPIO lines x86/pkey: Fix undefined behaviour with PKRU_WD_BIT parisc: Correct completer in lws start ipmi: fix initialization when workqueue allocation fails ipmi: bail out if init_srcu_struct fails Input: atmel_mxt_ts - fix double free in mxt_read_info_block ALSA: drivers: opl3: Fix incorrect use of vp->state ALSA: jack: Check the return value of kstrdup() hwmon: (lm90) Fix usage of CONFIG2 register in detect function sfc: falcon: Check null pointer of rx_queue->page_ring drivers: net: smc911x: Check for error irq fjes: Check for error irq bonding: fix ad_actor_system option setting to default ipmi: Fix UAF when uninstall ipmi_si and ipmi_msghandler module net: skip virtio_net_hdr_set_proto if protocol already set net: accept UFOv6 packages in virtio_net_hdr_to_skb qlcnic: potential dereference null pointer of rx_queue->page_ring netfilter: fix regression in looped (broad|multi)cast's MAC handling IB/qib: Fix memory leak in qib_user_sdma_queue_pkts() spi: change clk_disable_unprepare to clk_unprepare arm64: dts: allwinner: orangepi-zero-plus: fix PHY mode HID: holtek: fix mouse probing block, bfq: fix use after free in bfq_bfqq_expire block, bfq: fix queue removal from weights tree block, bfq: fix decrement of num_active_groups block, bfq: fix asymmetric scenarios detection block, bfq: improve asymmetric scenarios detection net: usb: lan78xx: add Allied Telesis AT29M2-AF Revert "ARM: 8800/1: use choice for kernel unwinders" Linux 4.19.222 xen/netback: don't queue unlimited number of packages xen/netback: fix rx queue stall detection xen/console: harden hvc_xen against event channel storms xen/netfront: harden netfront against event channel storms xen/blkfront: harden blkfront against event channel storms scsi: scsi_debug: Sanity check block descriptor length in resp_mode_select() ovl: fix warning in ovl_create_real() fuse: annotate lock in fuse_reverse_inval_entry() media: mxl111sf: change mutex_init() location ARM: dts: imx6ull-pinfunc: Fix CSI_DATA07__ESAI_TX0 pad name firmware: arm_scpi: Fix string overflow in SCPI genpd driver Input: touchscreen - avoid bitwise vs logical OR warning ARM: 8800/1: use choice for kernel unwinders mwifiex: Remove unnecessary braces from HostCmd_SET_SEQ_NO_BSS_INFO ARM: 8805/2: remove unneeded naked function usage net: lan78xx: Avoid unnecessary self assignment mac80211: validate extended element ID is present net: systemport: Add global locking for descriptor lifecycle drm/amdgpu: correct register access for RLC_JUMP_TABLE_RESTORE libata: if T_LENGTH is zero, dma direction should be DMA_NONE timekeeping: Really make sure wall_to_monotonic isn't positive USB: serial: option: add Telit FN990 compositions USB: serial: cp210x: fix CP2105 GPIO registration PCI/MSI: Mask MSI-X vectors only on success PCI/MSI: Clear PCI_MSIX_FLAGS_MASKALL on error USB: NO_LPM quirk Lenovo USB-C to Ethernet Adapher(RTL8153-04) USB: gadget: bRequestType is a bitfield, not a enum sit: do not call ipip6_dev_free() from sit_init_net() net/packet: rx_owner_map depends on pg_vec netdevsim: Zero-initialize memory for new map's value in function nsim_bpf_map_alloc ixgbe: set X550 MDIO speed before talking to PHY igbvf: fix double free in `igbvf_probe` igb: Fix removal of unicast MAC filters of VFs soc/tegra: fuse: Fix bitwise vs. logical OR warning rds: memory leak in __rds_conn_create() dmaengine: st_fdma: fix MODULE_ALIAS sch_cake: do not call cake_destroy() from cake_init() ARM: socfpga: dts: fix qspi node compatible mac80211: track only QoS data frames for admission control x86/sme: Explicitly map new EFI memmap table as encrypted x86: Make ARCH_USE_MEMREMAP_PROT a generic Kconfig symbol nfsd: fix use-after-free due to delegation race audit: improve robustness of the audit queue handling dm btree remove: fix use after free in rebalance_children() recordmcount.pl: look for jgnop instruction as well as bcrl on s390 mac80211: send ADDBA requests using the tid/queue of the aggregation session hwmon: (dell-smm) Fix warning on /proc/i8k creation error tracing: Fix a kmemleak false positive in tracing_map net: netlink: af_netlink: Prevent empty skb by adding a check on len. i2c: rk3x: Handle a spurious start completion interrupt flag parisc/agp: Annotate parisc agp init functions with __init net/mlx4_en: Update reported link modes for 1/10G drm/msm/dsi: set default num_data_lanes nfc: fix segfault in nfc_genl_dump_devices_done stable: clamp SUBLEVEL in 4.19 FROMGIT: USB: gadget: bRequestType is a bitfield, not a enum ANDROID: GKI: abi workaround for 4.19.221 Linux 4.19.221 net: sched: make function qdisc_free_cb() static net_sched: fix a crash in tc_new_tfilter() irqchip: nvic: Fix offset for Interrupt Priority Offsets irqchip/irq-gic-v3-its.c: Force synchronisation when issuing INVALL irqchip/armada-370-xp: Fix support for Multi-MSI interrupts irqchip/armada-370-xp: Fix return value of armada_370_xp_msi_alloc() iio: accel: kxcjk-1013: Fix possible memory leak in probe and remove iio: adc: axp20x_adc: fix charging current reporting on AXP22x iio: at91-sama5d2: Fix incorrect sign extension iio: dln2: Check return value of devm_iio_trigger_register() iio: dln2-adc: Fix lockdep complaint iio: itg3200: Call iio_trigger_notify_done() on error iio: kxsd9: Don't return error code in trigger handler iio: ltr501: Don't return error code in trigger handler iio: mma8452: Fix trigger reference couting iio: stk3310: Don't return error code in interrupt handler iio: trigger: stm32-timer: fix MODULE_ALIAS iio: trigger: Fix reference counting xhci: avoid race between disable slot command and host runtime suspend usb: core: config: using bit mask instead of individual bits xhci: Remove CONFIG_USB_DEFAULT_PERSIST to prevent xHCI from runtime suspending usb: core: config: fix validation of wMaxPacketValue entries USB: gadget: zero allocate endpoint 0 buffers USB: gadget: detect too-big endpoint 0 requests net/qla3xxx: fix an error code in ql_adapter_up() net, neigh: clear whole pneigh_entry at alloc time net: fec: only clear interrupt of handling queue in fec_enet_rx_queue() net: altera: set a couple error code in probe() net: cdc_ncm: Allow for dwNtbOutMaxSize to be unset or zero tools build: Remove needless libpython-version feature check that breaks test-all fast path mtd: rawnand: fsmc: Take instruction delay into account i40e: Fix pre-set max number of queues for VF ASoC: qdsp6: q6routing: Fix return value from msm_routing_put_audio_mixer qede: validate non LSO skb length block: fix ioprio_get(IOPRIO_WHO_PGRP) vs setuid(2) tracefs: Set all files to the same group ownership as the mount option aio: fix use-after-free due to missing POLLFREE handling aio: keep poll requests on waitqueue until completed signalfd: use wake_up_pollfree() binder: use wake_up_pollfree() wait: add wake_up_pollfree() libata: add horkage for ASMedia 1092 can: m_can: Disable and ignore ELO interrupt can: pch_can: pch_can_rx_normal: fix use after free clk: qcom: regmap-mux: fix parent clock lookup tracefs: Have new files inherit the ownership of their parent ALSA: pcm: oss: Handle missing errors in snd_pcm_oss_change_params*() ALSA: pcm: oss: Limit the period size to 16MB ALSA: pcm: oss: Fix negative period/buffer sizes ALSA: ctl: Fix copy of updated id with element read/write mm: bdi: initialize bdi_min_ratio when bdi is unregistered IB/hfi1: Correct guard on eager buffer deallocation udp: using datalen to cap max gso segments seg6: fix the iif in the IPv6 socket control block nfp: Fix memory leak in nfp_cpp_area_cache_add() bonding: make tx_rebalance_counter an atomic ice: ignore dropped packets during init bpf: Fix the off-by-two error in range markings nfc: fix potential NULL pointer deref in nfc_genl_dump_ses_done net: sched: use Qdisc rcu API instead of relying on rtnl lock net: sched: add helper function to take reference to Qdisc net: sched: extend Qdisc with rcu net: sched: rename qdisc_destroy() to qdisc_put() net: core: netlink: add helper refcount dec and lock function can: sja1000: fix use after free in ems_pcmcia_add_card() can: kvaser_usb: get CAN clock frequency from device HID: check for valid USB device for many HID drivers HID: wacom: fix problems when device is not a valid USB device HID: add USB_HID dependancy on some USB HID drivers HID: add USB_HID dependancy to hid-chicony HID: add USB_HID dependancy to hid-prodikeys HID: add hid_is_usb() function to make it simpler for USB detection HID: google: add eel USB id UPSTREAM: USB: gadget: zero allocate endpoint 0 buffers UPSTREAM: USB: gadget: detect too-big endpoint 0 requests Linux 4.19.220 ipmi: msghandler: Make symbol 'remove_work_wq' static parisc: Mark cr16 CPU clocksource unstable on all SMP machines serial: core: fix transmit-buffer reset and memleak serial: pl011: Add ACPI SBSA UART match id tty: serial: msm_serial: Deactivate RX DMA for polling support x86/64/mm: Map all kernel memory into trampoline_pgd usb: typec: tcpm: Wait in SNK_DEBOUNCED until disconnect USB: NO_LPM quirk Lenovo Powered USB-C Travel Hub xhci: Fix commad ring abort, write all 64 bits to CRCR register. vgacon: Propagate console boot parameters before calling `vc_resize' parisc: Fix "make install" on newer debian releases parisc: Fix KBUILD_IMAGE for self-extracting kernel drm/msm: Do hw_init() before capturing GPU state net/smc: Keep smc_close_final rc during active close net/rds: correct socket tunable error in rds_tcp_tune() net: annotate data-races on txq->xmit_lock_owner net: usb: lan78xx: lan78xx_phy_init(): use PHY_POLL instead of "0" if no IRQ is available rxrpc: Fix rxrpc_local leak in rxrpc_lookup_peer() net/mlx4_en: Fix an use-after-free bug in mlx4_en_try_alloc_resources() siphash: use _unaligned version by default net: mpls: Fix notifications when deleting a device net: qlogic: qlcnic: Fix a NULL pointer dereference in qlcnic_83xx_add_rings() natsemi: xtensa: fix section mismatch warnings i2c: stm32f7: stop dma transfer in case of NACK i2c: stm32f7: recover the bus on access timeout fget: check that the fd still exists after getting a ref to it fs: add fget_many() and fput_many() sata_fsl: fix warning in remove_proc_entry when rmmod sata_fsl sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl ipmi: Move remove_work to dedicated workqueue kprobes: Limit max data_size of the kretprobe instances vrf: Reset IPCB/IP6CB when processing outbound pkts in vrf dev xmit perf hist: Fix memory leak of a perf_hpp_fmt net: ethernet: dec: tulip: de4x5: fix possible array overflows in type3_infoblock() net: tulip: de4x5: fix the problem that the array 'lp->phy[8]' may be out of bound ethernet: hisilicon: hns: hns_dsaf_misc: fix a possible array overflow in hns_dsaf_ge_srst_by_port() ata: ahci: Add Green Sardine vendor ID as board_ahci_mobile scsi: iscsi: Unblock session then wake up error handler thermal: core: Reset previous low and high trip during thermal zone init btrfs: check-integrity: fix a warning on write caching disabled disk s390/setup: avoid using memblock_enforce_memory_limit platform/x86: thinkpad_acpi: Fix WWAN device disabled issue after S3 deep net: return correct error code atlantic: Fix OOB read and write in hw_atl_utils_fw_rpc_wait gfs2: Fix length of holes reported at end-of-file of: clk: Make <linux/of_clk.h> self-contained NFSv42: Fix pagecache invalidation after COPY/CLONE shm: extend forced shm destroy to support objects from several IPC nses Conflicts: drivers/hid/hid-holtek-mouse.c (used theirs) drivers/usb/gadget/legacy/dbgp.c Change-Id: I7d36754e28ada463e28de2fbd95a5d8c9c9554d9 Signed-off-by: bengris32 <bengris32@protonmail.ch>
This commit is contained in:
@@ -1448,6 +1448,8 @@
|
||||
architectures force reset to be always executed
|
||||
i8042.unlock [HW] Unlock (ignore) the keylock
|
||||
i8042.kbdreset [HW] Reset device connected to KBD port
|
||||
i8042.probe_defer
|
||||
[HW] Allow deferred probing upon i8042 probe errors
|
||||
|
||||
i810= [HW,DRM]
|
||||
|
||||
@@ -2037,8 +2039,12 @@
|
||||
Default is 1 (enabled)
|
||||
|
||||
kvm-intel.emulate_invalid_guest_state=
|
||||
[KVM,Intel] Enable emulation of invalid guest states
|
||||
Default is 0 (disabled)
|
||||
[KVM,Intel] Disable emulation of invalid guest state.
|
||||
Ignored if kvm-intel.enable_unrestricted_guest=1, as
|
||||
guest state is never invalid for unrestricted guests.
|
||||
This param doesn't apply to nested guests (L2), as KVM
|
||||
never emulates invalid L2 guest state.
|
||||
Default is 1 (enabled)
|
||||
|
||||
kvm-intel.flexpriority=
|
||||
[KVM,Intel] Disable FlexPriority feature (TPR shadow).
|
||||
|
||||
@@ -191,11 +191,12 @@ ad_actor_sys_prio
|
||||
ad_actor_system
|
||||
|
||||
In an AD system, this specifies the mac-address for the actor in
|
||||
protocol packet exchanges (LACPDUs). The value cannot be NULL or
|
||||
multicast. It is preferred to have the local-admin bit set for this
|
||||
mac but driver does not enforce it. If the value is not given then
|
||||
system defaults to using the masters' mac address as actors' system
|
||||
address.
|
||||
protocol packet exchanges (LACPDUs). The value cannot be a multicast
|
||||
address. If the all-zeroes MAC is specified, bonding will internally
|
||||
use the MAC of the bond itself. It is preferred to have the
|
||||
local-admin bit set for this mac but driver does not enforce it. If
|
||||
the value is not given then system defaults to using the masters'
|
||||
mac address as actors' system address.
|
||||
|
||||
This parameter has effect only in 802.3ad mode and is available through
|
||||
SysFs interface.
|
||||
|
||||
4
Makefile
4
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 19
|
||||
SUBLEVEL = 219
|
||||
SUBLEVEL = 224
|
||||
EXTRAVERSION =
|
||||
NAME = "People's Front"
|
||||
|
||||
@@ -1265,7 +1265,7 @@ endef
|
||||
|
||||
define filechk_version.h
|
||||
(echo \#define LINUX_VERSION_CODE $(shell \
|
||||
expr $(VERSION) \* 65536 + 0$(PATCHLEVEL) \* 256 + 0$(SUBLEVEL)); \
|
||||
expr $(VERSION) \* 65536 + 0$(PATCHLEVEL) \* 256 + 255); \
|
||||
echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';)
|
||||
endef
|
||||
|
||||
|
||||
140684
android/abi_gki_aarch64.xml
140684
android/abi_gki_aarch64.xml
File diff suppressed because it is too large
Load Diff
@@ -982,6 +982,9 @@ config HAVE_ARCH_PREL32_RELOCATIONS
|
||||
architectures, and don't require runtime relocation on relocatable
|
||||
kernels.
|
||||
|
||||
config ARCH_USE_MEMREMAP_PROT
|
||||
bool
|
||||
|
||||
# Select if the architecture has support for applying RELR relocations.
|
||||
config ARCH_HAS_RELR
|
||||
bool
|
||||
|
||||
@@ -68,6 +68,6 @@
|
||||
#define MX6ULL_PAD_CSI_DATA04__ESAI_TX_FS 0x01F4 0x0480 0x0000 0x9 0x0
|
||||
#define MX6ULL_PAD_CSI_DATA05__ESAI_TX_CLK 0x01F8 0x0484 0x0000 0x9 0x0
|
||||
#define MX6ULL_PAD_CSI_DATA06__ESAI_TX5_RX0 0x01FC 0x0488 0x0000 0x9 0x0
|
||||
#define MX6ULL_PAD_CSI_DATA07__ESAI_T0 0x0200 0x048C 0x0000 0x9 0x0
|
||||
#define MX6ULL_PAD_CSI_DATA07__ESAI_TX0 0x0200 0x048C 0x0000 0x9 0x0
|
||||
|
||||
#endif /* __DTS_IMX6ULL_PINFUNC_H */
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
flash0: n25q00@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "n25q00aa";
|
||||
compatible = "micron,mt25qu02g", "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <100000000>;
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
flash: flash@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "n25q256a";
|
||||
compatible = "micron,n25q256a", "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <100000000>;
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
flash0: n25q00@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "n25q00";
|
||||
compatible = "micron,mt25qu02g", "jedec,spi-nor";
|
||||
reg = <0>; /* chip select */
|
||||
spi-max-frequency = <100000000>;
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@
|
||||
flash: flash@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "n25q00";
|
||||
compatible = "micron,mt25qu02g", "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <100000000>;
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
flash: flash@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "n25q256a";
|
||||
compatible = "micron,n25q256a", "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <100000000>;
|
||||
m25p,fast-read;
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
flash0: n25q512a@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "n25q512a";
|
||||
compatible = "micron,n25q512a", "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <100000000>;
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
n25q128@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "n25q128";
|
||||
compatible = "micron,n25q128", "jedec,spi-nor";
|
||||
reg = <0>; /* chip select */
|
||||
spi-max-frequency = <100000000>;
|
||||
m25p,fast-read;
|
||||
@@ -266,7 +266,7 @@
|
||||
n25q00@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "n25q00";
|
||||
compatible = "micron,mt25qu02g", "jedec,spi-nor";
|
||||
reg = <1>; /* chip select */
|
||||
spi-max-frequency = <100000000>;
|
||||
m25p,fast-read;
|
||||
|
||||
@@ -620,11 +620,9 @@ call_fpe:
|
||||
tstne r0, #0x04000000 @ bit 26 set on both ARM and Thumb-2
|
||||
reteq lr
|
||||
and r8, r0, #0x00000f00 @ mask out CP number
|
||||
THUMB( lsr r8, r8, #8 )
|
||||
mov r7, #1
|
||||
add r6, r10, #TI_USED_CP
|
||||
ARM( strb r7, [r6, r8, lsr #8] ) @ set appropriate used_cp[]
|
||||
THUMB( strb r7, [r6, r8] ) @ set appropriate used_cp[]
|
||||
add r6, r10, r8, lsr #8 @ add used_cp[] array offset first
|
||||
strb r7, [r6, #TI_USED_CP] @ set appropriate used_cp[]
|
||||
#ifdef CONFIG_IWMMXT
|
||||
@ Test if we need to give access to iWMMXt coprocessors
|
||||
ldr r5, [r10, #TI_FLAGS]
|
||||
@@ -633,7 +631,7 @@ call_fpe:
|
||||
bcs iwmmxt_task_enable
|
||||
#endif
|
||||
ARM( add pc, pc, r8, lsr #6 )
|
||||
THUMB( lsl r8, r8, #2 )
|
||||
THUMB( lsr r8, r8, #6 )
|
||||
THUMB( add pc, r8 )
|
||||
nop
|
||||
|
||||
|
||||
@@ -17,26 +17,25 @@
|
||||
/*
|
||||
* Faraday optimised copy_user_page
|
||||
*/
|
||||
static void __naked
|
||||
fa_copy_user_page(void *kto, const void *kfrom)
|
||||
static void fa_copy_user_page(void *kto, const void *kfrom)
|
||||
{
|
||||
asm("\
|
||||
stmfd sp!, {r4, lr} @ 2\n\
|
||||
mov r2, %0 @ 1\n\
|
||||
1: ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
||||
stmia r0, {r3, r4, ip, lr} @ 4\n\
|
||||
mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\
|
||||
add r0, r0, #16 @ 1\n\
|
||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
||||
stmia r0, {r3, r4, ip, lr} @ 4\n\
|
||||
mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\
|
||||
add r0, r0, #16 @ 1\n\
|
||||
subs r2, r2, #1 @ 1\n\
|
||||
int tmp;
|
||||
|
||||
asm volatile ("\
|
||||
1: ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||
stmia %0, {r3, r4, ip, lr} @ 4\n\
|
||||
mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
|
||||
add %0, %0, #16 @ 1\n\
|
||||
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||
stmia %0, {r3, r4, ip, lr} @ 4\n\
|
||||
mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
|
||||
add %0, %0, #16 @ 1\n\
|
||||
subs %2, %2, #1 @ 1\n\
|
||||
bne 1b @ 1\n\
|
||||
mcr p15, 0, r2, c7, c10, 4 @ 1 drain WB\n\
|
||||
ldmfd sp!, {r4, pc} @ 3"
|
||||
:
|
||||
: "I" (PAGE_SIZE / 32));
|
||||
mcr p15, 0, %2, c7, c10, 4 @ 1 drain WB"
|
||||
: "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
||||
: "2" (PAGE_SIZE / 32)
|
||||
: "r3", "r4", "ip", "lr");
|
||||
}
|
||||
|
||||
void fa_copy_user_highpage(struct page *to, struct page *from,
|
||||
|
||||
@@ -13,58 +13,56 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/highmem.h>
|
||||
|
||||
static void __naked
|
||||
feroceon_copy_user_page(void *kto, const void *kfrom)
|
||||
static void feroceon_copy_user_page(void *kto, const void *kfrom)
|
||||
{
|
||||
asm("\
|
||||
stmfd sp!, {r4-r9, lr} \n\
|
||||
mov ip, %2 \n\
|
||||
1: mov lr, r1 \n\
|
||||
ldmia r1!, {r2 - r9} \n\
|
||||
pld [lr, #32] \n\
|
||||
pld [lr, #64] \n\
|
||||
pld [lr, #96] \n\
|
||||
pld [lr, #128] \n\
|
||||
pld [lr, #160] \n\
|
||||
pld [lr, #192] \n\
|
||||
pld [lr, #224] \n\
|
||||
stmia r0, {r2 - r9} \n\
|
||||
ldmia r1!, {r2 - r9} \n\
|
||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add r0, r0, #32 \n\
|
||||
stmia r0, {r2 - r9} \n\
|
||||
ldmia r1!, {r2 - r9} \n\
|
||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add r0, r0, #32 \n\
|
||||
stmia r0, {r2 - r9} \n\
|
||||
ldmia r1!, {r2 - r9} \n\
|
||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add r0, r0, #32 \n\
|
||||
stmia r0, {r2 - r9} \n\
|
||||
ldmia r1!, {r2 - r9} \n\
|
||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add r0, r0, #32 \n\
|
||||
stmia r0, {r2 - r9} \n\
|
||||
ldmia r1!, {r2 - r9} \n\
|
||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add r0, r0, #32 \n\
|
||||
stmia r0, {r2 - r9} \n\
|
||||
ldmia r1!, {r2 - r9} \n\
|
||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add r0, r0, #32 \n\
|
||||
stmia r0, {r2 - r9} \n\
|
||||
ldmia r1!, {r2 - r9} \n\
|
||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add r0, r0, #32 \n\
|
||||
stmia r0, {r2 - r9} \n\
|
||||
subs ip, ip, #(32 * 8) \n\
|
||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add r0, r0, #32 \n\
|
||||
int tmp;
|
||||
|
||||
asm volatile ("\
|
||||
1: ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||
pld [%1, #0] \n\
|
||||
pld [%1, #32] \n\
|
||||
pld [%1, #64] \n\
|
||||
pld [%1, #96] \n\
|
||||
pld [%1, #128] \n\
|
||||
pld [%1, #160] \n\
|
||||
pld [%1, #192] \n\
|
||||
stmia %0, {r2 - r7, ip, lr} \n\
|
||||
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add %0, %0, #32 \n\
|
||||
stmia %0, {r2 - r7, ip, lr} \n\
|
||||
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add %0, %0, #32 \n\
|
||||
stmia %0, {r2 - r7, ip, lr} \n\
|
||||
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add %0, %0, #32 \n\
|
||||
stmia %0, {r2 - r7, ip, lr} \n\
|
||||
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add %0, %0, #32 \n\
|
||||
stmia %0, {r2 - r7, ip, lr} \n\
|
||||
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add %0, %0, #32 \n\
|
||||
stmia %0, {r2 - r7, ip, lr} \n\
|
||||
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add %0, %0, #32 \n\
|
||||
stmia %0, {r2 - r7, ip, lr} \n\
|
||||
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add %0, %0, #32 \n\
|
||||
stmia %0, {r2 - r7, ip, lr} \n\
|
||||
subs %2, %2, #(32 * 8) \n\
|
||||
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||
add %0, %0, #32 \n\
|
||||
bne 1b \n\
|
||||
mcr p15, 0, ip, c7, c10, 4 @ drain WB\n\
|
||||
ldmfd sp!, {r4-r9, pc}"
|
||||
:
|
||||
: "r" (kto), "r" (kfrom), "I" (PAGE_SIZE));
|
||||
mcr p15, 0, %2, c7, c10, 4 @ drain WB"
|
||||
: "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
||||
: "2" (PAGE_SIZE)
|
||||
: "r2", "r3", "r4", "r5", "r6", "r7", "ip", "lr");
|
||||
}
|
||||
|
||||
void feroceon_copy_user_highpage(struct page *to, struct page *from,
|
||||
|
||||
@@ -40,12 +40,11 @@ static DEFINE_RAW_SPINLOCK(minicache_lock);
|
||||
* instruction. If your processor does not supply this, you have to write your
|
||||
* own copy_user_highpage that does the right thing.
|
||||
*/
|
||||
static void __naked
|
||||
mc_copy_user_page(void *from, void *to)
|
||||
static void mc_copy_user_page(void *from, void *to)
|
||||
{
|
||||
asm volatile(
|
||||
"stmfd sp!, {r4, lr} @ 2\n\
|
||||
mov r4, %2 @ 1\n\
|
||||
int tmp;
|
||||
|
||||
asm volatile ("\
|
||||
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
|
||||
1: mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
|
||||
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
||||
@@ -55,13 +54,13 @@ mc_copy_user_page(void *from, void *to)
|
||||
mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
|
||||
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
||||
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
|
||||
subs r4, r4, #1 @ 1\n\
|
||||
subs %2, %2, #1 @ 1\n\
|
||||
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
||||
ldmneia %0!, {r2, r3, ip, lr} @ 4\n\
|
||||
bne 1b @ 1\n\
|
||||
ldmfd sp!, {r4, pc} @ 3"
|
||||
:
|
||||
: "r" (from), "r" (to), "I" (PAGE_SIZE / 64));
|
||||
bne 1b @ "
|
||||
: "+&r" (from), "+&r" (to), "=&r" (tmp)
|
||||
: "2" (PAGE_SIZE / 64)
|
||||
: "r2", "r3", "ip", "lr");
|
||||
}
|
||||
|
||||
void v4_mc_copy_user_highpage(struct page *to, struct page *from,
|
||||
|
||||
@@ -22,29 +22,28 @@
|
||||
* instruction. If your processor does not supply this, you have to write your
|
||||
* own copy_user_highpage that does the right thing.
|
||||
*/
|
||||
static void __naked
|
||||
v4wb_copy_user_page(void *kto, const void *kfrom)
|
||||
static void v4wb_copy_user_page(void *kto, const void *kfrom)
|
||||
{
|
||||
asm("\
|
||||
stmfd sp!, {r4, lr} @ 2\n\
|
||||
mov r2, %2 @ 1\n\
|
||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
||||
1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
|
||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\
|
||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
||||
mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
|
||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
||||
subs r2, r2, #1 @ 1\n\
|
||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmneia r1!, {r3, r4, ip, lr} @ 4\n\
|
||||
int tmp;
|
||||
|
||||
asm volatile ("\
|
||||
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||
1: mcr p15, 0, %0, c7, c6, 1 @ 1 invalidate D line\n\
|
||||
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmia %1!, {r3, r4, ip, lr} @ 4+1\n\
|
||||
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||
mcr p15, 0, %0, c7, c6, 1 @ 1 invalidate D line\n\
|
||||
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||
subs %2, %2, #1 @ 1\n\
|
||||
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmneia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||
bne 1b @ 1\n\
|
||||
mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB\n\
|
||||
ldmfd sp!, {r4, pc} @ 3"
|
||||
:
|
||||
: "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
|
||||
mcr p15, 0, %1, c7, c10, 4 @ 1 drain WB"
|
||||
: "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
||||
: "2" (PAGE_SIZE / 64)
|
||||
: "r3", "r4", "ip", "lr");
|
||||
}
|
||||
|
||||
void v4wb_copy_user_highpage(struct page *to, struct page *from,
|
||||
|
||||
@@ -20,27 +20,26 @@
|
||||
* dirty data in the cache. However, we do have to ensure that
|
||||
* subsequent reads are up to date.
|
||||
*/
|
||||
static void __naked
|
||||
v4wt_copy_user_page(void *kto, const void *kfrom)
|
||||
static void v4wt_copy_user_page(void *kto, const void *kfrom)
|
||||
{
|
||||
asm("\
|
||||
stmfd sp!, {r4, lr} @ 2\n\
|
||||
mov r2, %2 @ 1\n\
|
||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
||||
1: stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\
|
||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
||||
subs r2, r2, #1 @ 1\n\
|
||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmneia r1!, {r3, r4, ip, lr} @ 4\n\
|
||||
int tmp;
|
||||
|
||||
asm volatile ("\
|
||||
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||
1: stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmia %1!, {r3, r4, ip, lr} @ 4+1\n\
|
||||
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||
subs %2, %2, #1 @ 1\n\
|
||||
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||
ldmneia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||
bne 1b @ 1\n\
|
||||
mcr p15, 0, r2, c7, c7, 0 @ flush ID cache\n\
|
||||
ldmfd sp!, {r4, pc} @ 3"
|
||||
:
|
||||
: "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
|
||||
mcr p15, 0, %2, c7, c7, 0 @ flush ID cache"
|
||||
: "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
||||
: "2" (PAGE_SIZE / 64)
|
||||
: "r3", "r4", "ip", "lr");
|
||||
}
|
||||
|
||||
void v4wt_copy_user_highpage(struct page *to, struct page *from,
|
||||
|
||||
@@ -21,53 +21,46 @@
|
||||
|
||||
/*
|
||||
* XSC3 optimised copy_user_highpage
|
||||
* r0 = destination
|
||||
* r1 = source
|
||||
*
|
||||
* The source page may have some clean entries in the cache already, but we
|
||||
* can safely ignore them - break_cow() will flush them out of the cache
|
||||
* if we eventually end up using our copied page.
|
||||
*
|
||||
*/
|
||||
static void __naked
|
||||
xsc3_mc_copy_user_page(void *kto, const void *kfrom)
|
||||
static void xsc3_mc_copy_user_page(void *kto, const void *kfrom)
|
||||
{
|
||||
asm("\
|
||||
stmfd sp!, {r4, r5, lr} \n\
|
||||
mov lr, %2 \n\
|
||||
int tmp;
|
||||
|
||||
asm volatile ("\
|
||||
pld [%1, #0] \n\
|
||||
pld [%1, #32] \n\
|
||||
1: pld [%1, #64] \n\
|
||||
pld [%1, #96] \n\
|
||||
\n\
|
||||
pld [r1, #0] \n\
|
||||
pld [r1, #32] \n\
|
||||
1: pld [r1, #64] \n\
|
||||
pld [r1, #96] \n\
|
||||
\n\
|
||||
2: ldrd r2, [r1], #8 \n\
|
||||
mov ip, r0 \n\
|
||||
ldrd r4, [r1], #8 \n\
|
||||
mcr p15, 0, ip, c7, c6, 1 @ invalidate\n\
|
||||
strd r2, [r0], #8 \n\
|
||||
ldrd r2, [r1], #8 \n\
|
||||
strd r4, [r0], #8 \n\
|
||||
ldrd r4, [r1], #8 \n\
|
||||
strd r2, [r0], #8 \n\
|
||||
strd r4, [r0], #8 \n\
|
||||
ldrd r2, [r1], #8 \n\
|
||||
mov ip, r0 \n\
|
||||
ldrd r4, [r1], #8 \n\
|
||||
mcr p15, 0, ip, c7, c6, 1 @ invalidate\n\
|
||||
strd r2, [r0], #8 \n\
|
||||
ldrd r2, [r1], #8 \n\
|
||||
subs lr, lr, #1 \n\
|
||||
strd r4, [r0], #8 \n\
|
||||
ldrd r4, [r1], #8 \n\
|
||||
strd r2, [r0], #8 \n\
|
||||
strd r4, [r0], #8 \n\
|
||||
2: ldrd r2, [%1], #8 \n\
|
||||
ldrd r4, [%1], #8 \n\
|
||||
mcr p15, 0, %0, c7, c6, 1 @ invalidate\n\
|
||||
strd r2, [%0], #8 \n\
|
||||
ldrd r2, [%1], #8 \n\
|
||||
strd r4, [%0], #8 \n\
|
||||
ldrd r4, [%1], #8 \n\
|
||||
strd r2, [%0], #8 \n\
|
||||
strd r4, [%0], #8 \n\
|
||||
ldrd r2, [%1], #8 \n\
|
||||
ldrd r4, [%1], #8 \n\
|
||||
mcr p15, 0, %0, c7, c6, 1 @ invalidate\n\
|
||||
strd r2, [%0], #8 \n\
|
||||
ldrd r2, [%1], #8 \n\
|
||||
subs %2, %2, #1 \n\
|
||||
strd r4, [%0], #8 \n\
|
||||
ldrd r4, [%1], #8 \n\
|
||||
strd r2, [%0], #8 \n\
|
||||
strd r4, [%0], #8 \n\
|
||||
bgt 1b \n\
|
||||
beq 2b \n\
|
||||
\n\
|
||||
ldmfd sp!, {r4, r5, pc}"
|
||||
:
|
||||
: "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64 - 1));
|
||||
beq 2b "
|
||||
: "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
||||
: "2" (PAGE_SIZE / 64 - 1)
|
||||
: "r2", "r3", "r4", "r5");
|
||||
}
|
||||
|
||||
void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
|
||||
@@ -85,8 +78,6 @@ void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
|
||||
|
||||
/*
|
||||
* XScale optimised clear_user_page
|
||||
* r0 = destination
|
||||
* r1 = virtual user address of ultimate destination page
|
||||
*/
|
||||
void xsc3_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
|
||||
{
|
||||
|
||||
@@ -36,52 +36,51 @@ static DEFINE_RAW_SPINLOCK(minicache_lock);
|
||||
* Dcache aliasing issue. The writes will be forwarded to the write buffer,
|
||||
* and merged as appropriate.
|
||||
*/
|
||||
static void __naked
|
||||
mc_copy_user_page(void *from, void *to)
|
||||
static void mc_copy_user_page(void *from, void *to)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
/*
|
||||
* Strangely enough, best performance is achieved
|
||||
* when prefetching destination as well. (NP)
|
||||
*/
|
||||
asm volatile(
|
||||
"stmfd sp!, {r4, r5, lr} \n\
|
||||
mov lr, %2 \n\
|
||||
pld [r0, #0] \n\
|
||||
pld [r0, #32] \n\
|
||||
pld [r1, #0] \n\
|
||||
pld [r1, #32] \n\
|
||||
1: pld [r0, #64] \n\
|
||||
pld [r0, #96] \n\
|
||||
pld [r1, #64] \n\
|
||||
pld [r1, #96] \n\
|
||||
2: ldrd r2, [r0], #8 \n\
|
||||
ldrd r4, [r0], #8 \n\
|
||||
mov ip, r1 \n\
|
||||
strd r2, [r1], #8 \n\
|
||||
ldrd r2, [r0], #8 \n\
|
||||
strd r4, [r1], #8 \n\
|
||||
ldrd r4, [r0], #8 \n\
|
||||
strd r2, [r1], #8 \n\
|
||||
strd r4, [r1], #8 \n\
|
||||
asm volatile ("\
|
||||
pld [%0, #0] \n\
|
||||
pld [%0, #32] \n\
|
||||
pld [%1, #0] \n\
|
||||
pld [%1, #32] \n\
|
||||
1: pld [%0, #64] \n\
|
||||
pld [%0, #96] \n\
|
||||
pld [%1, #64] \n\
|
||||
pld [%1, #96] \n\
|
||||
2: ldrd r2, [%0], #8 \n\
|
||||
ldrd r4, [%0], #8 \n\
|
||||
mov ip, %1 \n\
|
||||
strd r2, [%1], #8 \n\
|
||||
ldrd r2, [%0], #8 \n\
|
||||
strd r4, [%1], #8 \n\
|
||||
ldrd r4, [%0], #8 \n\
|
||||
strd r2, [%1], #8 \n\
|
||||
strd r4, [%1], #8 \n\
|
||||
mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
|
||||
ldrd r2, [r0], #8 \n\
|
||||
ldrd r2, [%0], #8 \n\
|
||||
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
|
||||
ldrd r4, [r0], #8 \n\
|
||||
mov ip, r1 \n\
|
||||
strd r2, [r1], #8 \n\
|
||||
ldrd r2, [r0], #8 \n\
|
||||
strd r4, [r1], #8 \n\
|
||||
ldrd r4, [r0], #8 \n\
|
||||
strd r2, [r1], #8 \n\
|
||||
strd r4, [r1], #8 \n\
|
||||
ldrd r4, [%0], #8 \n\
|
||||
mov ip, %1 \n\
|
||||
strd r2, [%1], #8 \n\
|
||||
ldrd r2, [%0], #8 \n\
|
||||
strd r4, [%1], #8 \n\
|
||||
ldrd r4, [%0], #8 \n\
|
||||
strd r2, [%1], #8 \n\
|
||||
strd r4, [%1], #8 \n\
|
||||
mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
|
||||
subs lr, lr, #1 \n\
|
||||
subs %2, %2, #1 \n\
|
||||
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
|
||||
bgt 1b \n\
|
||||
beq 2b \n\
|
||||
ldmfd sp!, {r4, r5, pc} "
|
||||
:
|
||||
: "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1));
|
||||
beq 2b "
|
||||
: "+&r" (from), "+&r" (to), "=&r" (tmp)
|
||||
: "2" (PAGE_SIZE / 64 - 1)
|
||||
: "r2", "r3", "r4", "r5", "ip");
|
||||
}
|
||||
|
||||
void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
pinctrl-0 = <&emac_rgmii_pins>;
|
||||
phy-supply = <®_gmac_3v3>;
|
||||
phy-handle = <&ext_rgmii_phy>;
|
||||
phy-mode = "rgmii";
|
||||
phy-mode = "rgmii-id";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -17,7 +17,12 @@
|
||||
# Mike Shaver, Helge Deller and Martin K. Petersen
|
||||
#
|
||||
|
||||
ifdef CONFIG_PARISC_SELF_EXTRACT
|
||||
boot := arch/parisc/boot
|
||||
KBUILD_IMAGE := $(boot)/bzImage
|
||||
else
|
||||
KBUILD_IMAGE := vmlinuz
|
||||
endif
|
||||
|
||||
KBUILD_DEFCONFIG := default_defconfig
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ verify "$3"
|
||||
if [ -n "${INSTALLKERNEL}" ]; then
|
||||
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
|
||||
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
|
||||
if [ -x /usr/sbin/${INSTALLKERNEL} ]; then exec /usr/sbin/${INSTALLKERNEL} "$@"; fi
|
||||
fi
|
||||
|
||||
# Default install
|
||||
|
||||
@@ -478,7 +478,7 @@ lws_start:
|
||||
extrd,u %r1,PSW_W_BIT,1,%r1
|
||||
/* sp must be aligned on 4, so deposit the W bit setting into
|
||||
* the bottom of sp temporarily */
|
||||
or,ev %r1,%r30,%r30
|
||||
or,od %r1,%r30,%r30
|
||||
|
||||
/* Clip LWS number to a 32-bit value for 32-bit processes */
|
||||
depdi 0, 31, 32, %r20
|
||||
|
||||
@@ -245,27 +245,13 @@ void __init time_init(void)
|
||||
static int __init init_cr16_clocksource(void)
|
||||
{
|
||||
/*
|
||||
* The cr16 interval timers are not syncronized across CPUs on
|
||||
* different sockets, so mark them unstable and lower rating on
|
||||
* multi-socket SMP systems.
|
||||
* The cr16 interval timers are not syncronized across CPUs, even if
|
||||
* they share the same socket.
|
||||
*/
|
||||
if (num_online_cpus() > 1 && !running_on_qemu) {
|
||||
int cpu;
|
||||
unsigned long cpu0_loc;
|
||||
cpu0_loc = per_cpu(cpu_data, 0).cpu_loc;
|
||||
|
||||
for_each_online_cpu(cpu) {
|
||||
if (cpu == 0)
|
||||
continue;
|
||||
if ((cpu0_loc != 0) &&
|
||||
(cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc))
|
||||
continue;
|
||||
|
||||
clocksource_cr16.name = "cr16_unstable";
|
||||
clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE;
|
||||
clocksource_cr16.rating = 0;
|
||||
break;
|
||||
}
|
||||
clocksource_cr16.name = "cr16_unstable";
|
||||
clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE;
|
||||
clocksource_cr16.rating = 0;
|
||||
}
|
||||
|
||||
/* XXX: We may want to mark sched_clock stable here if cr16 clocks are
|
||||
|
||||
@@ -703,9 +703,6 @@ static void __init setup_memory(void)
|
||||
storage_key_init_range(reg->base, reg->base + reg->size);
|
||||
}
|
||||
psw_set_key(PAGE_DEFAULT_KEY);
|
||||
|
||||
/* Only cosmetics */
|
||||
memblock_enforce_memory_limit(memblock_end_of_DRAM());
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1492,6 +1492,7 @@ config AMD_MEM_ENCRYPT
|
||||
bool "AMD Secure Memory Encryption (SME) support"
|
||||
depends on X86_64 && CPU_SUP_AMD
|
||||
select DYNAMIC_PHYSICAL_MASK
|
||||
select ARCH_USE_MEMREMAP_PROT
|
||||
---help---
|
||||
Say yes to enable support for the encryption of system memory.
|
||||
This requires an AMD processor that supports Secure Memory
|
||||
@@ -1510,10 +1511,6 @@ config AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT
|
||||
If set to N, then the encryption of system memory can be
|
||||
activated with the mem_encrypt=on command line option.
|
||||
|
||||
config ARCH_USE_MEMREMAP_PROT
|
||||
def_bool y
|
||||
depends on AMD_MEM_ENCRYPT
|
||||
|
||||
# Common NUMA Features
|
||||
config NUMA
|
||||
bool "Numa Memory Allocation and Scheduler Support"
|
||||
@@ -1956,6 +1953,7 @@ config EFI
|
||||
depends on ACPI
|
||||
select UCS2_STRING
|
||||
select EFI_RUNTIME_WRAPPERS
|
||||
select ARCH_USE_MEMREMAP_PROT
|
||||
---help---
|
||||
This enables the kernel to use EFI runtime services that are
|
||||
available (such as the EFI variable services).
|
||||
|
||||
@@ -1356,8 +1356,8 @@ static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define PKRU_AD_BIT 0x1
|
||||
#define PKRU_WD_BIT 0x2
|
||||
#define PKRU_AD_BIT 0x1u
|
||||
#define PKRU_WD_BIT 0x2u
|
||||
#define PKRU_BITS_PER_PKEY 2
|
||||
|
||||
static inline bool __pkru_allows_read(u32 pkru, u16 pkey)
|
||||
|
||||
@@ -697,7 +697,7 @@ bool phys_mem_access_encrypted(unsigned long phys_addr, unsigned long size)
|
||||
return arch_memremap_can_ram_remap(phys_addr, size, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_USE_MEMREMAP_PROT
|
||||
#ifdef CONFIG_AMD_MEM_ENCRYPT
|
||||
/* Remap memory with encryption */
|
||||
void __init *early_memremap_encrypted(resource_size_t phys_addr,
|
||||
unsigned long size)
|
||||
@@ -739,7 +739,7 @@ void __init *early_memremap_decrypted_wp(resource_size_t phys_addr,
|
||||
|
||||
return early_memremap_prot(phys_addr, size, __PAGE_KERNEL_NOENC_WP);
|
||||
}
|
||||
#endif /* CONFIG_ARCH_USE_MEMREMAP_PROT */
|
||||
#endif /* CONFIG_AMD_MEM_ENCRYPT */
|
||||
|
||||
static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
|
||||
|
||||
|
||||
@@ -278,7 +278,8 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
|
||||
return;
|
||||
}
|
||||
|
||||
new = early_memremap(new_phys, new_size);
|
||||
new = early_memremap_prot(new_phys, new_size,
|
||||
pgprot_val(pgprot_encrypted(FIXMAP_PAGE_NORMAL)));
|
||||
if (!new) {
|
||||
pr_err("Failed to map new boot services memmap\n");
|
||||
return;
|
||||
|
||||
@@ -55,6 +55,7 @@ static void __init setup_real_mode(void)
|
||||
#ifdef CONFIG_X86_64
|
||||
u64 *trampoline_pgd;
|
||||
u64 efer;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
base = (unsigned char *)real_mode_header;
|
||||
@@ -113,8 +114,17 @@ static void __init setup_real_mode(void)
|
||||
trampoline_header->flags |= TH_FLAGS_SME_ACTIVE;
|
||||
|
||||
trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd);
|
||||
|
||||
/* Map the real mode stub as virtual == physical */
|
||||
trampoline_pgd[0] = trampoline_pgd_entry.pgd;
|
||||
trampoline_pgd[511] = init_top_pgt[511].pgd;
|
||||
|
||||
/*
|
||||
* Include the entirety of the kernel mapping into the trampoline
|
||||
* PGD. This way, all mappings present in the normal kernel page
|
||||
* tables are usable while running on trampoline_pgd.
|
||||
*/
|
||||
for (i = pgd_index(__PAGE_OFFSET); i < PTRS_PER_PGD; i++)
|
||||
trampoline_pgd[i] = init_top_pgt[i].pgd;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -625,12 +625,13 @@ void bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell whether there are active queues or groups with differentiated weights.
|
||||
* Tell whether there are active queues with different weights or
|
||||
* active groups.
|
||||
*/
|
||||
static bool bfq_differentiated_weights(struct bfq_data *bfqd)
|
||||
static bool bfq_varied_queue_weights_or_active_groups(struct bfq_data *bfqd)
|
||||
{
|
||||
/*
|
||||
* For weights to differ, at least one of the trees must contain
|
||||
* For queue weights to differ, queue_weights_tree must contain
|
||||
* at least two nodes.
|
||||
*/
|
||||
return (!RB_EMPTY_ROOT(&bfqd->queue_weights_tree) &&
|
||||
@@ -638,9 +639,7 @@ static bool bfq_differentiated_weights(struct bfq_data *bfqd)
|
||||
bfqd->queue_weights_tree.rb_node->rb_right)
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
) ||
|
||||
(!RB_EMPTY_ROOT(&bfqd->group_weights_tree) &&
|
||||
(bfqd->group_weights_tree.rb_node->rb_left ||
|
||||
bfqd->group_weights_tree.rb_node->rb_right)
|
||||
(bfqd->num_groups_with_pending_reqs > 0
|
||||
#endif
|
||||
);
|
||||
}
|
||||
@@ -658,26 +657,25 @@ static bool bfq_differentiated_weights(struct bfq_data *bfqd)
|
||||
* 3) all active groups at the same level in the groups tree have the same
|
||||
* number of children.
|
||||
*
|
||||
* Unfortunately, keeping the necessary state for evaluating exactly the
|
||||
* above symmetry conditions would be quite complex and time-consuming.
|
||||
* Therefore this function evaluates, instead, the following stronger
|
||||
* sub-conditions, for which it is much easier to maintain the needed
|
||||
* state:
|
||||
* Unfortunately, keeping the necessary state for evaluating exactly
|
||||
* the last two symmetry sub-conditions above would be quite complex
|
||||
* and time consuming. Therefore this function evaluates, instead,
|
||||
* only the following stronger two sub-conditions, for which it is
|
||||
* much easier to maintain the needed state:
|
||||
* 1) all active queues have the same weight,
|
||||
* 2) all active groups have the same weight,
|
||||
* 3) all active groups have at most one active child each.
|
||||
* In particular, the last two conditions are always true if hierarchical
|
||||
* support and the cgroups interface are not enabled, thus no state needs
|
||||
* to be maintained in this case.
|
||||
* 2) there are no active groups.
|
||||
* In particular, the last condition is always true if hierarchical
|
||||
* support or the cgroups interface are not enabled, thus no state
|
||||
* needs to be maintained in this case.
|
||||
*/
|
||||
static bool bfq_symmetric_scenario(struct bfq_data *bfqd)
|
||||
{
|
||||
return !bfq_differentiated_weights(bfqd);
|
||||
return !bfq_varied_queue_weights_or_active_groups(bfqd);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the weight-counter tree passed as input contains no counter for
|
||||
* the weight of the input entity, then add that counter; otherwise just
|
||||
* the weight of the input queue, then add that counter; otherwise just
|
||||
* increment the existing counter.
|
||||
*
|
||||
* Note that weight-counter trees contain few nodes in mostly symmetric
|
||||
@@ -688,25 +686,25 @@ static bool bfq_symmetric_scenario(struct bfq_data *bfqd)
|
||||
* In most scenarios, the rate at which nodes are created/destroyed
|
||||
* should be low too.
|
||||
*/
|
||||
void bfq_weights_tree_add(struct bfq_data *bfqd, struct bfq_entity *entity,
|
||||
void bfq_weights_tree_add(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
struct rb_root *root)
|
||||
{
|
||||
struct bfq_entity *entity = &bfqq->entity;
|
||||
struct rb_node **new = &(root->rb_node), *parent = NULL;
|
||||
|
||||
/*
|
||||
* Do not insert if the entity is already associated with a
|
||||
* Do not insert if the queue is already associated with a
|
||||
* counter, which happens if:
|
||||
* 1) the entity is associated with a queue,
|
||||
* 2) a request arrival has caused the queue to become both
|
||||
* 1) a request arrival has caused the queue to become both
|
||||
* non-weight-raised, and hence change its weight, and
|
||||
* backlogged; in this respect, each of the two events
|
||||
* causes an invocation of this function,
|
||||
* 3) this is the invocation of this function caused by the
|
||||
* 2) this is the invocation of this function caused by the
|
||||
* second event. This second invocation is actually useless,
|
||||
* and we handle this fact by exiting immediately. More
|
||||
* efficient or clearer solutions might possibly be adopted.
|
||||
*/
|
||||
if (entity->weight_counter)
|
||||
if (bfqq->weight_counter)
|
||||
return;
|
||||
|
||||
while (*new) {
|
||||
@@ -716,7 +714,7 @@ void bfq_weights_tree_add(struct bfq_data *bfqd, struct bfq_entity *entity,
|
||||
parent = *new;
|
||||
|
||||
if (entity->weight == __counter->weight) {
|
||||
entity->weight_counter = __counter;
|
||||
bfqq->weight_counter = __counter;
|
||||
goto inc_counter;
|
||||
}
|
||||
if (entity->weight < __counter->weight)
|
||||
@@ -725,68 +723,68 @@ void bfq_weights_tree_add(struct bfq_data *bfqd, struct bfq_entity *entity,
|
||||
new = &((*new)->rb_right);
|
||||
}
|
||||
|
||||
entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter),
|
||||
GFP_ATOMIC);
|
||||
bfqq->weight_counter = kzalloc(sizeof(struct bfq_weight_counter),
|
||||
GFP_ATOMIC);
|
||||
|
||||
/*
|
||||
* In the unlucky event of an allocation failure, we just
|
||||
* exit. This will cause the weight of entity to not be
|
||||
* considered in bfq_differentiated_weights, which, in its
|
||||
* turn, causes the scenario to be deemed wrongly symmetric in
|
||||
* case entity's weight would have been the only weight making
|
||||
* the scenario asymmetric. On the bright side, no unbalance
|
||||
* will however occur when entity becomes inactive again (the
|
||||
* invocation of this function is triggered by an activation
|
||||
* of entity). In fact, bfq_weights_tree_remove does nothing
|
||||
* if !entity->weight_counter.
|
||||
* exit. This will cause the weight of queue to not be
|
||||
* considered in bfq_varied_queue_weights_or_active_groups,
|
||||
* which, in its turn, causes the scenario to be deemed
|
||||
* wrongly symmetric in case bfqq's weight would have been
|
||||
* the only weight making the scenario asymmetric. On the
|
||||
* bright side, no unbalance will however occur when bfqq
|
||||
* becomes inactive again (the invocation of this function
|
||||
* is triggered by an activation of queue). In fact,
|
||||
* bfq_weights_tree_remove does nothing if
|
||||
* !bfqq->weight_counter.
|
||||
*/
|
||||
if (unlikely(!entity->weight_counter))
|
||||
if (unlikely(!bfqq->weight_counter))
|
||||
return;
|
||||
|
||||
entity->weight_counter->weight = entity->weight;
|
||||
rb_link_node(&entity->weight_counter->weights_node, parent, new);
|
||||
rb_insert_color(&entity->weight_counter->weights_node, root);
|
||||
bfqq->weight_counter->weight = entity->weight;
|
||||
rb_link_node(&bfqq->weight_counter->weights_node, parent, new);
|
||||
rb_insert_color(&bfqq->weight_counter->weights_node, root);
|
||||
|
||||
inc_counter:
|
||||
entity->weight_counter->num_active++;
|
||||
bfqq->weight_counter->num_active++;
|
||||
bfqq->ref++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrement the weight counter associated with the entity, and, if the
|
||||
* Decrement the weight counter associated with the queue, and, if the
|
||||
* counter reaches 0, remove the counter from the tree.
|
||||
* See the comments to the function bfq_weights_tree_add() for considerations
|
||||
* about overhead.
|
||||
*/
|
||||
void __bfq_weights_tree_remove(struct bfq_data *bfqd,
|
||||
struct bfq_entity *entity,
|
||||
struct bfq_queue *bfqq,
|
||||
struct rb_root *root)
|
||||
{
|
||||
if (!entity->weight_counter)
|
||||
if (!bfqq->weight_counter)
|
||||
return;
|
||||
|
||||
entity->weight_counter->num_active--;
|
||||
if (entity->weight_counter->num_active > 0)
|
||||
bfqq->weight_counter->num_active--;
|
||||
if (bfqq->weight_counter->num_active > 0)
|
||||
goto reset_entity_pointer;
|
||||
|
||||
rb_erase(&entity->weight_counter->weights_node, root);
|
||||
kfree(entity->weight_counter);
|
||||
rb_erase(&bfqq->weight_counter->weights_node, root);
|
||||
kfree(bfqq->weight_counter);
|
||||
|
||||
reset_entity_pointer:
|
||||
entity->weight_counter = NULL;
|
||||
bfqq->weight_counter = NULL;
|
||||
bfq_put_queue(bfqq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoke __bfq_weights_tree_remove on bfqq and all its inactive
|
||||
* parent entities.
|
||||
* Invoke __bfq_weights_tree_remove on bfqq and decrement the number
|
||||
* of active groups for each queue's inactive parent entity.
|
||||
*/
|
||||
void bfq_weights_tree_remove(struct bfq_data *bfqd,
|
||||
struct bfq_queue *bfqq)
|
||||
{
|
||||
struct bfq_entity *entity = bfqq->entity.parent;
|
||||
|
||||
__bfq_weights_tree_remove(bfqd, &bfqq->entity,
|
||||
&bfqd->queue_weights_tree);
|
||||
|
||||
for_each_entity(entity) {
|
||||
struct bfq_sched_data *sd = entity->my_sched_data;
|
||||
|
||||
@@ -798,18 +796,37 @@ void bfq_weights_tree_remove(struct bfq_data *bfqd,
|
||||
* next_in_service for details on why
|
||||
* in_service_entity must be checked too).
|
||||
*
|
||||
* As a consequence, the weight of entity is
|
||||
* not to be removed. In addition, if entity
|
||||
* is active, then its parent entities are
|
||||
* active as well, and thus their weights are
|
||||
* not to be removed either. In the end, this
|
||||
* loop must stop here.
|
||||
* As a consequence, its parent entities are
|
||||
* active as well, and thus this loop must
|
||||
* stop here.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
__bfq_weights_tree_remove(bfqd, entity,
|
||||
&bfqd->group_weights_tree);
|
||||
|
||||
/*
|
||||
* The decrement of num_groups_with_pending_reqs is
|
||||
* not performed immediately upon the deactivation of
|
||||
* entity, but it is delayed to when it also happens
|
||||
* that the first leaf descendant bfqq of entity gets
|
||||
* all its pending requests completed. The following
|
||||
* instructions perform this delayed decrement, if
|
||||
* needed. See the comments on
|
||||
* num_groups_with_pending_reqs for details.
|
||||
*/
|
||||
if (entity->in_groups_with_pending_reqs) {
|
||||
entity->in_groups_with_pending_reqs = false;
|
||||
bfqd->num_groups_with_pending_reqs--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Next function is invoked last, because it causes bfqq to be
|
||||
* freed if the following holds: bfqq is not in service and
|
||||
* has no dispatched request. DO NOT use bfqq after the next
|
||||
* function invocation.
|
||||
*/
|
||||
__bfq_weights_tree_remove(bfqd, bfqq,
|
||||
&bfqd->queue_weights_tree);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1003,7 +1020,8 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
|
||||
|
||||
static int bfqq_process_refs(struct bfq_queue *bfqq)
|
||||
{
|
||||
return bfqq->ref - bfqq->allocated - bfqq->entity.on_st;
|
||||
return bfqq->ref - bfqq->allocated - bfqq->entity.on_st -
|
||||
(bfqq->weight_counter != NULL);
|
||||
}
|
||||
|
||||
/* Empty burst list and add just bfqq (see comments on bfq_handle_burst) */
|
||||
@@ -2798,7 +2816,7 @@ static void bfq_dispatch_remove(struct request_queue *q, struct request *rq)
|
||||
bfq_remove_request(q, rq);
|
||||
}
|
||||
|
||||
static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
static bool __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
{
|
||||
/*
|
||||
* If this bfqq is shared between multiple processes, check
|
||||
@@ -2831,9 +2849,11 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
/*
|
||||
* All in-service entities must have been properly deactivated
|
||||
* or requeued before executing the next function, which
|
||||
* resets all in-service entites as no more in service.
|
||||
* resets all in-service entities as no more in service. This
|
||||
* may cause bfqq to be freed. If this happens, the next
|
||||
* function returns true.
|
||||
*/
|
||||
__bfq_bfqd_reset_in_service(bfqd);
|
||||
return __bfq_bfqd_reset_in_service(bfqd);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3238,7 +3258,6 @@ void bfq_bfqq_expire(struct bfq_data *bfqd,
|
||||
bool slow;
|
||||
unsigned long delta = 0;
|
||||
struct bfq_entity *entity = &bfqq->entity;
|
||||
int ref;
|
||||
|
||||
/*
|
||||
* Check whether the process is slow (see bfq_bfqq_is_slow).
|
||||
@@ -3307,10 +3326,8 @@ void bfq_bfqq_expire(struct bfq_data *bfqd,
|
||||
* reason.
|
||||
*/
|
||||
__bfq_bfqq_recalc_budget(bfqd, bfqq, reason);
|
||||
ref = bfqq->ref;
|
||||
__bfq_bfqq_expire(bfqd, bfqq);
|
||||
|
||||
if (ref == 1) /* bfqq is gone, no more actions on it */
|
||||
if (__bfq_bfqq_expire(bfqd, bfqq))
|
||||
/* bfqq is gone, no more actions on it */
|
||||
return;
|
||||
|
||||
bfqq->injected_service = 0;
|
||||
@@ -3521,9 +3538,11 @@ static bool bfq_better_to_idle(struct bfq_queue *bfqq)
|
||||
* symmetric scenario where:
|
||||
* (i) each of these processes must get the same throughput as
|
||||
* the others;
|
||||
* (ii) all these processes have the same I/O pattern
|
||||
(either sequential or random).
|
||||
* In fact, in such a scenario, the drive will tend to treat
|
||||
* (ii) the I/O of each process has the same properties, in
|
||||
* terms of locality (sequential or random), direction
|
||||
* (reads or writes), request sizes, greediness
|
||||
* (from I/O-bound to sporadic), and so on.
|
||||
* In fact, in such a scenario, the drive tends to treat
|
||||
* the requests of each of these processes in about the same
|
||||
* way as the requests of the others, and thus to provide
|
||||
* each of these processes with about the same throughput
|
||||
@@ -3532,18 +3551,67 @@ static bool bfq_better_to_idle(struct bfq_queue *bfqq)
|
||||
* certainly needed to guarantee that bfqq receives its
|
||||
* assigned fraction of the device throughput (see [1] for
|
||||
* details).
|
||||
* The problem is that idling may significantly reduce
|
||||
* throughput with certain combinations of types of I/O and
|
||||
* devices. An important example is sync random I/O, on flash
|
||||
* storage with command queueing. So, unless bfqq falls in the
|
||||
* above cases where idling also boosts throughput, it would
|
||||
* be important to check conditions (i) and (ii) accurately,
|
||||
* so as to avoid idling when not strictly needed for service
|
||||
* guarantees.
|
||||
*
|
||||
* We address this issue by controlling, actually, only the
|
||||
* symmetry sub-condition (i), i.e., provided that
|
||||
* sub-condition (i) holds, idling is not performed,
|
||||
* regardless of whether sub-condition (ii) holds. In other
|
||||
* words, only if sub-condition (i) holds, then idling is
|
||||
* allowed, and the device tends to be prevented from queueing
|
||||
* many requests, possibly of several processes. The reason
|
||||
* for not controlling also sub-condition (ii) is that we
|
||||
* exploit preemption to preserve guarantees in case of
|
||||
* symmetric scenarios, even if (ii) does not hold, as
|
||||
* explained in the next two paragraphs.
|
||||
* Unfortunately, it is extremely difficult to thoroughly
|
||||
* check condition (ii). And, in case there are active groups,
|
||||
* it becomes very difficult to check condition (i) too. In
|
||||
* fact, if there are active groups, then, for condition (i)
|
||||
* to become false, it is enough that an active group contains
|
||||
* more active processes or sub-groups than some other active
|
||||
* group. More precisely, for condition (i) to hold because of
|
||||
* such a group, it is not even necessary that the group is
|
||||
* (still) active: it is sufficient that, even if the group
|
||||
* has become inactive, some of its descendant processes still
|
||||
* have some request already dispatched but still waiting for
|
||||
* completion. In fact, requests have still to be guaranteed
|
||||
* their share of the throughput even after being
|
||||
* dispatched. In this respect, it is easy to show that, if a
|
||||
* group frequently becomes inactive while still having
|
||||
* in-flight requests, and if, when this happens, the group is
|
||||
* not considered in the calculation of whether the scenario
|
||||
* is asymmetric, then the group may fail to be guaranteed its
|
||||
* fair share of the throughput (basically because idling may
|
||||
* not be performed for the descendant processes of the group,
|
||||
* but it had to be). We address this issue with the
|
||||
* following bi-modal behavior, implemented in the function
|
||||
* bfq_symmetric_scenario().
|
||||
*
|
||||
* If there are groups with requests waiting for completion
|
||||
* (as commented above, some of these groups may even be
|
||||
* already inactive), then the scenario is tagged as
|
||||
* asymmetric, conservatively, without checking any of the
|
||||
* conditions (i) and (ii). So the device is idled for bfqq.
|
||||
* This behavior matches also the fact that groups are created
|
||||
* exactly if controlling I/O is a primary concern (to
|
||||
* preserve bandwidth and latency guarantees).
|
||||
*
|
||||
* On the opposite end, if there are no groups with requests
|
||||
* waiting for completion, then only condition (i) is actually
|
||||
* controlled, i.e., provided that condition (i) holds, idling
|
||||
* is not performed, regardless of whether condition (ii)
|
||||
* holds. In other words, only if condition (i) does not hold,
|
||||
* then idling is allowed, and the device tends to be
|
||||
* prevented from queueing many requests, possibly of several
|
||||
* processes. Since there are no groups with requests waiting
|
||||
* for completion, then, to control condition (i) it is enough
|
||||
* to check just whether all the queues with requests waiting
|
||||
* for completion also have the same weight.
|
||||
*
|
||||
* Not checking condition (ii) evidently exposes bfqq to the
|
||||
* risk of getting less throughput than its fair share.
|
||||
* However, for queues with the same weight, a further
|
||||
* mechanism, preemption, mitigates or even eliminates this
|
||||
* problem. And it does so without consequences on overall
|
||||
* throughput. This mechanism and its benefits are explained
|
||||
* in the next three paragraphs.
|
||||
*
|
||||
* Even if a queue, say Q, is expired when it remains idle, Q
|
||||
* can still preempt the new in-service queue if the next
|
||||
@@ -3557,11 +3625,7 @@ static bool bfq_better_to_idle(struct bfq_queue *bfqq)
|
||||
* idling allows the internal queues of the device to contain
|
||||
* many requests, and thus to reorder requests, we can rather
|
||||
* safely assume that the internal scheduler still preserves a
|
||||
* minimum of mid-term fairness. The motivation for using
|
||||
* preemption instead of idling is that, by not idling,
|
||||
* service guarantees are preserved without minimally
|
||||
* sacrificing throughput. In other words, both a high
|
||||
* throughput and its desired distribution are obtained.
|
||||
* minimum of mid-term fairness.
|
||||
*
|
||||
* More precisely, this preemption-based, idleless approach
|
||||
* provides fairness in terms of IOPS, and not sectors per
|
||||
@@ -3580,27 +3644,28 @@ static bool bfq_better_to_idle(struct bfq_queue *bfqq)
|
||||
* 1024/8 times as high as the service received by the other
|
||||
* queue.
|
||||
*
|
||||
* On the other hand, device idling is performed, and thus
|
||||
* pure sector-domain guarantees are provided, for the
|
||||
* following queues, which are likely to need stronger
|
||||
* throughput guarantees: weight-raised queues, and queues
|
||||
* with a higher weight than other queues. When such queues
|
||||
* are active, sub-condition (i) is false, which triggers
|
||||
* device idling.
|
||||
* The motivation for using preemption instead of idling (for
|
||||
* queues with the same weight) is that, by not idling,
|
||||
* service guarantees are preserved (completely or at least in
|
||||
* part) without minimally sacrificing throughput. And, if
|
||||
* there is no active group, then the primary expectation for
|
||||
* this device is probably a high throughput.
|
||||
*
|
||||
* According to the above considerations, the next variable is
|
||||
* true (only) if sub-condition (i) holds. To compute the
|
||||
* value of this variable, we not only use the return value of
|
||||
* the function bfq_symmetric_scenario(), but also check
|
||||
* whether bfqq is being weight-raised, because
|
||||
* bfq_symmetric_scenario() does not take into account also
|
||||
* weight-raised queues (see comments on
|
||||
* bfq_weights_tree_add()). In particular, if bfqq is being
|
||||
* weight-raised, it is important to idle only if there are
|
||||
* other, non-weight-raised queues that may steal throughput
|
||||
* to bfqq. Actually, we should be even more precise, and
|
||||
* differentiate between interactive weight raising and
|
||||
* soft real-time weight raising.
|
||||
* We are now left only with explaining the additional
|
||||
* compound condition that is checked below for deciding
|
||||
* whether the scenario is asymmetric. To explain this
|
||||
* compound condition, we need to add that the function
|
||||
* bfq_symmetric_scenario checks the weights of only
|
||||
* non-weight-raised queues, for efficiency reasons (see
|
||||
* comments on bfq_weights_tree_add()). Then the fact that
|
||||
* bfqq is weight-raised is checked explicitly here. More
|
||||
* precisely, the compound condition below takes into account
|
||||
* also the fact that, even if bfqq is being weight-raised,
|
||||
* the scenario is still symmetric if all queues with requests
|
||||
* waiting for completion happen to be
|
||||
* weight-raised. Actually, we should be even more precise
|
||||
* here, and differentiate between interactive weight raising
|
||||
* and soft real-time weight raising.
|
||||
*
|
||||
* As a side note, it is worth considering that the above
|
||||
* device-idling countermeasures may however fail in the
|
||||
@@ -5422,7 +5487,7 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
|
||||
bfqd->idle_slice_timer.function = bfq_idle_slice_timer;
|
||||
|
||||
bfqd->queue_weights_tree = RB_ROOT;
|
||||
bfqd->group_weights_tree = RB_ROOT;
|
||||
bfqd->num_groups_with_pending_reqs = 0;
|
||||
|
||||
INIT_LIST_HEAD(&bfqd->active_list);
|
||||
INIT_LIST_HEAD(&bfqd->idle_list);
|
||||
|
||||
@@ -108,15 +108,14 @@ struct bfq_sched_data {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct bfq_weight_counter - counter of the number of all active entities
|
||||
* struct bfq_weight_counter - counter of the number of all active queues
|
||||
* with a given weight.
|
||||
*/
|
||||
struct bfq_weight_counter {
|
||||
unsigned int weight; /* weight of the entities this counter refers to */
|
||||
unsigned int num_active; /* nr of active entities with this weight */
|
||||
unsigned int weight; /* weight of the queues this counter refers to */
|
||||
unsigned int num_active; /* nr of active queues with this weight */
|
||||
/*
|
||||
* Weights tree member (see bfq_data's @queue_weights_tree and
|
||||
* @group_weights_tree)
|
||||
* Weights tree member (see bfq_data's @queue_weights_tree)
|
||||
*/
|
||||
struct rb_node weights_node;
|
||||
};
|
||||
@@ -151,8 +150,6 @@ struct bfq_weight_counter {
|
||||
struct bfq_entity {
|
||||
/* service_tree member */
|
||||
struct rb_node rb_node;
|
||||
/* pointer to the weight counter associated with this entity */
|
||||
struct bfq_weight_counter *weight_counter;
|
||||
|
||||
/*
|
||||
* Flag, true if the entity is on a tree (either the active or
|
||||
@@ -199,6 +196,9 @@ struct bfq_entity {
|
||||
|
||||
/* flag, set to request a weight, ioprio or ioprio_class change */
|
||||
int prio_changed;
|
||||
|
||||
/* flag, set if the entity is counted in groups_with_pending_reqs */
|
||||
bool in_groups_with_pending_reqs;
|
||||
};
|
||||
|
||||
struct bfq_group;
|
||||
@@ -266,6 +266,9 @@ struct bfq_queue {
|
||||
/* entity representing this queue in the scheduler */
|
||||
struct bfq_entity entity;
|
||||
|
||||
/* pointer to the weight counter associated with this entity */
|
||||
struct bfq_weight_counter *weight_counter;
|
||||
|
||||
/* maximum budget allowed from the feedback mechanism */
|
||||
int max_budget;
|
||||
/* budget expiration (in jiffies) */
|
||||
@@ -448,15 +451,54 @@ struct bfq_data {
|
||||
* bfq_weights_tree_[add|remove] for further details).
|
||||
*/
|
||||
struct rb_root queue_weights_tree;
|
||||
|
||||
/*
|
||||
* rbtree of non-queue @bfq_entity weight counters, sorted by
|
||||
* weight. Used to keep track of whether all @bfq_groups have
|
||||
* the same weight. The tree contains one counter for each
|
||||
* distinct weight associated to some active @bfq_group (see
|
||||
* the comments to the functions bfq_weights_tree_[add|remove]
|
||||
* for further details).
|
||||
* Number of groups with at least one descendant process that
|
||||
* has at least one request waiting for completion. Note that
|
||||
* this accounts for also requests already dispatched, but not
|
||||
* yet completed. Therefore this number of groups may differ
|
||||
* (be larger) than the number of active groups, as a group is
|
||||
* considered active only if its corresponding entity has
|
||||
* descendant queues with at least one request queued. This
|
||||
* number is used to decide whether a scenario is symmetric.
|
||||
* For a detailed explanation see comments on the computation
|
||||
* of the variable asymmetric_scenario in the function
|
||||
* bfq_better_to_idle().
|
||||
*
|
||||
* However, it is hard to compute this number exactly, for
|
||||
* groups with multiple descendant processes. Consider a group
|
||||
* that is inactive, i.e., that has no descendant process with
|
||||
* pending I/O inside BFQ queues. Then suppose that
|
||||
* num_groups_with_pending_reqs is still accounting for this
|
||||
* group, because the group has descendant processes with some
|
||||
* I/O request still in flight. num_groups_with_pending_reqs
|
||||
* should be decremented when the in-flight request of the
|
||||
* last descendant process is finally completed (assuming that
|
||||
* nothing else has changed for the group in the meantime, in
|
||||
* terms of composition of the group and active/inactive state of child
|
||||
* groups and processes). To accomplish this, an additional
|
||||
* pending-request counter must be added to entities, and must
|
||||
* be updated correctly. To avoid this additional field and operations,
|
||||
* we resort to the following tradeoff between simplicity and
|
||||
* accuracy: for an inactive group that is still counted in
|
||||
* num_groups_with_pending_reqs, we decrement
|
||||
* num_groups_with_pending_reqs when the first descendant
|
||||
* process of the group remains with no request waiting for
|
||||
* completion.
|
||||
*
|
||||
* Even this simpler decrement strategy requires a little
|
||||
* carefulness: to avoid multiple decrements, we flag a group,
|
||||
* more precisely an entity representing a group, as still
|
||||
* counted in num_groups_with_pending_reqs when it becomes
|
||||
* inactive. Then, when the first descendant queue of the
|
||||
* entity remains with no request waiting for completion,
|
||||
* num_groups_with_pending_reqs is decremented, and this flag
|
||||
* is reset. After this flag is reset for the entity,
|
||||
* num_groups_with_pending_reqs won't be decremented any
|
||||
* longer in case a new descendant queue of the entity remains
|
||||
* with no request waiting for completion.
|
||||
*/
|
||||
struct rb_root group_weights_tree;
|
||||
unsigned int num_groups_with_pending_reqs;
|
||||
|
||||
/*
|
||||
* Number of bfq_queues containing requests (including the
|
||||
@@ -854,10 +896,10 @@ struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic, bool is_sync);
|
||||
void bic_set_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq, bool is_sync);
|
||||
struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic);
|
||||
void bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq);
|
||||
void bfq_weights_tree_add(struct bfq_data *bfqd, struct bfq_entity *entity,
|
||||
void bfq_weights_tree_add(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
struct rb_root *root);
|
||||
void __bfq_weights_tree_remove(struct bfq_data *bfqd,
|
||||
struct bfq_entity *entity,
|
||||
struct bfq_queue *bfqq,
|
||||
struct rb_root *root);
|
||||
void bfq_weights_tree_remove(struct bfq_data *bfqd,
|
||||
struct bfq_queue *bfqq);
|
||||
@@ -951,7 +993,7 @@ bool __bfq_deactivate_entity(struct bfq_entity *entity,
|
||||
bool ins_into_idle_tree);
|
||||
bool next_queue_may_preempt(struct bfq_data *bfqd);
|
||||
struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd);
|
||||
void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd);
|
||||
bool __bfq_bfqd_reset_in_service(struct bfq_data *bfqd);
|
||||
void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
bool ins_into_idle_tree, bool expiration);
|
||||
void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq);
|
||||
|
||||
@@ -788,25 +788,23 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
|
||||
new_weight = entity->orig_weight *
|
||||
(bfqq ? bfqq->wr_coeff : 1);
|
||||
/*
|
||||
* If the weight of the entity changes, remove the entity
|
||||
* from its old weight counter (if there is a counter
|
||||
* associated with the entity), and add it to the counter
|
||||
* associated with its new weight.
|
||||
* If the weight of the entity changes, and the entity is a
|
||||
* queue, remove the entity from its old weight counter (if
|
||||
* there is a counter associated with the entity).
|
||||
*/
|
||||
if (prev_weight != new_weight) {
|
||||
root = bfqq ? &bfqd->queue_weights_tree :
|
||||
&bfqd->group_weights_tree;
|
||||
__bfq_weights_tree_remove(bfqd, entity, root);
|
||||
if (prev_weight != new_weight && bfqq) {
|
||||
root = &bfqd->queue_weights_tree;
|
||||
__bfq_weights_tree_remove(bfqd, bfqq, root);
|
||||
}
|
||||
entity->weight = new_weight;
|
||||
/*
|
||||
* Add the entity to its weights tree only if it is
|
||||
* not associated with a weight-raised queue.
|
||||
* Add the entity, if it is not a weight-raised queue,
|
||||
* to the counter associated with its new weight.
|
||||
*/
|
||||
if (prev_weight != new_weight &&
|
||||
(bfqq ? bfqq->wr_coeff == 1 : 1))
|
||||
if (prev_weight != new_weight && bfqq && bfqq->wr_coeff == 1) {
|
||||
/* If we get here, root has been initialized. */
|
||||
bfq_weights_tree_add(bfqd, entity, root);
|
||||
bfq_weights_tree_add(bfqd, bfqq, root);
|
||||
}
|
||||
|
||||
new_st->wsum += entity->weight;
|
||||
|
||||
@@ -1012,9 +1010,12 @@ static void __bfq_activate_entity(struct bfq_entity *entity,
|
||||
if (!bfq_entity_to_bfqq(entity)) { /* bfq_group */
|
||||
struct bfq_group *bfqg =
|
||||
container_of(entity, struct bfq_group, entity);
|
||||
struct bfq_data *bfqd = bfqg->bfqd;
|
||||
|
||||
bfq_weights_tree_add(bfqg->bfqd, entity,
|
||||
&bfqd->group_weights_tree);
|
||||
if (!entity->in_groups_with_pending_reqs) {
|
||||
entity->in_groups_with_pending_reqs = true;
|
||||
bfqd->num_groups_with_pending_reqs++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1599,7 +1600,8 @@ struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
|
||||
return bfqq;
|
||||
}
|
||||
|
||||
void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
|
||||
/* returns true if the in-service queue gets freed */
|
||||
bool __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
|
||||
{
|
||||
struct bfq_queue *in_serv_bfqq = bfqd->in_service_queue;
|
||||
struct bfq_entity *in_serv_entity = &in_serv_bfqq->entity;
|
||||
@@ -1623,8 +1625,20 @@ void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
|
||||
* service tree either, then release the service reference to
|
||||
* the queue it represents (taken with bfq_get_entity).
|
||||
*/
|
||||
if (!in_serv_entity->on_st)
|
||||
if (!in_serv_entity->on_st) {
|
||||
/*
|
||||
* If no process is referencing in_serv_bfqq any
|
||||
* longer, then the service reference may be the only
|
||||
* reference to the queue. If this is the case, then
|
||||
* bfqq gets freed here.
|
||||
*/
|
||||
int ref = in_serv_bfqq->ref;
|
||||
bfq_put_queue(in_serv_bfqq);
|
||||
if (ref == 1)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
@@ -1667,15 +1681,15 @@ void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
|
||||
bfqd->busy_queues--;
|
||||
|
||||
if (!bfqq->dispatched)
|
||||
bfq_weights_tree_remove(bfqd, bfqq);
|
||||
|
||||
if (bfqq->wr_coeff > 1)
|
||||
bfqd->wr_busy_queues--;
|
||||
|
||||
bfqg_stats_update_dequeue(bfqq_group(bfqq));
|
||||
|
||||
bfq_deactivate_bfqq(bfqd, bfqq, true, expiration);
|
||||
|
||||
if (!bfqq->dispatched)
|
||||
bfq_weights_tree_remove(bfqd, bfqq);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1692,7 +1706,7 @@ void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
|
||||
if (!bfqq->dispatched)
|
||||
if (bfqq->wr_coeff == 1)
|
||||
bfq_weights_tree_add(bfqd, &bfqq->entity,
|
||||
bfq_weights_tree_add(bfqd, bfqq,
|
||||
&bfqd->queue_weights_tree);
|
||||
|
||||
if (bfqq->wr_coeff > 1)
|
||||
|
||||
@@ -206,6 +206,7 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
|
||||
pgrp = task_pgrp(current);
|
||||
else
|
||||
pgrp = find_vpid(who);
|
||||
read_lock(&tasklist_lock);
|
||||
do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
|
||||
tmpio = get_task_ioprio(p);
|
||||
if (tmpio < 0)
|
||||
@@ -215,6 +216,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
|
||||
else
|
||||
ret = ioprio_best(ret, tmpio);
|
||||
} while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
|
||||
read_unlock(&tasklist_lock);
|
||||
|
||||
break;
|
||||
case IOPRIO_WHO_USER:
|
||||
uid = make_kuid(current_user_ns(), who);
|
||||
|
||||
@@ -670,7 +670,7 @@ static void binder_free_buf_locked(struct binder_alloc *alloc,
|
||||
BUG_ON(buffer->user_data > alloc->buffer + alloc->buffer_size);
|
||||
|
||||
if (buffer->async_transaction) {
|
||||
alloc->free_async_space += size + sizeof(struct binder_buffer);
|
||||
alloc->free_async_space += buffer_size + sizeof(struct binder_buffer);
|
||||
|
||||
binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC,
|
||||
"%d: binder_free_buf size %zd async free %zd\n",
|
||||
|
||||
@@ -436,6 +436,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
/* AMD */
|
||||
{ PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */
|
||||
{ PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */
|
||||
{ PCI_VDEVICE(AMD, 0x7901), board_ahci_mobile }, /* AMD Green Sardine */
|
||||
/* AMD is using RAID class only for ahci controllers */
|
||||
{ PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||
PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci },
|
||||
|
||||
@@ -4453,6 +4453,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
||||
{ "VRFDFC22048UCHC-TE*", NULL, ATA_HORKAGE_NODMA },
|
||||
/* Odd clown on sil3726/4726 PMPs */
|
||||
{ "Config Disk", NULL, ATA_HORKAGE_DISABLE },
|
||||
/* Similar story with ASMedia 1092 */
|
||||
{ "ASMT109x- Config", NULL, ATA_HORKAGE_DISABLE },
|
||||
|
||||
/* Weird ATAPI devices */
|
||||
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 },
|
||||
|
||||
@@ -3181,8 +3181,19 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
|
||||
goto invalid_fld;
|
||||
}
|
||||
|
||||
if (ata_is_ncq(tf->protocol) && (cdb[2 + cdb_offset] & 0x3) == 0)
|
||||
tf->protocol = ATA_PROT_NCQ_NODATA;
|
||||
if ((cdb[2 + cdb_offset] & 0x3) == 0) {
|
||||
/*
|
||||
* When T_LENGTH is zero (No data is transferred), dir should
|
||||
* be DMA_NONE.
|
||||
*/
|
||||
if (scmd->sc_data_direction != DMA_NONE) {
|
||||
fp = 2 + cdb_offset;
|
||||
goto invalid_fld;
|
||||
}
|
||||
|
||||
if (ata_is_ncq(tf->protocol))
|
||||
tf->protocol = ATA_PROT_NCQ_NODATA;
|
||||
}
|
||||
|
||||
/* enable LBA */
|
||||
tf->flags |= ATA_TFLAG_LBA;
|
||||
|
||||
@@ -1399,6 +1399,14 @@ static int sata_fsl_init_controller(struct ata_host *host)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sata_fsl_host_stop(struct ata_host *host)
|
||||
{
|
||||
struct sata_fsl_host_priv *host_priv = host->private_data;
|
||||
|
||||
iounmap(host_priv->hcr_base);
|
||||
kfree(host_priv);
|
||||
}
|
||||
|
||||
/*
|
||||
* scsi mid-layer and libata interface structures
|
||||
*/
|
||||
@@ -1431,6 +1439,8 @@ static struct ata_port_operations sata_fsl_ops = {
|
||||
.port_start = sata_fsl_port_start,
|
||||
.port_stop = sata_fsl_port_stop,
|
||||
|
||||
.host_stop = sata_fsl_host_stop,
|
||||
|
||||
.pmp_attach = sata_fsl_pmp_attach,
|
||||
.pmp_detach = sata_fsl_pmp_detach,
|
||||
};
|
||||
@@ -1485,9 +1495,9 @@ static int sata_fsl_probe(struct platform_device *ofdev)
|
||||
host_priv->ssr_base = ssr_base;
|
||||
host_priv->csr_base = csr_base;
|
||||
|
||||
irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
|
||||
if (!irq) {
|
||||
dev_err(&ofdev->dev, "invalid irq from platform\n");
|
||||
irq = platform_get_irq(ofdev, 0);
|
||||
if (irq < 0) {
|
||||
retval = irq;
|
||||
goto error_exit_with_cleanup;
|
||||
}
|
||||
host_priv->irq = irq;
|
||||
@@ -1562,10 +1572,6 @@ static int sata_fsl_remove(struct platform_device *ofdev)
|
||||
|
||||
ata_host_detach(host);
|
||||
|
||||
irq_dispose_mapping(host_priv->irq);
|
||||
iounmap(host_priv->hcr_base);
|
||||
kfree(host_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1565,9 +1565,12 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
||||
unsigned long flags;
|
||||
struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)dev_id;
|
||||
struct blkfront_info *info = rinfo->dev_info;
|
||||
unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS;
|
||||
|
||||
if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
|
||||
if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
|
||||
xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&rinfo->ring_lock, flags);
|
||||
again:
|
||||
@@ -1583,6 +1586,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
||||
unsigned long id;
|
||||
unsigned int op;
|
||||
|
||||
eoiflag = 0;
|
||||
|
||||
RING_COPY_RESPONSE(&rinfo->ring, i, &bret);
|
||||
id = bret.id;
|
||||
|
||||
@@ -1698,6 +1703,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
||||
|
||||
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
|
||||
|
||||
xen_irq_lateeoi(irq, eoiflag);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
||||
err:
|
||||
@@ -1705,6 +1712,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
||||
|
||||
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
|
||||
|
||||
/* No EOI in order to avoid further interrupts. */
|
||||
|
||||
pr_alert("%s disabled for further use\n", info->gd->disk_name);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -1744,8 +1753,8 @@ static int setup_blkring(struct xenbus_device *dev,
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
err = bind_evtchn_to_irqhandler(rinfo->evtchn, blkif_interrupt, 0,
|
||||
"blkif", rinfo);
|
||||
err = bind_evtchn_to_irqhandler_lateeoi(rinfo->evtchn, blkif_interrupt,
|
||||
0, "blkif", rinfo);
|
||||
if (err <= 0) {
|
||||
xenbus_dev_fatal(dev, err,
|
||||
"bind_evtchn_to_irqhandler failed");
|
||||
|
||||
@@ -285,7 +285,7 @@ agp_ioc_init(void __iomem *ioc_regs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static int __init
|
||||
lba_find_capability(int cap)
|
||||
{
|
||||
struct _parisc_agp_info *info = &parisc_agp_info;
|
||||
@@ -370,7 +370,7 @@ fail:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
static int __init
|
||||
find_quicksilver(struct device *dev, void *data)
|
||||
{
|
||||
struct parisc_device **lba = data;
|
||||
@@ -382,7 +382,7 @@ find_quicksilver(struct device *dev, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static int __init
|
||||
parisc_agp_init(void)
|
||||
{
|
||||
extern struct sba_device *sba_list;
|
||||
|
||||
@@ -219,6 +219,8 @@ struct ipmi_user {
|
||||
struct work_struct remove_work;
|
||||
};
|
||||
|
||||
static struct workqueue_struct *remove_work_wq;
|
||||
|
||||
static struct ipmi_user *acquire_ipmi_user(struct ipmi_user *user, int *index)
|
||||
__acquires(user->release_barrier)
|
||||
{
|
||||
@@ -1207,7 +1209,7 @@ static void free_user(struct kref *ref)
|
||||
struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount);
|
||||
|
||||
/* SRCU cleanup must happen in task context. */
|
||||
schedule_work(&user->remove_work);
|
||||
queue_work(remove_work_wq, &user->remove_work);
|
||||
}
|
||||
|
||||
static void _ipmi_destroy_user(struct ipmi_user *user)
|
||||
@@ -2861,7 +2863,7 @@ cleanup_bmc_device(struct kref *ref)
|
||||
* with removing the device attributes while reading a device
|
||||
* attribute.
|
||||
*/
|
||||
schedule_work(&bmc->remove_work);
|
||||
queue_work(remove_work_wq, &bmc->remove_work);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5083,7 +5085,16 @@ static int ipmi_init_msghandler(void)
|
||||
if (initialized)
|
||||
goto out;
|
||||
|
||||
init_srcu_struct(&ipmi_interfaces_srcu);
|
||||
rv = init_srcu_struct(&ipmi_interfaces_srcu);
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
remove_work_wq = create_singlethread_workqueue("ipmi-msghandler-remove-wq");
|
||||
if (!remove_work_wq) {
|
||||
pr_err("unable to create ipmi-msghandler-remove-wq workqueue");
|
||||
rv = -ENOMEM;
|
||||
goto out_wq;
|
||||
}
|
||||
|
||||
timer_setup(&ipmi_timer, ipmi_timeout, 0);
|
||||
mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
|
||||
@@ -5092,6 +5103,9 @@ static int ipmi_init_msghandler(void)
|
||||
|
||||
initialized = true;
|
||||
|
||||
out_wq:
|
||||
if (rv)
|
||||
cleanup_srcu_struct(&ipmi_interfaces_srcu);
|
||||
out:
|
||||
mutex_unlock(&ipmi_interfaces_mutex);
|
||||
return rv;
|
||||
@@ -5115,6 +5129,8 @@ static void __exit cleanup_ipmi(void)
|
||||
int count;
|
||||
|
||||
if (initialized) {
|
||||
destroy_workqueue(remove_work_wq);
|
||||
|
||||
atomic_notifier_chain_unregister(&panic_notifier_list,
|
||||
&panic_block);
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ static u8 mux_get_parent(struct clk_hw *hw)
|
||||
val &= mask;
|
||||
|
||||
if (mux->parent_map)
|
||||
return qcom_find_src_index(hw, mux->parent_map, val);
|
||||
return qcom_find_cfg_index(hw, mux->parent_map, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -69,6 +69,18 @@ int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, u8 src)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_find_src_index);
|
||||
|
||||
int qcom_find_cfg_index(struct clk_hw *hw, const struct parent_map *map, u8 cfg)
|
||||
{
|
||||
int i, num_parents = clk_hw_get_num_parents(hw);
|
||||
|
||||
for (i = 0; i < num_parents; i++)
|
||||
if (cfg == map[i].cfg)
|
||||
return i;
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_find_cfg_index);
|
||||
|
||||
struct regmap *
|
||||
qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc)
|
||||
{
|
||||
|
||||
@@ -47,6 +47,8 @@ extern void
|
||||
qcom_pll_set_fsm_mode(struct regmap *m, u32 reg, u8 bias_count, u8 lock_count);
|
||||
extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map,
|
||||
u8 src);
|
||||
extern int qcom_find_cfg_index(struct clk_hw *hw, const struct parent_map *map,
|
||||
u8 cfg);
|
||||
|
||||
extern int qcom_cc_register_board_clk(struct device *dev, const char *path,
|
||||
const char *name, unsigned long rate);
|
||||
|
||||
@@ -886,4 +886,4 @@ MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("STMicroelectronics FDMA engine driver");
|
||||
MODULE_AUTHOR("Ludovic.barre <Ludovic.barre@st.com>");
|
||||
MODULE_AUTHOR("Peter Griffin <peter.griffin@linaro.org>");
|
||||
MODULE_ALIAS("platform: " DRIVER_NAME);
|
||||
MODULE_ALIAS("platform:" DRIVER_NAME);
|
||||
|
||||
@@ -27,7 +27,6 @@ struct scpi_pm_domain {
|
||||
struct generic_pm_domain genpd;
|
||||
struct scpi_ops *ops;
|
||||
u32 domain;
|
||||
char name[30];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -121,8 +120,13 @@ static int scpi_pm_domain_probe(struct platform_device *pdev)
|
||||
|
||||
scpi_pd->domain = i;
|
||||
scpi_pd->ops = scpi_ops;
|
||||
sprintf(scpi_pd->name, "%s.%d", np->name, i);
|
||||
scpi_pd->genpd.name = scpi_pd->name;
|
||||
scpi_pd->genpd.name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"%s.%d", np->name, i);
|
||||
if (!scpi_pd->genpd.name) {
|
||||
dev_err(dev, "Failed to allocate genpd name:%s.%d\n",
|
||||
np->name, i);
|
||||
continue;
|
||||
}
|
||||
scpi_pd->genpd.power_off = scpi_pd_power_off;
|
||||
scpi_pd->genpd.power_on = scpi_pd_power_on;
|
||||
|
||||
|
||||
@@ -2198,8 +2198,8 @@ static void gfx_v9_0_init_pg(struct amdgpu_device *adev)
|
||||
AMD_PG_SUPPORT_CP |
|
||||
AMD_PG_SUPPORT_GDS |
|
||||
AMD_PG_SUPPORT_RLC_SMU_HS)) {
|
||||
WREG32(mmRLC_JUMP_TABLE_RESTORE,
|
||||
adev->gfx.rlc.cp_table_gpu_addr >> 8);
|
||||
WREG32_SOC15(GC, 0, mmRLC_JUMP_TABLE_RESTORE,
|
||||
adev->gfx.rlc.cp_table_gpu_addr >> 8);
|
||||
gfx_v9_0_init_gfx_power_gating(adev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1677,6 +1677,8 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host,
|
||||
if (!prop) {
|
||||
dev_dbg(dev,
|
||||
"failed to find data lane mapping, using default\n");
|
||||
/* Set the number of date lanes to 4 by default. */
|
||||
msm_host->num_data_lanes = 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file)
|
||||
goto free_priv;
|
||||
|
||||
pm_runtime_get_sync(&gpu->pdev->dev);
|
||||
msm_gpu_hw_init(gpu);
|
||||
show_priv->state = gpu->funcs->gpu_state_get(gpu);
|
||||
pm_runtime_put_sync(&gpu->pdev->dev);
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ config HID_APPLEIR
|
||||
|
||||
config HID_ASUS
|
||||
tristate "Asus"
|
||||
depends on USB_HID
|
||||
depends on LEDS_CLASS
|
||||
---help---
|
||||
Support for Asus notebook built-in keyboard and touchpad via i2c, and
|
||||
|
||||
@@ -622,7 +622,7 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
if (drvdata->quirks & QUIRK_IS_MULTITOUCH)
|
||||
drvdata->tp = &asus_i2c_tp;
|
||||
|
||||
if (drvdata->quirks & QUIRK_T100_KEYBOARD) {
|
||||
if ((drvdata->quirks & QUIRK_T100_KEYBOARD) && hid_is_usb(hdev)) {
|
||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
||||
|
||||
if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) {
|
||||
|
||||
@@ -120,6 +120,8 @@ static int hammer_input_configured(struct hid_device *hdev,
|
||||
static const struct hid_device_id hammer_devices[] = {
|
||||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_DON) },
|
||||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_EEL) },
|
||||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) },
|
||||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
|
||||
@@ -68,8 +68,23 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
static int holtek_mouse_probe(struct hid_device *hdev,
|
||||
const struct hid_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
hid_err(hdev, "hid parse failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
if (ret) {
|
||||
hid_err(hdev, "hw start failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -479,6 +479,7 @@
|
||||
#define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d
|
||||
#define USB_DEVICE_ID_GOOGLE_MOONBALL 0x5044
|
||||
#define USB_DEVICE_ID_GOOGLE_DON 0x5050
|
||||
#define USB_DEVICE_ID_GOOGLE_EEL 0x5057
|
||||
|
||||
#define USB_VENDOR_ID_GOTOP 0x08f2
|
||||
#define USB_DEVICE_ID_SUPER_Q2 0x007f
|
||||
|
||||
@@ -791,6 +791,9 @@ static int uclogic_tablet_enable(struct hid_device *hdev)
|
||||
__u8 *p;
|
||||
s32 v;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Read string descriptor containing tablet parameters. The specific
|
||||
* string descriptor and data were discovered by sniffing the Windows
|
||||
|
||||
@@ -591,15 +591,18 @@ static const struct file_operations i8k_fops = {
|
||||
.unlocked_ioctl = i8k_ioctl,
|
||||
};
|
||||
|
||||
static struct proc_dir_entry *entry;
|
||||
|
||||
static void __init i8k_init_procfs(void)
|
||||
{
|
||||
/* Register the proc entry */
|
||||
proc_create("i8k", 0, NULL, &i8k_fops);
|
||||
entry = proc_create("i8k", 0, NULL, &i8k_fops);
|
||||
}
|
||||
|
||||
static void __exit i8k_exit_procfs(void)
|
||||
{
|
||||
remove_proc_entry("i8k", NULL);
|
||||
if (entry)
|
||||
remove_proc_entry("i8k", NULL);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
@@ -197,6 +197,7 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
|
||||
#define LM90_STATUS_RHIGH (1 << 4) /* remote high temp limit tripped */
|
||||
#define LM90_STATUS_LLOW (1 << 5) /* local low temp limit tripped */
|
||||
#define LM90_STATUS_LHIGH (1 << 6) /* local high temp limit tripped */
|
||||
#define LM90_STATUS_BUSY (1 << 7) /* conversion is ongoing */
|
||||
|
||||
#define MAX6696_STATUS2_R2THRM (1 << 1) /* remote2 THERM limit tripped */
|
||||
#define MAX6696_STATUS2_R2OPEN (1 << 2) /* remote2 is an open circuit */
|
||||
@@ -786,7 +787,7 @@ static int lm90_update_device(struct device *dev)
|
||||
val = lm90_read_reg(client, LM90_REG_R_STATUS);
|
||||
if (val < 0)
|
||||
return val;
|
||||
data->alarms = val; /* lower 8 bit of alarms */
|
||||
data->alarms = val & ~LM90_STATUS_BUSY;
|
||||
|
||||
if (data->kind == max6696) {
|
||||
val = lm90_select_remote_channel(client, data, 1);
|
||||
@@ -1439,12 +1440,11 @@ static int lm90_detect(struct i2c_client *client,
|
||||
if (man_id < 0 || chip_id < 0 || config1 < 0 || convrate < 0)
|
||||
return -ENODEV;
|
||||
|
||||
if (man_id == 0x01 || man_id == 0x5C || man_id == 0x41) {
|
||||
if (man_id == 0x01 || man_id == 0x5C || man_id == 0xA1) {
|
||||
config2 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG2);
|
||||
if (config2 < 0)
|
||||
return -ENODEV;
|
||||
} else
|
||||
config2 = 0; /* Make compiler happy */
|
||||
}
|
||||
|
||||
if ((address == 0x4C || address == 0x4D)
|
||||
&& man_id == 0x01) { /* National Semiconductor */
|
||||
|
||||
@@ -425,8 +425,8 @@ static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd)
|
||||
if (!(ipd & REG_INT_MBRF))
|
||||
return;
|
||||
|
||||
/* ack interrupt */
|
||||
i2c_writel(i2c, REG_INT_MBRF, REG_IPD);
|
||||
/* ack interrupt (read also produces a spurious START flag, clear it too) */
|
||||
i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD);
|
||||
|
||||
/* Can only handle a maximum of 32 bytes at a time */
|
||||
if (len > 32)
|
||||
|
||||
@@ -1379,6 +1379,7 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
|
||||
{
|
||||
struct stm32f7_i2c_dev *i2c_dev = data;
|
||||
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
|
||||
struct stm32_i2c_dma *dma = i2c_dev->dma;
|
||||
void __iomem *base = i2c_dev->base;
|
||||
u32 status, mask;
|
||||
int ret = IRQ_HANDLED;
|
||||
@@ -1403,6 +1404,10 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
|
||||
if (status & STM32F7_I2C_ISR_NACKF) {
|
||||
dev_dbg(i2c_dev->dev, "<%s>: Receive NACK\n", __func__);
|
||||
writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR);
|
||||
if (i2c_dev->use_dma) {
|
||||
stm32f7_i2c_disable_dma_req(i2c_dev);
|
||||
dmaengine_terminate_all(dma->chan_using);
|
||||
}
|
||||
f7_msg->result = -ENXIO;
|
||||
}
|
||||
|
||||
@@ -1418,7 +1423,7 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
|
||||
/* Clear STOP flag */
|
||||
writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR);
|
||||
|
||||
if (i2c_dev->use_dma) {
|
||||
if (i2c_dev->use_dma && !f7_msg->result) {
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
} else {
|
||||
i2c_dev->master_mode = false;
|
||||
@@ -1431,7 +1436,7 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
|
||||
if (f7_msg->stop) {
|
||||
mask = STM32F7_I2C_CR2_STOP;
|
||||
stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask);
|
||||
} else if (i2c_dev->use_dma) {
|
||||
} else if (i2c_dev->use_dma && !f7_msg->result) {
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
} else if (f7_msg->smbus) {
|
||||
stm32f7_i2c_smbus_rep_start(i2c_dev);
|
||||
@@ -1579,6 +1584,7 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap,
|
||||
i2c_dev->msg->addr);
|
||||
if (i2c_dev->use_dma)
|
||||
dmaengine_terminate_all(dma->chan_using);
|
||||
stm32f7_i2c_wait_free_bus(i2c_dev);
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@@ -1629,6 +1635,7 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
|
||||
dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr);
|
||||
if (i2c_dev->use_dma)
|
||||
dmaengine_terminate_all(dma->chan_using);
|
||||
stm32f7_i2c_wait_free_bus(i2c_dev);
|
||||
ret = -ETIMEDOUT;
|
||||
goto clk_free;
|
||||
}
|
||||
|
||||
@@ -544,6 +544,9 @@ static long compat_i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned lo
|
||||
sizeof(rdwr_arg)))
|
||||
return -EFAULT;
|
||||
|
||||
if (!rdwr_arg.msgs || rdwr_arg.nmsgs == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -1423,8 +1423,7 @@ static int kxcjk1013_probe(struct i2c_client *client,
|
||||
return 0;
|
||||
|
||||
err_buffer_cleanup:
|
||||
if (data->dready_trig)
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
err_trigger_unregister:
|
||||
if (data->dready_trig)
|
||||
iio_trigger_unregister(data->dready_trig);
|
||||
@@ -1447,8 +1446,8 @@ static int kxcjk1013_remove(struct i2c_client *client)
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
pm_runtime_put_noidle(&client->dev);
|
||||
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
if (data->dready_trig) {
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
iio_trigger_unregister(data->dready_trig);
|
||||
iio_trigger_unregister(data->motion_trig);
|
||||
}
|
||||
|
||||
@@ -227,14 +227,14 @@ static irqreturn_t kxsd9_trigger_handler(int irq, void *p)
|
||||
hw_values.chan,
|
||||
sizeof(hw_values.chan));
|
||||
if (ret) {
|
||||
dev_err(st->dev,
|
||||
"error reading data\n");
|
||||
return ret;
|
||||
dev_err(st->dev, "error reading data: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
iio_push_to_buffers_with_timestamp(indio_dev,
|
||||
&hw_values,
|
||||
iio_get_time_ns(indio_dev));
|
||||
out:
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
||||
@@ -1470,7 +1470,7 @@ static int mma8452_trigger_setup(struct iio_dev *indio_dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
indio_dev->trig = trig;
|
||||
indio_dev->trig = iio_trigger_get(trig);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1375,7 +1375,8 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
|
||||
*val = st->conversion_value;
|
||||
ret = at91_adc_adjust_val_osr(st, val);
|
||||
if (chan->scan_type.sign == 's')
|
||||
*val = sign_extend32(*val, 11);
|
||||
*val = sign_extend32(*val,
|
||||
chan->scan_type.realbits - 1);
|
||||
st->conversion_done = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -254,19 +254,8 @@ static int axp22x_adc_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan, int *val)
|
||||
{
|
||||
struct axp20x_adc_iio *info = iio_priv(indio_dev);
|
||||
int size;
|
||||
|
||||
/*
|
||||
* N.B.: Unlike the Chinese datasheets tell, the charging current is
|
||||
* stored on 12 bits, not 13 bits. Only discharging current is on 13
|
||||
* bits.
|
||||
*/
|
||||
if (chan->type == IIO_CURRENT && chan->channel == AXP22X_BATT_DISCHRG_I)
|
||||
size = 13;
|
||||
else
|
||||
size = 12;
|
||||
|
||||
*val = axp20x_read_variable_width(info->regmap, chan->address, size);
|
||||
*val = axp20x_read_variable_width(info->regmap, chan->address, 12);
|
||||
if (*val < 0)
|
||||
return *val;
|
||||
|
||||
@@ -389,9 +378,8 @@ static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val,
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
|
||||
case IIO_CURRENT:
|
||||
*val = 0;
|
||||
*val2 = 500000;
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
*val = 1;
|
||||
return IIO_VAL_INT;
|
||||
|
||||
case IIO_TEMP:
|
||||
*val = 100;
|
||||
|
||||
@@ -251,7 +251,6 @@ static int dln2_adc_set_chan_period(struct dln2_adc *dln2,
|
||||
static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel)
|
||||
{
|
||||
int ret, i;
|
||||
struct iio_dev *indio_dev = platform_get_drvdata(dln2->pdev);
|
||||
u16 conflict;
|
||||
__le16 value;
|
||||
int olen = sizeof(value);
|
||||
@@ -260,13 +259,9 @@ static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel)
|
||||
.chan = channel,
|
||||
};
|
||||
|
||||
ret = iio_device_claim_direct_mode(indio_dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = dln2_adc_set_chan_enabled(dln2, channel, true);
|
||||
if (ret < 0)
|
||||
goto release_direct;
|
||||
return ret;
|
||||
|
||||
ret = dln2_adc_set_port_enabled(dln2, true, &conflict);
|
||||
if (ret < 0) {
|
||||
@@ -303,8 +298,6 @@ disable_port:
|
||||
dln2_adc_set_port_enabled(dln2, false, NULL);
|
||||
disable_chan:
|
||||
dln2_adc_set_chan_enabled(dln2, channel, false);
|
||||
release_direct:
|
||||
iio_device_release_direct_mode(indio_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -340,10 +333,16 @@ static int dln2_adc_read_raw(struct iio_dev *indio_dev,
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
ret = iio_device_claim_direct_mode(indio_dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&dln2->mutex);
|
||||
ret = dln2_adc_read(dln2, chan->channel);
|
||||
mutex_unlock(&dln2->mutex);
|
||||
|
||||
iio_device_release_direct_mode(indio_dev);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -669,7 +668,11 @@ static int dln2_adc_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
iio_trigger_set_drvdata(dln2->trig, dln2);
|
||||
devm_iio_trigger_register(dev, dln2->trig);
|
||||
ret = devm_iio_trigger_register(dev, dln2->trig);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register trigger: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
iio_trigger_set_immutable(indio_dev, dln2->trig);
|
||||
|
||||
ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
|
||||
|
||||
@@ -64,9 +64,9 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p)
|
||||
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp);
|
||||
|
||||
error_ret:
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
|
||||
error_ret:
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
@@ -549,7 +549,6 @@ static struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs)
|
||||
irq_modify_status(trig->subirq_base + i,
|
||||
IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
|
||||
}
|
||||
get_device(&trig->dev);
|
||||
|
||||
return trig;
|
||||
|
||||
|
||||
@@ -1275,7 +1275,7 @@ static irqreturn_t ltr501_trigger_handler(int irq, void *p)
|
||||
ret = regmap_bulk_read(data->regmap, LTR501_ALS_DATA1,
|
||||
(u8 *)als_buf, sizeof(als_buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto done;
|
||||
if (test_bit(0, indio_dev->active_scan_mask))
|
||||
scan.channels[j++] = le16_to_cpu(als_buf[1]);
|
||||
if (test_bit(1, indio_dev->active_scan_mask))
|
||||
|
||||
@@ -545,9 +545,8 @@ static irqreturn_t stk3310_irq_event_handler(int irq, void *private)
|
||||
mutex_lock(&data->lock);
|
||||
ret = regmap_field_read(data->reg_flag_nf, &dir);
|
||||
if (ret < 0) {
|
||||
dev_err(&data->client->dev, "register read failed\n");
|
||||
mutex_unlock(&data->lock);
|
||||
return ret;
|
||||
dev_err(&data->client->dev, "register read failed: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
event = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1,
|
||||
IIO_EV_TYPE_THRESH,
|
||||
@@ -559,6 +558,7 @@ static irqreturn_t stk3310_irq_event_handler(int irq, void *private)
|
||||
ret = regmap_field_write(data->reg_flag_psint, 0);
|
||||
if (ret < 0)
|
||||
dev_err(&data->client->dev, "failed to reset interrupts\n");
|
||||
out:
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
||||
@@ -884,6 +884,6 @@ static struct platform_driver stm32_timer_trigger_driver = {
|
||||
};
|
||||
module_platform_driver(stm32_timer_trigger_driver);
|
||||
|
||||
MODULE_ALIAS("platform: stm32-timer-trigger");
|
||||
MODULE_ALIAS("platform:stm32-timer-trigger");
|
||||
MODULE_DESCRIPTION("STMicroelectronics STM32 Timer Trigger driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
@@ -1146,7 +1146,7 @@ void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
|
||||
rcd->egrbufs.rcvtids = NULL;
|
||||
|
||||
for (e = 0; e < rcd->egrbufs.alloced; e++) {
|
||||
if (rcd->egrbufs.buffers[e].dma)
|
||||
if (rcd->egrbufs.buffers[e].addr)
|
||||
dma_free_coherent(&dd->pcidev->dev,
|
||||
rcd->egrbufs.buffers[e].len,
|
||||
rcd->egrbufs.buffers[e].addr,
|
||||
|
||||
@@ -945,7 +945,7 @@ static int qib_user_sdma_queue_pkts(const struct qib_devdata *dd,
|
||||
&addrlimit) ||
|
||||
addrlimit > type_max(typeof(pkt->addrlimit))) {
|
||||
ret = -EINVAL;
|
||||
goto free_pbc;
|
||||
goto free_pkt;
|
||||
}
|
||||
pkt->addrlimit = addrlimit;
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/serio.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#define DRIVER_DESC "SpaceTec SpaceBall 2003/3003/4000 FLX driver"
|
||||
|
||||
@@ -87,9 +88,15 @@ static void spaceball_process_packet(struct spaceball* spaceball)
|
||||
|
||||
case 'D': /* Ball data */
|
||||
if (spaceball->idx != 15) return;
|
||||
for (i = 0; i < 6; i++)
|
||||
/*
|
||||
* Skip first three bytes; read six axes worth of data.
|
||||
* Axis values are signed 16-bit big-endian.
|
||||
*/
|
||||
data += 3;
|
||||
for (i = 0; i < ARRAY_SIZE(spaceball_axes); i++) {
|
||||
input_report_abs(dev, spaceball_axes[i],
|
||||
(__s16)((data[2 * i + 3] << 8) | data[2 * i + 2]));
|
||||
(__s16)get_unaligned_be16(&data[i * 2]));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'K': /* Button data */
|
||||
|
||||
@@ -930,6 +930,8 @@ static int atp_probe(struct usb_interface *iface,
|
||||
set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
|
||||
set_bit(BTN_LEFT, input_dev->keybit);
|
||||
|
||||
INIT_WORK(&dev->work, atp_reinit);
|
||||
|
||||
error = input_register_device(dev->input);
|
||||
if (error)
|
||||
goto err_free_buffer;
|
||||
@@ -937,8 +939,6 @@ static int atp_probe(struct usb_interface *iface,
|
||||
/* save our data pointer in this interface device */
|
||||
usb_set_intfdata(iface, dev);
|
||||
|
||||
INIT_WORK(&dev->work, atp_reinit);
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_buffer:
|
||||
|
||||
@@ -999,6 +999,24 @@ static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct dmi_system_id i8042_dmi_probe_defer_table[] __initconst = {
|
||||
{
|
||||
/* ASUS ZenBook UX425UA */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* ASUS ZenBook UM325UA */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
#endif /* CONFIG_X86 */
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
@@ -1318,6 +1336,9 @@ static int __init i8042_platform_init(void)
|
||||
if (dmi_check_system(i8042_dmi_kbdreset_table))
|
||||
i8042_kbdreset = true;
|
||||
|
||||
if (dmi_check_system(i8042_dmi_probe_defer_table))
|
||||
i8042_probe_defer = true;
|
||||
|
||||
/*
|
||||
* A20 was already enabled during early kernel init. But some buggy
|
||||
* BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to
|
||||
|
||||
@@ -48,6 +48,10 @@ static bool i8042_unlock;
|
||||
module_param_named(unlock, i8042_unlock, bool, 0);
|
||||
MODULE_PARM_DESC(unlock, "Ignore keyboard lock.");
|
||||
|
||||
static bool i8042_probe_defer;
|
||||
module_param_named(probe_defer, i8042_probe_defer, bool, 0);
|
||||
MODULE_PARM_DESC(probe_defer, "Allow deferred probing.");
|
||||
|
||||
enum i8042_controller_reset_mode {
|
||||
I8042_RESET_NEVER,
|
||||
I8042_RESET_ALWAYS,
|
||||
@@ -702,7 +706,7 @@ static int i8042_set_mux_mode(bool multiplex, unsigned char *mux_version)
|
||||
* LCS/Telegraphics.
|
||||
*/
|
||||
|
||||
static int __init i8042_check_mux(void)
|
||||
static int i8042_check_mux(void)
|
||||
{
|
||||
unsigned char mux_version;
|
||||
|
||||
@@ -731,10 +735,10 @@ static int __init i8042_check_mux(void)
|
||||
/*
|
||||
* The following is used to test AUX IRQ delivery.
|
||||
*/
|
||||
static struct completion i8042_aux_irq_delivered __initdata;
|
||||
static bool i8042_irq_being_tested __initdata;
|
||||
static struct completion i8042_aux_irq_delivered;
|
||||
static bool i8042_irq_being_tested;
|
||||
|
||||
static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id)
|
||||
static irqreturn_t i8042_aux_test_irq(int irq, void *dev_id)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned char str, data;
|
||||
@@ -761,7 +765,7 @@ static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id)
|
||||
* verifies success by readinng CTR. Used when testing for presence of AUX
|
||||
* port.
|
||||
*/
|
||||
static int __init i8042_toggle_aux(bool on)
|
||||
static int i8042_toggle_aux(bool on)
|
||||
{
|
||||
unsigned char param;
|
||||
int i;
|
||||
@@ -789,7 +793,7 @@ static int __init i8042_toggle_aux(bool on)
|
||||
* the presence of an AUX interface.
|
||||
*/
|
||||
|
||||
static int __init i8042_check_aux(void)
|
||||
static int i8042_check_aux(void)
|
||||
{
|
||||
int retval = -1;
|
||||
bool irq_registered = false;
|
||||
@@ -996,7 +1000,7 @@ static int i8042_controller_init(void)
|
||||
|
||||
if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) {
|
||||
pr_err("Can't read CTR while initializing i8042\n");
|
||||
return -EIO;
|
||||
return i8042_probe_defer ? -EPROBE_DEFER : -EIO;
|
||||
}
|
||||
|
||||
} while (n < 2 || ctr[0] != ctr[1]);
|
||||
@@ -1311,7 +1315,7 @@ static void i8042_shutdown(struct platform_device *dev)
|
||||
i8042_controller_reset(false);
|
||||
}
|
||||
|
||||
static int __init i8042_create_kbd_port(void)
|
||||
static int i8042_create_kbd_port(void)
|
||||
{
|
||||
struct serio *serio;
|
||||
struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
|
||||
@@ -1339,7 +1343,7 @@ static int __init i8042_create_kbd_port(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init i8042_create_aux_port(int idx)
|
||||
static int i8042_create_aux_port(int idx)
|
||||
{
|
||||
struct serio *serio;
|
||||
int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx;
|
||||
@@ -1376,13 +1380,13 @@ static int __init i8042_create_aux_port(int idx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init i8042_free_kbd_port(void)
|
||||
static void i8042_free_kbd_port(void)
|
||||
{
|
||||
kfree(i8042_ports[I8042_KBD_PORT_NO].serio);
|
||||
i8042_ports[I8042_KBD_PORT_NO].serio = NULL;
|
||||
}
|
||||
|
||||
static void __init i8042_free_aux_ports(void)
|
||||
static void i8042_free_aux_ports(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1392,7 +1396,7 @@ static void __init i8042_free_aux_ports(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void __init i8042_register_ports(void)
|
||||
static void i8042_register_ports(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1444,7 +1448,7 @@ static void i8042_free_irqs(void)
|
||||
i8042_aux_irq_registered = i8042_kbd_irq_registered = false;
|
||||
}
|
||||
|
||||
static int __init i8042_setup_aux(void)
|
||||
static int i8042_setup_aux(void)
|
||||
{
|
||||
int (*aux_enable)(void);
|
||||
int error;
|
||||
@@ -1486,7 +1490,7 @@ static int __init i8042_setup_aux(void)
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __init i8042_setup_kbd(void)
|
||||
static int i8042_setup_kbd(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
@@ -1536,7 +1540,7 @@ static int i8042_kbd_bind_notifier(struct notifier_block *nb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init i8042_probe(struct platform_device *dev)
|
||||
static int i8042_probe(struct platform_device *dev)
|
||||
{
|
||||
int error;
|
||||
|
||||
@@ -1601,6 +1605,7 @@ static struct platform_driver i8042_driver = {
|
||||
.pm = &i8042_pm_ops,
|
||||
#endif
|
||||
},
|
||||
.probe = i8042_probe,
|
||||
.remove = i8042_remove,
|
||||
.shutdown = i8042_shutdown,
|
||||
};
|
||||
@@ -1611,7 +1616,6 @@ static struct notifier_block i8042_kbd_bind_notifier_block = {
|
||||
|
||||
static int __init i8042_init(void)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
int err;
|
||||
|
||||
dbg_init();
|
||||
@@ -1627,17 +1631,29 @@ static int __init i8042_init(void)
|
||||
/* Set this before creating the dev to allow i8042_command to work right away */
|
||||
i8042_present = true;
|
||||
|
||||
pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0);
|
||||
if (IS_ERR(pdev)) {
|
||||
err = PTR_ERR(pdev);
|
||||
err = platform_driver_register(&i8042_driver);
|
||||
if (err)
|
||||
goto err_platform_exit;
|
||||
|
||||
i8042_platform_device = platform_device_alloc("i8042", -1);
|
||||
if (!i8042_platform_device) {
|
||||
err = -ENOMEM;
|
||||
goto err_unregister_driver;
|
||||
}
|
||||
|
||||
err = platform_device_add(i8042_platform_device);
|
||||
if (err)
|
||||
goto err_free_device;
|
||||
|
||||
bus_register_notifier(&serio_bus, &i8042_kbd_bind_notifier_block);
|
||||
panic_blink = i8042_panic_blink;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_device:
|
||||
platform_device_put(i8042_platform_device);
|
||||
err_unregister_driver:
|
||||
platform_driver_unregister(&i8042_driver);
|
||||
err_platform_exit:
|
||||
i8042_platform_exit();
|
||||
return err;
|
||||
|
||||
@@ -1809,7 +1809,7 @@ static int mxt_read_info_block(struct mxt_data *data)
|
||||
if (error) {
|
||||
dev_err(&client->dev, "Error %d parsing object table\n", error);
|
||||
mxt_free_object_table(data);
|
||||
goto err_free_mem;
|
||||
return error;
|
||||
}
|
||||
|
||||
data->object_table = (struct mxt_object *)(id_buf + MXT_OBJECT_START);
|
||||
|
||||
@@ -80,8 +80,8 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
|
||||
data_present = touchscreen_get_prop_u32(dev, "touchscreen-size-x",
|
||||
input_abs_get_max(input,
|
||||
axis) + 1,
|
||||
&maximum) |
|
||||
touchscreen_get_prop_u32(dev, "touchscreen-fuzz-x",
|
||||
&maximum);
|
||||
data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-x",
|
||||
input_abs_get_fuzz(input, axis),
|
||||
&fuzz);
|
||||
if (data_present)
|
||||
@@ -91,8 +91,8 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
|
||||
data_present = touchscreen_get_prop_u32(dev, "touchscreen-size-y",
|
||||
input_abs_get_max(input,
|
||||
axis) + 1,
|
||||
&maximum) |
|
||||
touchscreen_get_prop_u32(dev, "touchscreen-fuzz-y",
|
||||
&maximum);
|
||||
data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-y",
|
||||
input_abs_get_fuzz(input, axis),
|
||||
&fuzz);
|
||||
if (data_present)
|
||||
@@ -102,11 +102,11 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
|
||||
data_present = touchscreen_get_prop_u32(dev,
|
||||
"touchscreen-max-pressure",
|
||||
input_abs_get_max(input, axis),
|
||||
&maximum) |
|
||||
touchscreen_get_prop_u32(dev,
|
||||
"touchscreen-fuzz-pressure",
|
||||
input_abs_get_fuzz(input, axis),
|
||||
&fuzz);
|
||||
&maximum);
|
||||
data_present |= touchscreen_get_prop_u32(dev,
|
||||
"touchscreen-fuzz-pressure",
|
||||
input_abs_get_fuzz(input, axis),
|
||||
&fuzz);
|
||||
if (data_present)
|
||||
touchscreen_set_params(input, axis, maximum, fuzz);
|
||||
|
||||
|
||||
@@ -232,17 +232,13 @@ static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
int hwirq, i;
|
||||
|
||||
mutex_lock(&msi_used_lock);
|
||||
|
||||
hwirq = bitmap_find_next_zero_area(msi_used, PCI_MSI_DOORBELL_NR,
|
||||
0, nr_irqs, 0);
|
||||
if (hwirq >= PCI_MSI_DOORBELL_NR) {
|
||||
mutex_unlock(&msi_used_lock);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
bitmap_set(msi_used, hwirq, nr_irqs);
|
||||
hwirq = bitmap_find_free_region(msi_used, PCI_MSI_DOORBELL_NR,
|
||||
order_base_2(nr_irqs));
|
||||
mutex_unlock(&msi_used_lock);
|
||||
|
||||
if (hwirq < 0)
|
||||
return -ENOSPC;
|
||||
|
||||
for (i = 0; i < nr_irqs; i++) {
|
||||
irq_domain_set_info(domain, virq + i, hwirq + i,
|
||||
&armada_370_xp_msi_bottom_irq_chip,
|
||||
@@ -250,7 +246,7 @@ static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
return hwirq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void armada_370_xp_msi_free(struct irq_domain *domain,
|
||||
@@ -259,7 +255,7 @@ static void armada_370_xp_msi_free(struct irq_domain *domain,
|
||||
struct irq_data *d = irq_domain_get_irq_data(domain, virq);
|
||||
|
||||
mutex_lock(&msi_used_lock);
|
||||
bitmap_clear(msi_used, d->hwirq, nr_irqs);
|
||||
bitmap_release_region(msi_used, d->hwirq, order_base_2(nr_irqs));
|
||||
mutex_unlock(&msi_used_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -581,7 +581,7 @@ static struct its_collection *its_build_invall_cmd(struct its_node *its,
|
||||
|
||||
its_fixup_cmd(cmd);
|
||||
|
||||
return NULL;
|
||||
return desc->its_invall_cmd.col;
|
||||
}
|
||||
|
||||
static struct its_vpe *its_build_vinvall_cmd(struct its_node *its,
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#define NVIC_ISER 0x000
|
||||
#define NVIC_ICER 0x080
|
||||
#define NVIC_IPR 0x300
|
||||
#define NVIC_IPR 0x400
|
||||
|
||||
#define NVIC_MAX_BANKS 16
|
||||
/*
|
||||
|
||||
@@ -423,9 +423,9 @@ static int rebalance_children(struct shadow_spine *s,
|
||||
|
||||
memcpy(n, dm_block_data(child),
|
||||
dm_bm_block_size(dm_tm_get_bm(info->tm)));
|
||||
dm_tm_unlock(info->tm, child);
|
||||
|
||||
dm_tm_dec(info->tm, dm_block_location(child));
|
||||
dm_tm_unlock(info->tm, child);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -932,8 +932,6 @@ static int mxl111sf_init(struct dvb_usb_device *d)
|
||||
.len = sizeof(eeprom), .buf = eeprom },
|
||||
};
|
||||
|
||||
mutex_init(&state->msg_lock);
|
||||
|
||||
ret = get_chip_info(state);
|
||||
if (mxl_fail(ret))
|
||||
pr_err("failed to get chip info during probe");
|
||||
@@ -1075,6 +1073,14 @@ static int mxl111sf_get_stream_config_dvbt(struct dvb_frontend *fe,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxl111sf_probe(struct dvb_usb_device *dev)
|
||||
{
|
||||
struct mxl111sf_state *state = d_to_priv(dev);
|
||||
|
||||
mutex_init(&state->msg_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dvb_usb_device_properties mxl111sf_props_dvbt = {
|
||||
.driver_name = KBUILD_MODNAME,
|
||||
.owner = THIS_MODULE,
|
||||
@@ -1084,6 +1090,7 @@ static struct dvb_usb_device_properties mxl111sf_props_dvbt = {
|
||||
.generic_bulk_ctrl_endpoint = 0x02,
|
||||
.generic_bulk_ctrl_endpoint_response = 0x81,
|
||||
|
||||
.probe = mxl111sf_probe,
|
||||
.i2c_algo = &mxl111sf_i2c_algo,
|
||||
.frontend_attach = mxl111sf_frontend_attach_dvbt,
|
||||
.tuner_attach = mxl111sf_attach_tuner,
|
||||
@@ -1125,6 +1132,7 @@ static struct dvb_usb_device_properties mxl111sf_props_atsc = {
|
||||
.generic_bulk_ctrl_endpoint = 0x02,
|
||||
.generic_bulk_ctrl_endpoint_response = 0x81,
|
||||
|
||||
.probe = mxl111sf_probe,
|
||||
.i2c_algo = &mxl111sf_i2c_algo,
|
||||
.frontend_attach = mxl111sf_frontend_attach_atsc,
|
||||
.tuner_attach = mxl111sf_attach_tuner,
|
||||
@@ -1166,6 +1174,7 @@ static struct dvb_usb_device_properties mxl111sf_props_mh = {
|
||||
.generic_bulk_ctrl_endpoint = 0x02,
|
||||
.generic_bulk_ctrl_endpoint_response = 0x81,
|
||||
|
||||
.probe = mxl111sf_probe,
|
||||
.i2c_algo = &mxl111sf_i2c_algo,
|
||||
.frontend_attach = mxl111sf_frontend_attach_mh,
|
||||
.tuner_attach = mxl111sf_attach_tuner,
|
||||
@@ -1234,6 +1243,7 @@ static struct dvb_usb_device_properties mxl111sf_props_atsc_mh = {
|
||||
.generic_bulk_ctrl_endpoint = 0x02,
|
||||
.generic_bulk_ctrl_endpoint_response = 0x81,
|
||||
|
||||
.probe = mxl111sf_probe,
|
||||
.i2c_algo = &mxl111sf_i2c_algo,
|
||||
.frontend_attach = mxl111sf_frontend_attach_atsc_mh,
|
||||
.tuner_attach = mxl111sf_attach_tuner,
|
||||
@@ -1312,6 +1322,7 @@ static struct dvb_usb_device_properties mxl111sf_props_mercury = {
|
||||
.generic_bulk_ctrl_endpoint = 0x02,
|
||||
.generic_bulk_ctrl_endpoint_response = 0x81,
|
||||
|
||||
.probe = mxl111sf_probe,
|
||||
.i2c_algo = &mxl111sf_i2c_algo,
|
||||
.frontend_attach = mxl111sf_frontend_attach_mercury,
|
||||
.tuner_attach = mxl111sf_attach_tuner,
|
||||
@@ -1382,6 +1393,7 @@ static struct dvb_usb_device_properties mxl111sf_props_mercury_mh = {
|
||||
.generic_bulk_ctrl_endpoint = 0x02,
|
||||
.generic_bulk_ctrl_endpoint_response = 0x81,
|
||||
|
||||
.probe = mxl111sf_probe,
|
||||
.i2c_algo = &mxl111sf_i2c_algo,
|
||||
.frontend_attach = mxl111sf_frontend_attach_mercury_mh,
|
||||
.tuner_attach = mxl111sf_attach_tuner,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/dma-direction.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
@@ -700,6 +701,9 @@ static int fsmc_exec_op(struct nand_chip *chip, const struct nand_operation *op,
|
||||
instr->ctx.waitrdy.timeout_ms);
|
||||
break;
|
||||
}
|
||||
|
||||
if (instr->delay_ns)
|
||||
ndelay(instr->delay_ns);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -1530,14 +1530,14 @@ void bond_alb_monitor(struct work_struct *work)
|
||||
struct slave *slave;
|
||||
|
||||
if (!bond_has_slaves(bond)) {
|
||||
bond_info->tx_rebalance_counter = 0;
|
||||
atomic_set(&bond_info->tx_rebalance_counter, 0);
|
||||
bond_info->lp_counter = 0;
|
||||
goto re_arm;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
bond_info->tx_rebalance_counter++;
|
||||
atomic_inc(&bond_info->tx_rebalance_counter);
|
||||
bond_info->lp_counter++;
|
||||
|
||||
/* send learning packets */
|
||||
@@ -1559,7 +1559,7 @@ void bond_alb_monitor(struct work_struct *work)
|
||||
}
|
||||
|
||||
/* rebalance tx traffic */
|
||||
if (bond_info->tx_rebalance_counter >= BOND_TLB_REBALANCE_TICKS) {
|
||||
if (atomic_read(&bond_info->tx_rebalance_counter) >= BOND_TLB_REBALANCE_TICKS) {
|
||||
bond_for_each_slave_rcu(bond, slave, iter) {
|
||||
tlb_clear_slave(bond, slave, 1);
|
||||
if (slave == rcu_access_pointer(bond->curr_active_slave)) {
|
||||
@@ -1569,7 +1569,7 @@ void bond_alb_monitor(struct work_struct *work)
|
||||
bond_info->unbalanced_load = 0;
|
||||
}
|
||||
}
|
||||
bond_info->tx_rebalance_counter = 0;
|
||||
atomic_set(&bond_info->tx_rebalance_counter, 0);
|
||||
}
|
||||
|
||||
if (bond_info->rlb_enabled) {
|
||||
@@ -1639,7 +1639,8 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
|
||||
tlb_init_slave(slave);
|
||||
|
||||
/* order a rebalance ASAP */
|
||||
bond->alb_info.tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS;
|
||||
atomic_set(&bond->alb_info.tx_rebalance_counter,
|
||||
BOND_TLB_REBALANCE_TICKS);
|
||||
|
||||
if (bond->alb_info.rlb_enabled)
|
||||
bond->alb_info.rlb_rebalance = 1;
|
||||
@@ -1676,7 +1677,8 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char
|
||||
rlb_clear_slave(bond, slave);
|
||||
} else if (link == BOND_LINK_UP) {
|
||||
/* order a rebalance ASAP */
|
||||
bond_info->tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS;
|
||||
atomic_set(&bond_info->tx_rebalance_counter,
|
||||
BOND_TLB_REBALANCE_TICKS);
|
||||
if (bond->alb_info.rlb_enabled) {
|
||||
bond->alb_info.rlb_rebalance = 1;
|
||||
/* If the updelay module parameter is smaller than the
|
||||
|
||||
@@ -1439,7 +1439,7 @@ static int bond_option_ad_actor_system_set(struct bonding *bond,
|
||||
mac = (u8 *)&newval->value;
|
||||
}
|
||||
|
||||
if (!is_valid_ether_addr(mac))
|
||||
if (is_multicast_ether_addr(mac))
|
||||
goto err;
|
||||
|
||||
netdev_dbg(bond->dev, "Setting ad_actor_system to %pM\n", mac);
|
||||
|
||||
@@ -233,15 +233,15 @@ enum m_can_mram_cfg {
|
||||
|
||||
/* Interrupts for version 3.0.x */
|
||||
#define IR_ERR_LEC_30X (IR_STE | IR_FOE | IR_ACKE | IR_BE | IR_CRCE)
|
||||
#define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_ELO | IR_BEU | \
|
||||
IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \
|
||||
IR_RF1L | IR_RF0L)
|
||||
#define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_BEU | IR_BEC | \
|
||||
IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | IR_RF1L | \
|
||||
IR_RF0L)
|
||||
#define IR_ERR_ALL_30X (IR_ERR_STATE | IR_ERR_BUS_30X)
|
||||
/* Interrupts for version >= 3.1.x */
|
||||
#define IR_ERR_LEC_31X (IR_PED | IR_PEA)
|
||||
#define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_ELO | IR_BEU | \
|
||||
IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \
|
||||
IR_RF1L | IR_RF0L)
|
||||
#define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_BEU | IR_BEC | \
|
||||
IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | IR_RF1L | \
|
||||
IR_RF0L)
|
||||
#define IR_ERR_ALL_31X (IR_ERR_STATE | IR_ERR_BUS_31X)
|
||||
|
||||
/* Interrupt Line Select (ILS) */
|
||||
@@ -769,8 +769,6 @@ static void m_can_handle_other_err(struct net_device *dev, u32 irqstatus)
|
||||
{
|
||||
if (irqstatus & IR_WDI)
|
||||
netdev_err(dev, "Message RAM Watchdog event due to missing READY\n");
|
||||
if (irqstatus & IR_ELO)
|
||||
netdev_err(dev, "Error Logging Overflow\n");
|
||||
if (irqstatus & IR_BEU)
|
||||
netdev_err(dev, "Bit Error Uncorrected\n");
|
||||
if (irqstatus & IR_BEC)
|
||||
|
||||
@@ -703,11 +703,11 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota)
|
||||
cf->data[i + 1] = data_reg >> 8;
|
||||
}
|
||||
|
||||
netif_receive_skb(skb);
|
||||
rcv_pkts++;
|
||||
stats->rx_packets++;
|
||||
quota--;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
netif_receive_skb(skb);
|
||||
|
||||
pch_fifo_thresh(priv, obj_num);
|
||||
obj_num++;
|
||||
|
||||
@@ -243,7 +243,12 @@ static int ems_pcmcia_add_card(struct pcmcia_device *pdev, unsigned long base)
|
||||
free_sja1000dev(dev);
|
||||
}
|
||||
|
||||
err = request_irq(dev->irq, &ems_pcmcia_interrupt, IRQF_SHARED,
|
||||
if (!card->channels) {
|
||||
err = -ENODEV;
|
||||
goto failure_cleanup;
|
||||
}
|
||||
|
||||
err = request_irq(pdev->irq, &ems_pcmcia_interrupt, IRQF_SHARED,
|
||||
DRV_NAME, card);
|
||||
if (!err)
|
||||
return 0;
|
||||
|
||||
@@ -28,10 +28,6 @@
|
||||
|
||||
#include "kvaser_usb.h"
|
||||
|
||||
/* Forward declaration */
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg;
|
||||
|
||||
#define CAN_USB_CLOCK 8000000
|
||||
#define MAX_USBCAN_NET_DEVICES 2
|
||||
|
||||
/* Command header size */
|
||||
@@ -80,6 +76,12 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg;
|
||||
|
||||
#define CMD_LEAF_LOG_MESSAGE 106
|
||||
|
||||
/* Leaf frequency options */
|
||||
#define KVASER_USB_LEAF_SWOPTION_FREQ_MASK 0x60
|
||||
#define KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK 0
|
||||
#define KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK BIT(5)
|
||||
#define KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK BIT(6)
|
||||
|
||||
/* error factors */
|
||||
#define M16C_EF_ACKE BIT(0)
|
||||
#define M16C_EF_CRCE BIT(1)
|
||||
@@ -340,6 +342,50 @@ struct kvaser_usb_err_summary {
|
||||
};
|
||||
};
|
||||
|
||||
static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = {
|
||||
.name = "kvaser_usb",
|
||||
.tseg1_min = KVASER_USB_TSEG1_MIN,
|
||||
.tseg1_max = KVASER_USB_TSEG1_MAX,
|
||||
.tseg2_min = KVASER_USB_TSEG2_MIN,
|
||||
.tseg2_max = KVASER_USB_TSEG2_MAX,
|
||||
.sjw_max = KVASER_USB_SJW_MAX,
|
||||
.brp_min = KVASER_USB_BRP_MIN,
|
||||
.brp_max = KVASER_USB_BRP_MAX,
|
||||
.brp_inc = KVASER_USB_BRP_INC,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_8mhz = {
|
||||
.clock = {
|
||||
.freq = 8000000,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_16mhz = {
|
||||
.clock = {
|
||||
.freq = 16000000,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_24mhz = {
|
||||
.clock = {
|
||||
.freq = 24000000,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_32mhz = {
|
||||
.clock = {
|
||||
.freq = 32000000,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
static void *
|
||||
kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
|
||||
const struct sk_buff *skb, int *frame_len,
|
||||
@@ -471,6 +517,27 @@ static int kvaser_usb_leaf_send_simple_cmd(const struct kvaser_usb *dev,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev,
|
||||
const struct leaf_cmd_softinfo *softinfo)
|
||||
{
|
||||
u32 sw_options = le32_to_cpu(softinfo->sw_options);
|
||||
|
||||
dev->fw_version = le32_to_cpu(softinfo->fw_version);
|
||||
dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx);
|
||||
|
||||
switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) {
|
||||
case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK:
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz;
|
||||
break;
|
||||
case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK:
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz;
|
||||
break;
|
||||
case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK:
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev)
|
||||
{
|
||||
struct kvaser_cmd cmd;
|
||||
@@ -486,14 +553,13 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev)
|
||||
|
||||
switch (dev->card_data.leaf.family) {
|
||||
case KVASER_LEAF:
|
||||
dev->fw_version = le32_to_cpu(cmd.u.leaf.softinfo.fw_version);
|
||||
dev->max_tx_urbs =
|
||||
le16_to_cpu(cmd.u.leaf.softinfo.max_outstanding_tx);
|
||||
kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo);
|
||||
break;
|
||||
case KVASER_USBCAN:
|
||||
dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version);
|
||||
dev->max_tx_urbs =
|
||||
le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx);
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg_8mhz;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1225,24 +1291,11 @@ static int kvaser_usb_leaf_init_card(struct kvaser_usb *dev)
|
||||
{
|
||||
struct kvaser_usb_dev_card_data *card_data = &dev->card_data;
|
||||
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg;
|
||||
card_data->ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = {
|
||||
.name = "kvaser_usb",
|
||||
.tseg1_min = KVASER_USB_TSEG1_MIN,
|
||||
.tseg1_max = KVASER_USB_TSEG1_MAX,
|
||||
.tseg2_min = KVASER_USB_TSEG2_MIN,
|
||||
.tseg2_max = KVASER_USB_TSEG2_MAX,
|
||||
.sjw_max = KVASER_USB_SJW_MAX,
|
||||
.brp_min = KVASER_USB_BRP_MIN,
|
||||
.brp_max = KVASER_USB_BRP_MAX,
|
||||
.brp_inc = KVASER_USB_BRP_INC,
|
||||
};
|
||||
|
||||
static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
|
||||
{
|
||||
struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
|
||||
@@ -1348,11 +1401,3 @@ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = {
|
||||
.dev_read_bulk_callback = kvaser_usb_leaf_read_bulk_callback,
|
||||
.dev_frame_to_cmd = kvaser_usb_leaf_frame_to_cmd,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg = {
|
||||
.clock = {
|
||||
.freq = CAN_USB_CLOCK,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
@@ -1445,16 +1445,19 @@ static int altera_tse_probe(struct platform_device *pdev)
|
||||
priv->rxdescmem_busaddr = dma_res->start;
|
||||
|
||||
} else {
|
||||
ret = -ENODEV;
|
||||
goto err_free_netdev;
|
||||
}
|
||||
|
||||
if (!dma_set_mask(priv->device, DMA_BIT_MASK(priv->dmaops->dmamask)))
|
||||
if (!dma_set_mask(priv->device, DMA_BIT_MASK(priv->dmaops->dmamask))) {
|
||||
dma_set_coherent_mask(priv->device,
|
||||
DMA_BIT_MASK(priv->dmaops->dmamask));
|
||||
else if (!dma_set_mask(priv->device, DMA_BIT_MASK(32)))
|
||||
} else if (!dma_set_mask(priv->device, DMA_BIT_MASK(32))) {
|
||||
dma_set_coherent_mask(priv->device, DMA_BIT_MASK(32));
|
||||
else
|
||||
} else {
|
||||
ret = -EIO;
|
||||
goto err_free_netdev;
|
||||
}
|
||||
|
||||
/* MAC address space */
|
||||
ret = request_and_map(pdev, "control_port", &control_port,
|
||||
|
||||
@@ -459,6 +459,11 @@ int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
|
||||
goto err_exit;
|
||||
|
||||
if (fw.len == 0xFFFFU) {
|
||||
if (sw.len > sizeof(self->rpc)) {
|
||||
printk(KERN_INFO "Invalid sw len: %x\n", sw.len);
|
||||
err = -EINVAL;
|
||||
goto err_exit;
|
||||
}
|
||||
err = hw_atl_utils_fw_rpc_call(self, sw.len);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
@@ -469,6 +474,11 @@ int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
|
||||
|
||||
if (rpc) {
|
||||
if (fw.len) {
|
||||
if (fw.len > sizeof(self->rpc)) {
|
||||
printk(KERN_INFO "Invalid fw len: %x\n", fw.len);
|
||||
err = -EINVAL;
|
||||
goto err_exit;
|
||||
}
|
||||
err =
|
||||
hw_atl_utils_fw_downld_dwords(self,
|
||||
self->rpc_addr,
|
||||
|
||||
@@ -120,9 +120,13 @@ static inline void tdma_port_write_desc_addr(struct bcm_sysport_priv *priv,
|
||||
struct dma_desc *desc,
|
||||
unsigned int port)
|
||||
{
|
||||
unsigned long desc_flags;
|
||||
|
||||
/* Ports are latched, so write upper address first */
|
||||
spin_lock_irqsave(&priv->desc_lock, desc_flags);
|
||||
tdma_writel(priv, desc->addr_status_len, TDMA_WRITE_PORT_HI(port));
|
||||
tdma_writel(priv, desc->addr_lo, TDMA_WRITE_PORT_LO(port));
|
||||
spin_unlock_irqrestore(&priv->desc_lock, desc_flags);
|
||||
}
|
||||
|
||||
/* Ethtool operations */
|
||||
@@ -2003,6 +2007,7 @@ static int bcm_sysport_open(struct net_device *dev)
|
||||
}
|
||||
|
||||
/* Initialize both hardware and software ring */
|
||||
spin_lock_init(&priv->desc_lock);
|
||||
for (i = 0; i < dev->num_tx_queues; i++) {
|
||||
ret = bcm_sysport_init_tx_ring(priv, i);
|
||||
if (ret) {
|
||||
|
||||
@@ -751,6 +751,7 @@ struct bcm_sysport_priv {
|
||||
int wol_irq;
|
||||
|
||||
/* Transmit rings */
|
||||
spinlock_t desc_lock;
|
||||
struct bcm_sysport_tx_ring *tx_rings;
|
||||
|
||||
/* Receive queue */
|
||||
|
||||
@@ -4708,6 +4708,10 @@ type3_infoblock(struct net_device *dev, u_char count, u_char *p)
|
||||
lp->ibn = 3;
|
||||
lp->active = *p++;
|
||||
if (MOTO_SROM_BUG) lp->active = 0;
|
||||
/* if (MOTO_SROM_BUG) statement indicates lp->active could
|
||||
* be 8 (i.e. the size of array lp->phy) */
|
||||
if (WARN_ON(lp->active >= ARRAY_SIZE(lp->phy)))
|
||||
return -EINVAL;
|
||||
lp->phy[lp->active].gep = (*p ? p : NULL); p += (2 * (*p) + 1);
|
||||
lp->phy[lp->active].rst = (*p ? p : NULL); p += (2 * (*p) + 1);
|
||||
lp->phy[lp->active].mc = get_unaligned_le16(p); p += 2;
|
||||
@@ -4999,19 +5003,23 @@ mii_get_phy(struct net_device *dev)
|
||||
}
|
||||
if ((j == limit) && (i < DE4X5_MAX_MII)) {
|
||||
for (k=0; k < DE4X5_MAX_PHY && lp->phy[k].id; k++);
|
||||
lp->phy[k].addr = i;
|
||||
lp->phy[k].id = id;
|
||||
lp->phy[k].spd.reg = GENERIC_REG; /* ANLPA register */
|
||||
lp->phy[k].spd.mask = GENERIC_MASK; /* 100Mb/s technologies */
|
||||
lp->phy[k].spd.value = GENERIC_VALUE; /* TX & T4, H/F Duplex */
|
||||
lp->mii_cnt++;
|
||||
lp->active++;
|
||||
printk("%s: Using generic MII device control. If the board doesn't operate,\nplease mail the following dump to the author:\n", dev->name);
|
||||
j = de4x5_debug;
|
||||
de4x5_debug |= DEBUG_MII;
|
||||
de4x5_dbg_mii(dev, k);
|
||||
de4x5_debug = j;
|
||||
printk("\n");
|
||||
if (k < DE4X5_MAX_PHY) {
|
||||
lp->phy[k].addr = i;
|
||||
lp->phy[k].id = id;
|
||||
lp->phy[k].spd.reg = GENERIC_REG; /* ANLPA register */
|
||||
lp->phy[k].spd.mask = GENERIC_MASK; /* 100Mb/s technologies */
|
||||
lp->phy[k].spd.value = GENERIC_VALUE; /* TX & T4, H/F Duplex */
|
||||
lp->mii_cnt++;
|
||||
lp->active++;
|
||||
printk("%s: Using generic MII device control. If the board doesn't operate,\nplease mail the following dump to the author:\n", dev->name);
|
||||
j = de4x5_debug;
|
||||
de4x5_debug |= DEBUG_MII;
|
||||
de4x5_dbg_mii(dev, k);
|
||||
de4x5_debug = j;
|
||||
printk("\n");
|
||||
} else {
|
||||
goto purgatory;
|
||||
}
|
||||
}
|
||||
}
|
||||
purgatory:
|
||||
|
||||
@@ -373,6 +373,9 @@ struct bufdesc_ex {
|
||||
#define FEC_ENET_WAKEUP ((uint)0x00020000) /* Wakeup request */
|
||||
#define FEC_ENET_TXF (FEC_ENET_TXF_0 | FEC_ENET_TXF_1 | FEC_ENET_TXF_2)
|
||||
#define FEC_ENET_RXF (FEC_ENET_RXF_0 | FEC_ENET_RXF_1 | FEC_ENET_RXF_2)
|
||||
#define FEC_ENET_RXF_GET(X) (((X) == 0) ? FEC_ENET_RXF_0 : \
|
||||
(((X) == 1) ? FEC_ENET_RXF_1 : \
|
||||
FEC_ENET_RXF_2))
|
||||
#define FEC_ENET_TS_AVAIL ((uint)0x00010000)
|
||||
#define FEC_ENET_TS_TIMER ((uint)0x00008000)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user