Merge branch 'zImage_DTB_append' of git://git.linaro.org/people/nico/linux into devel-stable
This commit is contained in:
commit
1db3706b05
|
@ -1,13 +1,21 @@
|
|||
00-INDEX
|
||||
- this file
|
||||
3c359.txt
|
||||
- information on the 3Com TokenLink Velocity XL (3c5359) driver.
|
||||
3c505.txt
|
||||
- information on the 3Com EtherLink Plus (3c505) driver.
|
||||
3c509.txt
|
||||
- information on the 3Com Etherlink III Series Ethernet cards.
|
||||
6pack.txt
|
||||
- info on the 6pack protocol, an alternative to KISS for AX.25
|
||||
DLINK.txt
|
||||
- info on the D-Link DE-600/DE-620 parallel port pocket adapters
|
||||
PLIP.txt
|
||||
- PLIP: The Parallel Line Internet Protocol device driver
|
||||
README.ipw2100
|
||||
- README for the Intel PRO/Wireless 2100 driver.
|
||||
README.ipw2200
|
||||
- README for the Intel PRO/Wireless 2915ABG and 2200BG driver.
|
||||
README.sb1000
|
||||
- info on General Instrument/NextLevel SURFboard1000 cable modem.
|
||||
alias.txt
|
||||
|
@ -20,8 +28,12 @@ atm.txt
|
|||
- info on where to get ATM programs and support for Linux.
|
||||
ax25.txt
|
||||
- info on using AX.25 and NET/ROM code for Linux
|
||||
batman-adv.txt
|
||||
- B.A.T.M.A.N routing protocol on top of layer 2 Ethernet Frames.
|
||||
baycom.txt
|
||||
- info on the driver for Baycom style amateur radio modems
|
||||
bonding.txt
|
||||
- Linux Ethernet Bonding Driver HOWTO: link aggregation in Linux.
|
||||
bridge.txt
|
||||
- where to get user space programs for ethernet bridging with Linux.
|
||||
can.txt
|
||||
|
@ -34,32 +46,60 @@ cxacru.txt
|
|||
- Conexant AccessRunner USB ADSL Modem
|
||||
cxacru-cf.py
|
||||
- Conexant AccessRunner USB ADSL Modem configuration file parser
|
||||
cxgb.txt
|
||||
- Release Notes for the Chelsio N210 Linux device driver.
|
||||
dccp.txt
|
||||
- the Datagram Congestion Control Protocol (DCCP) (RFC 4340..42).
|
||||
de4x5.txt
|
||||
- the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver
|
||||
decnet.txt
|
||||
- info on using the DECnet networking layer in Linux.
|
||||
depca.txt
|
||||
- the Digital DEPCA/EtherWORKS DE1?? and DE2?? LANCE Ethernet driver
|
||||
dl2k.txt
|
||||
- README for D-Link DL2000-based Gigabit Ethernet Adapters (dl2k.ko).
|
||||
dm9000.txt
|
||||
- README for the Simtec DM9000 Network driver.
|
||||
dmfe.txt
|
||||
- info on the Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver.
|
||||
dns_resolver.txt
|
||||
- The DNS resolver module allows kernel servies to make DNS queries.
|
||||
driver.txt
|
||||
- Softnet driver issues.
|
||||
e100.txt
|
||||
- info on Intel's EtherExpress PRO/100 line of 10/100 boards
|
||||
e1000.txt
|
||||
- info on Intel's E1000 line of gigabit ethernet boards
|
||||
e1000e.txt
|
||||
- README for the Intel Gigabit Ethernet Driver (e1000e).
|
||||
eql.txt
|
||||
- serial IP load balancing
|
||||
ewrk3.txt
|
||||
- the Digital EtherWORKS 3 DE203/4/5 Ethernet driver
|
||||
fib_trie.txt
|
||||
- Level Compressed Trie (LC-trie) notes: a structure for routing.
|
||||
filter.txt
|
||||
- Linux Socket Filtering
|
||||
fore200e.txt
|
||||
- FORE Systems PCA-200E/SBA-200E ATM NIC driver info.
|
||||
framerelay.txt
|
||||
- info on using Frame Relay/Data Link Connection Identifier (DLCI).
|
||||
gen_stats.txt
|
||||
- Generic networking statistics for netlink users.
|
||||
generic_hdlc.txt
|
||||
- The generic High Level Data Link Control (HDLC) layer.
|
||||
generic_netlink.txt
|
||||
- info on Generic Netlink
|
||||
gianfar.txt
|
||||
- Gianfar Ethernet Driver.
|
||||
ieee802154.txt
|
||||
- Linux IEEE 802.15.4 implementation, API and drivers
|
||||
ifenslave.c
|
||||
- Configure network interfaces for parallel routing (bonding).
|
||||
igb.txt
|
||||
- README for the Intel Gigabit Ethernet Driver (igb).
|
||||
igbvf.txt
|
||||
- README for the Intel Gigabit Ethernet Driver (igbvf).
|
||||
ip-sysctl.txt
|
||||
- /proc/sys/net/ipv4/* variables
|
||||
ip_dynaddr.txt
|
||||
|
@ -68,41 +108,117 @@ ipddp.txt
|
|||
- AppleTalk-IP Decapsulation and AppleTalk-IP Encapsulation
|
||||
iphase.txt
|
||||
- Interphase PCI ATM (i)Chip IA Linux driver info.
|
||||
ipv6.txt
|
||||
- Options to the ipv6 kernel module.
|
||||
ipvs-sysctl.txt
|
||||
- Per-inode explanation of the /proc/sys/net/ipv4/vs interface.
|
||||
irda.txt
|
||||
- where to get IrDA (infrared) utilities and info for Linux.
|
||||
ixgb.txt
|
||||
- README for the Intel 10 Gigabit Ethernet Driver (ixgb).
|
||||
ixgbe.txt
|
||||
- README for the Intel 10 Gigabit Ethernet Driver (ixgbe).
|
||||
ixgbevf.txt
|
||||
- README for the Intel Virtual Function (VF) Driver (ixgbevf).
|
||||
l2tp.txt
|
||||
- User guide to the L2TP tunnel protocol.
|
||||
lapb-module.txt
|
||||
- programming information of the LAPB module.
|
||||
ltpc.txt
|
||||
- the Apple or Farallon LocalTalk PC card driver
|
||||
mac80211-injection.txt
|
||||
- HOWTO use packet injection with mac80211
|
||||
multicast.txt
|
||||
- Behaviour of cards under Multicast
|
||||
multiqueue.txt
|
||||
- HOWTO for multiqueue network device support.
|
||||
netconsole.txt
|
||||
- The network console module netconsole.ko: configuration and notes.
|
||||
netdev-features.txt
|
||||
- Network interface features API description.
|
||||
netdevices.txt
|
||||
- info on network device driver functions exported to the kernel.
|
||||
netif-msg.txt
|
||||
- Design of the network interface message level setting (NETIF_MSG_*).
|
||||
nfc.txt
|
||||
- The Linux Near Field Communication (NFS) subsystem.
|
||||
olympic.txt
|
||||
- IBM PCI Pit/Pit-Phy/Olympic Token Ring driver info.
|
||||
operstates.txt
|
||||
- Overview of network interface operational states.
|
||||
packet_mmap.txt
|
||||
- User guide to memory mapped packet socket rings (PACKET_[RT]X_RING).
|
||||
phonet.txt
|
||||
- The Phonet packet protocol used in Nokia cellular modems.
|
||||
phy.txt
|
||||
- The PHY abstraction layer.
|
||||
pktgen.txt
|
||||
- User guide to the kernel packet generator (pktgen.ko).
|
||||
policy-routing.txt
|
||||
- IP policy-based routing
|
||||
ppp_generic.txt
|
||||
- Information about the generic PPP driver.
|
||||
proc_net_tcp.txt
|
||||
- Per inode overview of the /proc/net/tcp and /proc/net/tcp6 interfaces.
|
||||
radiotap-headers.txt
|
||||
- Background on radiotap headers.
|
||||
ray_cs.txt
|
||||
- Raylink Wireless LAN card driver info.
|
||||
rds.txt
|
||||
- Background on the reliable, ordered datagram delivery method RDS.
|
||||
regulatory.txt
|
||||
- Overview of the Linux wireless regulatory infrastructure.
|
||||
rxrpc.txt
|
||||
- Guide to the RxRPC protocol.
|
||||
s2io.txt
|
||||
- Release notes for Neterion Xframe I/II 10GbE driver.
|
||||
scaling.txt
|
||||
- Explanation of network scaling techniques: RSS, RPS, RFS, aRFS, XPS.
|
||||
sctp.txt
|
||||
- Notes on the Linux kernel implementation of the SCTP protocol.
|
||||
secid.txt
|
||||
- Explanation of the secid member in flow structures.
|
||||
skfp.txt
|
||||
- SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
|
||||
smc9.txt
|
||||
- the driver for SMC's 9000 series of Ethernet cards
|
||||
smctr.txt
|
||||
- SMC TokenCard TokenRing Linux driver info.
|
||||
spider-net.txt
|
||||
- README for the Spidernet Driver (as found in PS3 / Cell BE).
|
||||
stmmac.txt
|
||||
- README for the STMicro Synopsys Ethernet driver.
|
||||
tc-actions-env-rules.txt
|
||||
- rules for traffic control (tc) actions.
|
||||
timestamping.txt
|
||||
- overview of network packet timestamping variants.
|
||||
tcp.txt
|
||||
- short blurb on how TCP output takes place.
|
||||
tcp-thin.txt
|
||||
- kernel tuning options for low rate 'thin' TCP streams.
|
||||
tlan.txt
|
||||
- ThunderLAN (Compaq Netelligent 10/100, Olicom OC-2xxx) driver info.
|
||||
tms380tr.txt
|
||||
- SysKonnect Token Ring ISA/PCI adapter driver info.
|
||||
tproxy.txt
|
||||
- Transparent proxy support user guide.
|
||||
tuntap.txt
|
||||
- TUN/TAP device driver, allowing user space Rx/Tx of packets.
|
||||
udplite.txt
|
||||
- UDP-Lite protocol (RFC 3828) introduction.
|
||||
vortex.txt
|
||||
- info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) Ethernet cards.
|
||||
vxge.txt
|
||||
- README for the Neterion X3100 PCIe Server Adapter.
|
||||
x25.txt
|
||||
- general info on X.25 development.
|
||||
x25-iface.txt
|
||||
- description of the X.25 Packet Layer to LAPB device interface.
|
||||
xfrm_proc.txt
|
||||
- description of the statistics package for XFRM.
|
||||
xfrm_sync.txt
|
||||
- sync patches for XFRM enable migration of an SA between hosts.
|
||||
xfrm_sysctl.txt
|
||||
- description of the XFRM configuration options.
|
||||
z8530drv.txt
|
||||
- info about Linux driver for Z8530 based HDLC cards for AX.25
|
||||
|
|
|
@ -992,7 +992,7 @@ bindv6only - BOOLEAN
|
|||
TRUE: disable IPv4-mapped address feature
|
||||
FALSE: enable IPv4-mapped address feature
|
||||
|
||||
Default: FALSE (as specified in RFC2553bis)
|
||||
Default: FALSE (as specified in RFC3493)
|
||||
|
||||
IPv6 Fragmentation:
|
||||
|
||||
|
|
|
@ -52,7 +52,8 @@ module parameter for specifying the number of hardware queues to
|
|||
configure. In the bnx2x driver, for instance, this parameter is called
|
||||
num_queues. A typical RSS configuration would be to have one receive queue
|
||||
for each CPU if the device supports enough queues, or otherwise at least
|
||||
one for each cache domain at a particular cache level (L1, L2, etc.).
|
||||
one for each memory domain, where a memory domain is a set of CPUs that
|
||||
share a particular memory level (L1, L2, NUMA node, etc.).
|
||||
|
||||
The indirection table of an RSS device, which resolves a queue by masked
|
||||
hash, is usually programmed by the driver at initialization. The
|
||||
|
@ -82,11 +83,17 @@ RSS should be enabled when latency is a concern or whenever receive
|
|||
interrupt processing forms a bottleneck. Spreading load between CPUs
|
||||
decreases queue length. For low latency networking, the optimal setting
|
||||
is to allocate as many queues as there are CPUs in the system (or the
|
||||
NIC maximum, if lower). Because the aggregate number of interrupts grows
|
||||
with each additional queue, the most efficient high-rate configuration
|
||||
NIC maximum, if lower). The most efficient high-rate configuration
|
||||
is likely the one with the smallest number of receive queues where no
|
||||
CPU that processes receive interrupts reaches 100% utilization. Per-cpu
|
||||
load can be observed using the mpstat utility.
|
||||
receive queue overflows due to a saturated CPU, because in default
|
||||
mode with interrupt coalescing enabled, the aggregate number of
|
||||
interrupts (and thus work) grows with each additional queue.
|
||||
|
||||
Per-cpu load can be observed using the mpstat utility, but note that on
|
||||
processors with hyperthreading (HT), each hyperthread is represented as
|
||||
a separate CPU. For interrupt handling, HT has shown no benefit in
|
||||
initial tests, so limit the number of queues to the number of CPU cores
|
||||
in the system.
|
||||
|
||||
|
||||
RPS: Receive Packet Steering
|
||||
|
@ -145,7 +152,7 @@ the bitmap.
|
|||
== Suggested Configuration
|
||||
|
||||
For a single queue device, a typical RPS configuration would be to set
|
||||
the rps_cpus to the CPUs in the same cache domain of the interrupting
|
||||
the rps_cpus to the CPUs in the same memory domain of the interrupting
|
||||
CPU. If NUMA locality is not an issue, this could also be all CPUs in
|
||||
the system. At high interrupt rate, it might be wise to exclude the
|
||||
interrupting CPU from the map since that already performs much work.
|
||||
|
@ -154,7 +161,7 @@ For a multi-queue system, if RSS is configured so that a hardware
|
|||
receive queue is mapped to each CPU, then RPS is probably redundant
|
||||
and unnecessary. If there are fewer hardware queues than CPUs, then
|
||||
RPS might be beneficial if the rps_cpus for each queue are the ones that
|
||||
share the same cache domain as the interrupting CPU for that queue.
|
||||
share the same memory domain as the interrupting CPU for that queue.
|
||||
|
||||
|
||||
RFS: Receive Flow Steering
|
||||
|
@ -326,7 +333,7 @@ The queue chosen for transmitting a particular flow is saved in the
|
|||
corresponding socket structure for the flow (e.g. a TCP connection).
|
||||
This transmit queue is used for subsequent packets sent on the flow to
|
||||
prevent out of order (ooo) packets. The choice also amortizes the cost
|
||||
of calling get_xps_queues() over all packets in the connection. To avoid
|
||||
of calling get_xps_queues() over all packets in the flow. To avoid
|
||||
ooo packets, the queue for a flow can subsequently only be changed if
|
||||
skb->ooo_okay is set for a packet in the flow. This flag indicates that
|
||||
there are no outstanding packets in the flow, so the transmit queue can
|
||||
|
|
|
@ -431,8 +431,7 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
|
|||
|
||||
void pm_runtime_irq_safe(struct device *dev);
|
||||
- set the power.irq_safe flag for the device, causing the runtime-PM
|
||||
suspend and resume callbacks (but not the idle callback) to be invoked
|
||||
with interrupts disabled
|
||||
callbacks to be invoked with interrupts off
|
||||
|
||||
void pm_runtime_mark_last_busy(struct device *dev);
|
||||
- set the power.last_busy field to the current time
|
||||
|
|
|
@ -1883,7 +1883,7 @@ S: Maintained
|
|||
F: drivers/connector/
|
||||
|
||||
CONTROL GROUPS (CGROUPS)
|
||||
M: Paul Menage <menage@google.com>
|
||||
M: Paul Menage <paul@paulmenage.org>
|
||||
M: Li Zefan <lizf@cn.fujitsu.com>
|
||||
L: containers@lists.linux-foundation.org
|
||||
S: Maintained
|
||||
|
@ -1932,7 +1932,7 @@ S: Maintained
|
|||
F: tools/power/cpupower
|
||||
|
||||
CPUSETS
|
||||
M: Paul Menage <menage@google.com>
|
||||
M: Paul Menage <paul@paulmenage.org>
|
||||
W: http://www.bullopensource.org/cpuset/
|
||||
W: http://oss.sgi.com/projects/cpusets/
|
||||
S: Supported
|
||||
|
@ -5532,6 +5532,7 @@ F: include/media/*7146*
|
|||
|
||||
SAMSUNG AUDIO (ASoC) DRIVERS
|
||||
M: Jassi Brar <jassisinghbrar@gmail.com>
|
||||
M: Sangbeom Kim <sbkim73@samsung.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Supported
|
||||
F: sound/soc/samsung
|
||||
|
@ -7087,7 +7088,7 @@ S: Supported
|
|||
F: drivers/mmc/host/vub300.c
|
||||
|
||||
W1 DALLAS'S 1-WIRE BUS
|
||||
M: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
|
||||
M: Evgeniy Polyakov <zbr@ioremap.net>
|
||||
S: Maintained
|
||||
F: Documentation/w1/
|
||||
F: drivers/w1/
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc3
|
||||
EXTRAVERSION = -rc4
|
||||
NAME = "Divemaster Edition"
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -27,13 +27,4 @@
|
|||
#define UAC_NOFIX 2
|
||||
#define UAC_SIGBUS 4
|
||||
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* This is the shift that is applied to the UAC bits as stored in the
|
||||
per-thread flags. See thread_info.h. */
|
||||
#define UAC_SHIFT 6
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_ALPHA_SYSINFO_H */
|
||||
|
|
|
@ -74,9 +74,9 @@ register struct thread_info *__current_thread_info __asm__("$8");
|
|||
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
|
||||
#define TIF_POLLING_NRFLAG 8 /* poll_idle is polling NEED_RESCHED */
|
||||
#define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */
|
||||
#define TIF_UAC_NOPRINT 10 /* see sysinfo.h */
|
||||
#define TIF_UAC_NOFIX 11
|
||||
#define TIF_UAC_SIGBUS 12
|
||||
#define TIF_UAC_NOPRINT 10 /* ! Preserve sequence of following */
|
||||
#define TIF_UAC_NOFIX 11 /* ! flags as they match */
|
||||
#define TIF_UAC_SIGBUS 12 /* ! userspace part of 'osf_sysinfo' */
|
||||
#define TIF_MEMDIE 13 /* is terminating due to OOM killer */
|
||||
#define TIF_RESTORE_SIGMASK 14 /* restore signal mask in do_signal */
|
||||
#define TIF_FREEZE 16 /* is freezing for suspend */
|
||||
|
@ -97,7 +97,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
|
|||
#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \
|
||||
| _TIF_SYSCALL_TRACE)
|
||||
|
||||
#define ALPHA_UAC_SHIFT 10
|
||||
#define ALPHA_UAC_SHIFT TIF_UAC_NOPRINT
|
||||
#define ALPHA_UAC_MASK (1 << TIF_UAC_NOPRINT | 1 << TIF_UAC_NOFIX | \
|
||||
1 << TIF_UAC_SIGBUS)
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <asm/uaccess.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/sysinfo.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/hwrpb.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
|
@ -633,7 +634,8 @@ SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer,
|
|||
case GSI_UACPROC:
|
||||
if (nbytes < sizeof(unsigned int))
|
||||
return -EINVAL;
|
||||
w = (current_thread_info()->flags >> UAC_SHIFT) & UAC_BITMASK;
|
||||
w = (current_thread_info()->flags >> ALPHA_UAC_SHIFT) &
|
||||
UAC_BITMASK;
|
||||
if (put_user(w, (unsigned int __user *)buffer))
|
||||
return -EFAULT;
|
||||
return 1;
|
||||
|
@ -756,8 +758,8 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer,
|
|||
case SSIN_UACPROC:
|
||||
again:
|
||||
old = current_thread_info()->flags;
|
||||
new = old & ~(UAC_BITMASK << UAC_SHIFT);
|
||||
new = new | (w & UAC_BITMASK) << UAC_SHIFT;
|
||||
new = old & ~(UAC_BITMASK << ALPHA_UAC_SHIFT);
|
||||
new = new | (w & UAC_BITMASK) << ALPHA_UAC_SHIFT;
|
||||
if (cmpxchg(¤t_thread_info()->flags,
|
||||
old, new) != old)
|
||||
goto again;
|
||||
|
|
|
@ -360,7 +360,7 @@ sys_call_table:
|
|||
.quad sys_newuname
|
||||
.quad sys_nanosleep /* 340 */
|
||||
.quad sys_mremap
|
||||
.quad sys_nfsservctl
|
||||
.quad sys_ni_syscall /* old nfsservctl */
|
||||
.quad sys_setresuid
|
||||
.quad sys_getresuid
|
||||
.quad sys_pciconfig_read /* 345 */
|
||||
|
|
|
@ -1781,6 +1781,38 @@ config ZBOOT_ROM_SH_MOBILE_SDHI
|
|||
|
||||
endchoice
|
||||
|
||||
config ARM_APPENDED_DTB
|
||||
bool "Use appended device tree blob to zImage (EXPERIMENTAL)"
|
||||
depends on OF && !ZBOOT_ROM && EXPERIMENTAL
|
||||
help
|
||||
With this option, the boot code will look for a device tree binary
|
||||
(DTB) appended to zImage
|
||||
(e.g. cat zImage <filename>.dtb > zImage_w_dtb).
|
||||
|
||||
This is meant as a backward compatibility convenience for those
|
||||
systems with a bootloader that can't be upgraded to accommodate
|
||||
the documented boot protocol using a device tree.
|
||||
|
||||
Beware that there is very little in terms of protection against
|
||||
this option being confused by leftover garbage in memory that might
|
||||
look like a DTB header after a reboot if no actual DTB is appended
|
||||
to zImage. Do not leave this option active in a production kernel
|
||||
if you don't intend to always append a DTB. Proper passing of the
|
||||
location into r2 of a bootloader provided DTB is always preferable
|
||||
to this option.
|
||||
|
||||
config ARM_ATAG_DTB_COMPAT
|
||||
bool "Supplement the appended DTB with traditional ATAG information"
|
||||
depends on ARM_APPENDED_DTB
|
||||
help
|
||||
Some old bootloaders can't be updated to a DTB capable one, yet
|
||||
they provide ATAGs with memory configuration, the ramdisk address,
|
||||
the kernel cmdline string, etc. Such information is dynamically
|
||||
provided by the bootloader and can't always be stored in a static
|
||||
DTB. To allow a device tree enabled kernel to be used with such
|
||||
bootloaders, this option allows zImage to extract the information
|
||||
from the ATAG list and store it at run time into the appended DTB.
|
||||
|
||||
config CMDLINE
|
||||
string "Default kernel command string"
|
||||
default ""
|
||||
|
|
|
@ -5,3 +5,12 @@ piggy.lzo
|
|||
piggy.lzma
|
||||
vmlinux
|
||||
vmlinux.lds
|
||||
|
||||
# borrowed libfdt files
|
||||
fdt.c
|
||||
fdt.h
|
||||
fdt_ro.c
|
||||
fdt_rw.c
|
||||
fdt_wip.c
|
||||
libfdt.h
|
||||
libfdt_internal.h
|
||||
|
|
|
@ -26,6 +26,10 @@ HEAD = head.o
|
|||
OBJS += misc.o decompress.o
|
||||
FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
|
||||
|
||||
# string library code (-Os is enforced to keep it much smaller)
|
||||
OBJS += string.o
|
||||
CFLAGS_string.o := -Os
|
||||
|
||||
#
|
||||
# Architecture dependencies
|
||||
#
|
||||
|
@ -89,21 +93,41 @@ suffix_$(CONFIG_KERNEL_GZIP) = gzip
|
|||
suffix_$(CONFIG_KERNEL_LZO) = lzo
|
||||
suffix_$(CONFIG_KERNEL_LZMA) = lzma
|
||||
|
||||
# Borrowed libfdt files for the ATAG compatibility mode
|
||||
|
||||
libfdt := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c
|
||||
libfdt_hdrs := fdt.h libfdt.h libfdt_internal.h
|
||||
|
||||
libfdt_objs := $(addsuffix .o, $(basename $(libfdt)))
|
||||
|
||||
$(addprefix $(obj)/,$(libfdt) $(libfdt_hdrs)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/%
|
||||
$(call cmd,shipped)
|
||||
|
||||
$(addprefix $(obj)/,$(libfdt_objs) atags_to_fdt.o): \
|
||||
$(addprefix $(obj)/,$(libfdt_hdrs))
|
||||
|
||||
ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
|
||||
OBJS += $(libfdt_objs) atags_to_fdt.o
|
||||
endif
|
||||
|
||||
targets := vmlinux vmlinux.lds \
|
||||
piggy.$(suffix_y) piggy.$(suffix_y).o \
|
||||
font.o font.c head.o misc.o $(OBJS)
|
||||
lib1funcs.o lib1funcs.S font.o font.c head.o misc.o $(OBJS)
|
||||
|
||||
# Make sure files are removed during clean
|
||||
extra-y += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S
|
||||
extra-y += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S $(libfdt) $(libfdt_hdrs)
|
||||
|
||||
ifeq ($(CONFIG_FUNCTION_TRACER),y)
|
||||
ORIG_CFLAGS := $(KBUILD_CFLAGS)
|
||||
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
|
||||
endif
|
||||
|
||||
ccflags-y := -fpic -fno-builtin
|
||||
ccflags-y := -fpic -fno-builtin -I$(obj)
|
||||
asflags-y := -Wa,-march=all
|
||||
|
||||
# Supply kernel BSS size to the decompressor via a linker symbol.
|
||||
KBSS_SZ = $(shell size $(obj)/../../../../vmlinux | awk 'END{print $$3}')
|
||||
LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
|
||||
# Supply ZRELADDR to the decompressor via a linker symbol.
|
||||
ifneq ($(CONFIG_AUTO_ZRELADDR),y)
|
||||
LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
|
||||
|
@ -123,7 +147,7 @@ LDFLAGS_vmlinux += -T
|
|||
# For __aeabi_uidivmod
|
||||
lib1funcs = $(obj)/lib1funcs.o
|
||||
|
||||
$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
|
||||
$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
|
||||
$(call cmd,shipped)
|
||||
|
||||
# We need to prevent any GOTOFF relocs being used with references
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
#include <asm/setup.h>
|
||||
#include <libfdt.h>
|
||||
|
||||
static int node_offset(void *fdt, const char *node_path)
|
||||
{
|
||||
int offset = fdt_path_offset(fdt, node_path);
|
||||
if (offset == -FDT_ERR_NOTFOUND)
|
||||
offset = fdt_add_subnode(fdt, 0, node_path);
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int setprop(void *fdt, const char *node_path, const char *property,
|
||||
uint32_t *val_array, int size)
|
||||
{
|
||||
int offset = node_offset(fdt, node_path);
|
||||
if (offset < 0)
|
||||
return offset;
|
||||
return fdt_setprop(fdt, offset, property, val_array, size);
|
||||
}
|
||||
|
||||
static int setprop_string(void *fdt, const char *node_path,
|
||||
const char *property, const char *string)
|
||||
{
|
||||
int offset = node_offset(fdt, node_path);
|
||||
if (offset < 0)
|
||||
return offset;
|
||||
return fdt_setprop_string(fdt, offset, property, string);
|
||||
}
|
||||
|
||||
static int setprop_cell(void *fdt, const char *node_path,
|
||||
const char *property, uint32_t val)
|
||||
{
|
||||
int offset = node_offset(fdt, node_path);
|
||||
if (offset < 0)
|
||||
return offset;
|
||||
return fdt_setprop_cell(fdt, offset, property, val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert and fold provided ATAGs into the provided FDT.
|
||||
*
|
||||
* REturn values:
|
||||
* = 0 -> pretend success
|
||||
* = 1 -> bad ATAG (may retry with another possible ATAG pointer)
|
||||
* < 0 -> error from libfdt
|
||||
*/
|
||||
int atags_to_fdt(void *atag_list, void *fdt, int total_space)
|
||||
{
|
||||
struct tag *atag = atag_list;
|
||||
uint32_t mem_reg_property[2 * NR_BANKS];
|
||||
int memcount = 0;
|
||||
int ret;
|
||||
|
||||
/* make sure we've got an aligned pointer */
|
||||
if ((u32)atag_list & 0x3)
|
||||
return 1;
|
||||
|
||||
/* if we get a DTB here we're done already */
|
||||
if (*(u32 *)atag_list == fdt32_to_cpu(FDT_MAGIC))
|
||||
return 0;
|
||||
|
||||
/* validate the ATAG */
|
||||
if (atag->hdr.tag != ATAG_CORE ||
|
||||
(atag->hdr.size != tag_size(tag_core) &&
|
||||
atag->hdr.size != 2))
|
||||
return 1;
|
||||
|
||||
/* let's give it all the room it could need */
|
||||
ret = fdt_open_into(fdt, fdt, total_space);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for_each_tag(atag, atag_list) {
|
||||
if (atag->hdr.tag == ATAG_CMDLINE) {
|
||||
setprop_string(fdt, "/chosen", "bootargs",
|
||||
atag->u.cmdline.cmdline);
|
||||
} else if (atag->hdr.tag == ATAG_MEM) {
|
||||
if (memcount >= sizeof(mem_reg_property)/4)
|
||||
continue;
|
||||
mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start);
|
||||
mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size);
|
||||
} else if (atag->hdr.tag == ATAG_INITRD2) {
|
||||
uint32_t initrd_start, initrd_size;
|
||||
initrd_start = atag->u.initrd.start;
|
||||
initrd_size = atag->u.initrd.size;
|
||||
setprop_cell(fdt, "/chosen", "linux,initrd-start",
|
||||
initrd_start);
|
||||
setprop_cell(fdt, "/chosen", "linux,initrd-end",
|
||||
initrd_start + initrd_size);
|
||||
}
|
||||
}
|
||||
|
||||
if (memcount)
|
||||
setprop(fdt, "/memory", "reg", mem_reg_property, 4*memcount);
|
||||
|
||||
return fdt_pack(fdt);
|
||||
}
|
|
@ -216,6 +216,103 @@ restart: adr r0, LC0
|
|||
mov r10, r6
|
||||
#endif
|
||||
|
||||
mov r5, #0 @ init dtb size to 0
|
||||
#ifdef CONFIG_ARM_APPENDED_DTB
|
||||
/*
|
||||
* r0 = delta
|
||||
* r2 = BSS start
|
||||
* r3 = BSS end
|
||||
* r4 = final kernel address
|
||||
* r5 = appended dtb size (still unknown)
|
||||
* r6 = _edata
|
||||
* r7 = architecture ID
|
||||
* r8 = atags/device tree pointer
|
||||
* r9 = size of decompressed image
|
||||
* r10 = end of this image, including bss/stack/malloc space if non XIP
|
||||
* r11 = GOT start
|
||||
* r12 = GOT end
|
||||
* sp = stack pointer
|
||||
*
|
||||
* if there are device trees (dtb) appended to zImage, advance r10 so that the
|
||||
* dtb data will get relocated along with the kernel if necessary.
|
||||
*/
|
||||
|
||||
ldr lr, [r6, #0]
|
||||
#ifndef __ARMEB__
|
||||
ldr r1, =0xedfe0dd0 @ sig is 0xd00dfeed big endian
|
||||
#else
|
||||
ldr r1, =0xd00dfeed
|
||||
#endif
|
||||
cmp lr, r1
|
||||
bne dtb_check_done @ not found
|
||||
|
||||
#ifdef CONFIG_ARM_ATAG_DTB_COMPAT
|
||||
/*
|
||||
* OK... Let's do some funky business here.
|
||||
* If we do have a DTB appended to zImage, and we do have
|
||||
* an ATAG list around, we want the later to be translated
|
||||
* and folded into the former here. To be on the safe side,
|
||||
* let's temporarily move the stack away into the malloc
|
||||
* area. No GOT fixup has occurred yet, but none of the
|
||||
* code we're about to call uses any global variable.
|
||||
*/
|
||||
add sp, sp, #0x10000
|
||||
stmfd sp!, {r0-r3, ip, lr}
|
||||
mov r0, r8
|
||||
mov r1, r6
|
||||
sub r2, sp, r6
|
||||
bl atags_to_fdt
|
||||
|
||||
/*
|
||||
* If returned value is 1, there is no ATAG at the location
|
||||
* pointed by r8. Try the typical 0x100 offset from start
|
||||
* of RAM and hope for the best.
|
||||
*/
|
||||
cmp r0, #1
|
||||
sub r0, r4, #(TEXT_OFFSET - 0x100)
|
||||
mov r1, r6
|
||||
sub r2, sp, r6
|
||||
blne atags_to_fdt
|
||||
|
||||
ldmfd sp!, {r0-r3, ip, lr}
|
||||
sub sp, sp, #0x10000
|
||||
#endif
|
||||
|
||||
mov r8, r6 @ use the appended device tree
|
||||
|
||||
/*
|
||||
* Make sure that the DTB doesn't end up in the final
|
||||
* kernel's .bss area. To do so, we adjust the decompressed
|
||||
* kernel size to compensate if that .bss size is larger
|
||||
* than the relocated code.
|
||||
*/
|
||||
ldr r5, =_kernel_bss_size
|
||||
adr r1, wont_overwrite
|
||||
sub r1, r6, r1
|
||||
subs r1, r5, r1
|
||||
addhi r9, r9, r1
|
||||
|
||||
/* Get the dtb's size */
|
||||
ldr r5, [r6, #4]
|
||||
#ifndef __ARMEB__
|
||||
/* convert r5 (dtb size) to little endian */
|
||||
eor r1, r5, r5, ror #16
|
||||
bic r1, r1, #0x00ff0000
|
||||
mov r5, r5, ror #8
|
||||
eor r5, r5, r1, lsr #8
|
||||
#endif
|
||||
|
||||
/* preserve 64-bit alignment */
|
||||
add r5, r5, #7
|
||||
bic r5, r5, #7
|
||||
|
||||
/* relocate some pointers past the appended dtb */
|
||||
add r6, r6, r5
|
||||
add r10, r10, r5
|
||||
add sp, sp, r5
|
||||
dtb_check_done:
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check to see if we will overwrite ourselves.
|
||||
* r4 = final kernel address
|
||||
|
@ -223,15 +320,14 @@ restart: adr r0, LC0
|
|||
* r10 = end of this image, including bss/stack/malloc space if non XIP
|
||||
* We basically want:
|
||||
* r4 - 16k page directory >= r10 -> OK
|
||||
* r4 + image length <= current position (pc) -> OK
|
||||
* r4 + image length <= address of wont_overwrite -> OK
|
||||
*/
|
||||
add r10, r10, #16384
|
||||
cmp r4, r10
|
||||
bhs wont_overwrite
|
||||
add r10, r4, r9
|
||||
ARM( cmp r10, pc )
|
||||
THUMB( mov lr, pc )
|
||||
THUMB( cmp r10, lr )
|
||||
adr r9, wont_overwrite
|
||||
cmp r10, r9
|
||||
bls wont_overwrite
|
||||
|
||||
/*
|
||||
|
@ -285,14 +381,16 @@ wont_overwrite:
|
|||
* r2 = BSS start
|
||||
* r3 = BSS end
|
||||
* r4 = kernel execution address
|
||||
* r5 = appended dtb size (0 if not present)
|
||||
* r7 = architecture ID
|
||||
* r8 = atags pointer
|
||||
* r11 = GOT start
|
||||
* r12 = GOT end
|
||||
* sp = stack pointer
|
||||
*/
|
||||
teq r0, #0
|
||||
orrs r1, r0, r5
|
||||
beq not_relocated
|
||||
|
||||
add r11, r11, r0
|
||||
add r12, r12, r0
|
||||
|
||||
|
@ -307,12 +405,21 @@ wont_overwrite:
|
|||
|
||||
/*
|
||||
* Relocate all entries in the GOT table.
|
||||
* Bump bss entries to _edata + dtb size
|
||||
*/
|
||||
1: ldr r1, [r11, #0] @ relocate entries in the GOT
|
||||
add r1, r1, r0 @ table. This fixes up the
|
||||
str r1, [r11], #4 @ C references.
|
||||
add r1, r1, r0 @ This fixes up C references
|
||||
cmp r1, r2 @ if entry >= bss_start &&
|
||||
cmphs r3, r1 @ bss_end > entry
|
||||
addhi r1, r1, r5 @ entry += dtb size
|
||||
str r1, [r11], #4 @ next entry
|
||||
cmp r11, r12
|
||||
blo 1b
|
||||
|
||||
/* bump our bss pointers too */
|
||||
add r2, r2, r5
|
||||
add r3, r3, r5
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef _ARM_LIBFDT_ENV_H
|
||||
#define _ARM_LIBFDT_ENV_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#define fdt16_to_cpu(x) be16_to_cpu(x)
|
||||
#define cpu_to_fdt16(x) cpu_to_be16(x)
|
||||
#define fdt32_to_cpu(x) be32_to_cpu(x)
|
||||
#define cpu_to_fdt32(x) cpu_to_be32(x)
|
||||
#define fdt64_to_cpu(x) be64_to_cpu(x)
|
||||
#define cpu_to_fdt64(x) cpu_to_be64(x)
|
||||
|
||||
#endif
|
|
@ -18,14 +18,9 @@
|
|||
|
||||
unsigned int __machine_arch_type;
|
||||
|
||||
#define _LINUX_STRING_H_
|
||||
|
||||
#include <linux/compiler.h> /* for inline */
|
||||
#include <linux/types.h> /* for size_t */
|
||||
#include <linux/stddef.h> /* for NULL */
|
||||
#include <linux/types.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/string.h>
|
||||
|
||||
|
||||
static void putstr(const char *ptr);
|
||||
extern void error(char *x);
|
||||
|
@ -101,41 +96,6 @@ static void putstr(const char *ptr)
|
|||
flush();
|
||||
}
|
||||
|
||||
|
||||
void *memcpy(void *__dest, __const void *__src, size_t __n)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
|
||||
|
||||
for (i = __n >> 3; i > 0; i--) {
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
if (__n & 1 << 2) {
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
if (__n & 1 << 1) {
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
if (__n & 1)
|
||||
*d++ = *s++;
|
||||
|
||||
return __dest;
|
||||
}
|
||||
|
||||
/*
|
||||
* gzip declarations
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* arch/arm/boot/compressed/string.c
|
||||
*
|
||||
* Small subset of simple string routines
|
||||
*/
|
||||
|
||||
#include <linux/string.h>
|
||||
|
||||
void *memcpy(void *__dest, __const void *__src, size_t __n)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
|
||||
|
||||
for (i = __n >> 3; i > 0; i--) {
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
if (__n & 1 << 2) {
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
if (__n & 1 << 1) {
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
if (__n & 1)
|
||||
*d++ = *s++;
|
||||
|
||||
return __dest;
|
||||
}
|
||||
|
||||
void *memmove(void *__dest, __const void *__src, size_t count)
|
||||
{
|
||||
unsigned char *d = __dest;
|
||||
const unsigned char *s = __src;
|
||||
|
||||
if (__dest == __src)
|
||||
return __dest;
|
||||
|
||||
if (__dest < __src)
|
||||
return memcpy(__dest, __src, count);
|
||||
|
||||
while (count--)
|
||||
d[count] = s[count];
|
||||
return __dest;
|
||||
}
|
||||
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char *sc = s;
|
||||
|
||||
while (*sc != '\0')
|
||||
sc++;
|
||||
return sc - s;
|
||||
}
|
||||
|
||||
int memcmp(const void *cs, const void *ct, size_t count)
|
||||
{
|
||||
const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
|
||||
int res = 0;
|
||||
|
||||
while (su1 < end) {
|
||||
res = *su1++ - *su2++;
|
||||
if (res)
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int strcmp(const char *cs, const char *ct)
|
||||
{
|
||||
unsigned char c1, c2;
|
||||
int res = 0;
|
||||
|
||||
do {
|
||||
c1 = *cs++;
|
||||
c2 = *ct++;
|
||||
res = c1 - c2;
|
||||
if (res)
|
||||
break;
|
||||
} while (c1);
|
||||
return res;
|
||||
}
|
||||
|
||||
void *memchr(const void *s, int c, size_t count)
|
||||
{
|
||||
const unsigned char *p = s;
|
||||
|
||||
while (count--)
|
||||
if ((unsigned char)c == *p++)
|
||||
return (void *)(p - 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *strchr(const char *s, int c)
|
||||
{
|
||||
while (*s != (char)c)
|
||||
if (*s++ == '\0')
|
||||
return NULL;
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
#undef memset
|
||||
|
||||
void *memset(void *s, int c, size_t count)
|
||||
{
|
||||
char *xs = s;
|
||||
while (count--)
|
||||
*xs++ = c;
|
||||
return s;
|
||||
}
|
||||
|
||||
void __memzero(void *s, size_t count)
|
||||
{
|
||||
memset(s, 0, count);
|
||||
}
|
|
@ -51,6 +51,10 @@ SECTIONS
|
|||
_got_start = .;
|
||||
.got : { *(.got) }
|
||||
_got_end = .;
|
||||
|
||||
/* ensure the zImage file size is always a multiple of 64 bits */
|
||||
/* (without a dummy byte, ld just ignores the empty section) */
|
||||
.pad : { BYTE(0); . = ALIGN(8); }
|
||||
_edata = .;
|
||||
|
||||
. = BSS_START;
|
||||
|
|
|
@ -178,7 +178,7 @@
|
|||
CALL(sys_ni_syscall) /* vm86 */
|
||||
CALL(sys_ni_syscall) /* was sys_query_module */
|
||||
CALL(sys_poll)
|
||||
CALL(sys_nfsservctl)
|
||||
CALL(sys_ni_syscall) /* was nfsservctl */
|
||||
/* 170 */ CALL(sys_setresgid16)
|
||||
CALL(sys_getresgid16)
|
||||
CALL(sys_prctl)
|
||||
|
|
|
@ -1415,6 +1415,7 @@ static void __init ap4evb_init(void)
|
|||
fsi_init_pm_clock();
|
||||
sh7372_pm_init();
|
||||
pm_clk_add(&fsi_device.dev, "spu2");
|
||||
pm_clk_add(&lcdc1_device.dev, "hdmi");
|
||||
}
|
||||
|
||||
static void __init ap4evb_timer_init(void)
|
||||
|
|
|
@ -1591,6 +1591,7 @@ static void __init mackerel_init(void)
|
|||
hdmi_init_pm_clock();
|
||||
sh7372_pm_init();
|
||||
pm_clk_add(&fsi_device.dev, "spu2");
|
||||
pm_clk_add(&hdmi_lcdc_device.dev, "hdmi");
|
||||
}
|
||||
|
||||
static void __init mackerel_timer_init(void)
|
||||
|
|
|
@ -655,6 +655,8 @@ static struct clk_lookup lookups[] = {
|
|||
CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
|
||||
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
|
||||
|
||||
CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1",
|
||||
&div6_reparent_clks[DIV6_HDMI]),
|
||||
CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
|
||||
CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
|
||||
CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
|
||||
|
|
|
@ -622,7 +622,8 @@ static struct dev_pm_domain omap_device_pm_domain = {
|
|||
SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
|
||||
_od_runtime_idle)
|
||||
USE_PLATFORM_PM_SLEEP_OPS
|
||||
SET_SYSTEM_SLEEP_PM_OPS(_od_suspend_noirq, _od_resume_noirq)
|
||||
.suspend_noirq = _od_suspend_noirq,
|
||||
.resume_noirq = _od_resume_noirq,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ sys_call_table:
|
|||
.long sys_sched_rr_get_interval
|
||||
.long sys_nanosleep
|
||||
.long sys_poll
|
||||
.long sys_nfsservctl /* 145 */
|
||||
.long sys_ni_syscall /* 145 was nfsservctl */
|
||||
.long sys_setresgid
|
||||
.long sys_getresgid
|
||||
.long sys_prctl
|
||||
|
|
|
@ -1543,7 +1543,7 @@ ENTRY(_sys_call_table)
|
|||
.long _sys_ni_syscall /* for vm86 */
|
||||
.long _sys_ni_syscall /* old "query_module" */
|
||||
.long _sys_ni_syscall /* sys_poll */
|
||||
.long _sys_nfsservctl
|
||||
.long _sys_ni_syscall /* old nfsservctl */
|
||||
.long _sys_setresgid /* setresgid16 */ /* 170 */
|
||||
.long _sys_getresgid /* getresgid16 */
|
||||
.long _sys_prctl
|
||||
|
|
|
@ -771,7 +771,7 @@ sys_call_table:
|
|||
.long sys_ni_syscall /* sys_vm86 */
|
||||
.long sys_ni_syscall /* Old sys_query_module */
|
||||
.long sys_poll
|
||||
.long sys_nfsservctl
|
||||
.long sys_ni_syscall /* old nfsservctl */
|
||||
.long sys_setresgid16 /* 170 */
|
||||
.long sys_getresgid16
|
||||
.long sys_prctl
|
||||
|
|
|
@ -714,7 +714,7 @@ sys_call_table:
|
|||
.long sys_ni_syscall /* sys_vm86 */
|
||||
.long sys_ni_syscall /* Old sys_query_module */
|
||||
.long sys_poll
|
||||
.long sys_nfsservctl
|
||||
.long sys_ni_syscall /* Old nfsservctl */
|
||||
.long sys_setresgid16 /* 170 */
|
||||
.long sys_getresgid16
|
||||
.long sys_prctl
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef _ASM_SERIAL_H
|
||||
#define _ASM_SERIAL_H
|
||||
|
||||
/*
|
||||
* This assumes you have a 1.8432 MHz clock for your UART.
|
||||
*/
|
||||
#define BASE_BAUD (1843200 / 16)
|
||||
|
||||
#endif /* _ASM_SERIAL_H */
|
|
@ -1358,7 +1358,7 @@ sys_call_table:
|
|||
.long sys_ni_syscall /* for vm86 */
|
||||
.long sys_ni_syscall /* Old sys_query_module */
|
||||
.long sys_poll
|
||||
.long sys_nfsservctl
|
||||
.long sys_ni_syscall /* Old nfsservctl */
|
||||
.long sys_setresgid16 /* 170 */
|
||||
.long sys_getresgid16
|
||||
.long sys_prctl
|
||||
|
|
|
@ -183,7 +183,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
|
|||
.long SYMBOL_NAME(sys_ni_syscall) /* for vm86 */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* sys_query_module */
|
||||
.long SYMBOL_NAME(sys_poll)
|
||||
.long SYMBOL_NAME(sys_nfsservctl)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* old nfsservctl */
|
||||
.long SYMBOL_NAME(sys_setresgid16) /* 170 */
|
||||
.long SYMBOL_NAME(sys_getresgid16)
|
||||
.long SYMBOL_NAME(sys_prctl)
|
||||
|
|
|
@ -1614,7 +1614,7 @@ sys_call_table:
|
|||
data8 sys_sched_get_priority_min
|
||||
data8 sys_sched_rr_get_interval
|
||||
data8 sys_nanosleep
|
||||
data8 sys_nfsservctl
|
||||
data8 sys_ni_syscall // old nfsservctl
|
||||
data8 sys_prctl // 1170
|
||||
data8 sys_getpagesize
|
||||
data8 sys_mmap2
|
||||
|
|
|
@ -168,7 +168,7 @@ ENTRY(sys_call_table)
|
|||
.long sys_tas /* vm86 syscall holder */
|
||||
.long sys_ni_syscall /* query_module syscall holder */
|
||||
.long sys_poll
|
||||
.long sys_nfsservctl
|
||||
.long sys_ni_syscall /* was nfsservctl */
|
||||
.long sys_setresgid /* 170 */
|
||||
.long sys_getresgid
|
||||
.long sys_prctl
|
||||
|
|
|
@ -162,7 +162,7 @@ static inline __attribute_const__ int __virt_to_node_shift(void)
|
|||
pgdat->node_mem_map + (__pfn - pgdat->node_start_pfn); \
|
||||
})
|
||||
#define page_to_pfn(_page) ({ \
|
||||
struct page *__p = (_page); \
|
||||
const struct page *__p = (_page); \
|
||||
struct pglist_data *pgdat; \
|
||||
pgdat = &pg_data_map[page_to_nid(__p)]; \
|
||||
((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \
|
||||
|
|
|
@ -189,7 +189,7 @@ ENTRY(sys_call_table)
|
|||
.long sys_getpagesize
|
||||
.long sys_ni_syscall /* old "query_module" */
|
||||
.long sys_poll
|
||||
.long sys_nfsservctl
|
||||
.long sys_ni_syscall /* old nfsservctl */
|
||||
.long sys_setresgid16 /* 170 */
|
||||
.long sys_getresgid16
|
||||
.long sys_prctl
|
||||
|
|
|
@ -173,7 +173,7 @@ ENTRY(sys_call_table)
|
|||
.long sys_ni_syscall /* sys_vm86 */
|
||||
.long sys_ni_syscall /* Old sys_query_module */
|
||||
.long sys_poll
|
||||
.long sys_nfsservctl
|
||||
.long sys_ni_syscall /* old nfsservctl */
|
||||
.long sys_setresgid /* 170 */
|
||||
.long sys_getresgid
|
||||
.long sys_prctl
|
||||
|
|
|
@ -424,7 +424,7 @@ einval: li v0, -ENOSYS
|
|||
sys sys_getresuid 3
|
||||
sys sys_ni_syscall 0 /* was sys_query_module */
|
||||
sys sys_poll 3
|
||||
sys sys_nfsservctl 3
|
||||
sys sys_ni_syscall 0 /* was nfsservctl */
|
||||
sys sys_setresgid 3 /* 4190 */
|
||||
sys sys_getresgid 3
|
||||
sys sys_prctl 5
|
||||
|
|
|
@ -299,7 +299,7 @@ sys_call_table:
|
|||
PTR sys_ni_syscall /* 5170, was get_kernel_syms */
|
||||
PTR sys_ni_syscall /* was query_module */
|
||||
PTR sys_quotactl
|
||||
PTR sys_nfsservctl
|
||||
PTR sys_ni_syscall /* was nfsservctl */
|
||||
PTR sys_ni_syscall /* res. for getpmsg */
|
||||
PTR sys_ni_syscall /* 5175 for putpmsg */
|
||||
PTR sys_ni_syscall /* res. for afs_syscall */
|
||||
|
|
|
@ -294,7 +294,7 @@ EXPORT(sysn32_call_table)
|
|||
PTR sys_ni_syscall /* 6170, was get_kernel_syms */
|
||||
PTR sys_ni_syscall /* was query_module */
|
||||
PTR sys_quotactl
|
||||
PTR compat_sys_nfsservctl
|
||||
PTR sys_ni_syscall /* was nfsservctl */
|
||||
PTR sys_ni_syscall /* res. for getpmsg */
|
||||
PTR sys_ni_syscall /* 6175 for putpmsg */
|
||||
PTR sys_ni_syscall /* res. for afs_syscall */
|
||||
|
|
|
@ -392,7 +392,7 @@ sys_call_table:
|
|||
PTR sys_getresuid
|
||||
PTR sys_ni_syscall /* was query_module */
|
||||
PTR sys_poll
|
||||
PTR compat_sys_nfsservctl
|
||||
PTR sys_ni_syscall /* was nfsservctl */
|
||||
PTR sys_setresgid /* 4190 */
|
||||
PTR sys_getresgid
|
||||
PTR sys_prctl
|
||||
|
|
|
@ -589,7 +589,7 @@ ENTRY(sys_call_table)
|
|||
.long sys_ni_syscall /* vm86 */
|
||||
.long sys_ni_syscall /* Old sys_query_module */
|
||||
.long sys_poll
|
||||
.long sys_nfsservctl
|
||||
.long sys_ni_syscall /* was nfsservctl */
|
||||
.long sys_setresgid16 /* 170 */
|
||||
.long sys_getresgid16
|
||||
.long sys_prctl
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#define ODSR_CLEAR 0x1c00
|
||||
#define LTLEECSR_ENABLE_ALL 0xFFC000FC
|
||||
#define ESCSR_CLEAR 0x07120204
|
||||
#define IECSR_CLEAR 0x80000000
|
||||
|
||||
#define RIO_PORT1_EDCSR 0x0640
|
||||
#define RIO_PORT2_EDCSR 0x0680
|
||||
|
@ -1089,11 +1090,11 @@ static void port_error_handler(struct rio_mport *port, int offset)
|
|||
|
||||
if (offset == 0) {
|
||||
out_be32((u32 *)(rio_regs_win + RIO_PORT1_EDCSR), 0);
|
||||
out_be32((u32 *)(rio_regs_win + RIO_PORT1_IECSR), 0);
|
||||
out_be32((u32 *)(rio_regs_win + RIO_PORT1_IECSR), IECSR_CLEAR);
|
||||
out_be32((u32 *)(rio_regs_win + RIO_ESCSR), ESCSR_CLEAR);
|
||||
} else {
|
||||
out_be32((u32 *)(rio_regs_win + RIO_PORT2_EDCSR), 0);
|
||||
out_be32((u32 *)(rio_regs_win + RIO_PORT2_IECSR), 0);
|
||||
out_be32((u32 *)(rio_regs_win + RIO_PORT2_IECSR), IECSR_CLEAR);
|
||||
out_be32((u32 *)(rio_regs_win + RIO_PORT2_ESCSR), ESCSR_CLEAR);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -665,12 +665,6 @@ ENTRY(sys32_poll_wrapper)
|
|||
lgfr %r4,%r4 # long
|
||||
jg sys_poll # branch to system call
|
||||
|
||||
ENTRY(compat_sys_nfsservctl_wrapper)
|
||||
lgfr %r2,%r2 # int
|
||||
llgtr %r3,%r3 # struct compat_nfsctl_arg*
|
||||
llgtr %r4,%r4 # union compat_nfsctl_res*
|
||||
jg compat_sys_nfsservctl # branch to system call
|
||||
|
||||
ENTRY(sys32_setresgid16_wrapper)
|
||||
llgfr %r2,%r2 # __kernel_old_gid_emu31_t
|
||||
llgfr %r3,%r3 # __kernel_old_gid_emu31_t
|
||||
|
|
|
@ -396,17 +396,19 @@ static __init void detect_machine_facilities(void)
|
|||
static __init void rescue_initrd(void)
|
||||
{
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
unsigned long min_initrd_addr = (unsigned long) _end + (4UL << 20);
|
||||
/*
|
||||
* Move the initrd right behind the bss section in case it starts
|
||||
* within the bss section. So we don't overwrite it when the bss
|
||||
* section gets cleared.
|
||||
* Just like in case of IPL from VM reader we make sure there is a
|
||||
* gap of 4MB between end of kernel and start of initrd.
|
||||
* That way we can also be sure that saving an NSS will succeed,
|
||||
* which however only requires different segments.
|
||||
*/
|
||||
if (!INITRD_START || !INITRD_SIZE)
|
||||
return;
|
||||
if (INITRD_START >= (unsigned long) __bss_stop)
|
||||
if (INITRD_START >= min_initrd_addr)
|
||||
return;
|
||||
memmove(__bss_stop, (void *) INITRD_START, INITRD_SIZE);
|
||||
INITRD_START = (unsigned long) __bss_stop;
|
||||
memmove((void *) min_initrd_addr, (void *) INITRD_START, INITRD_SIZE);
|
||||
INITRD_START = min_initrd_addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1220,7 +1220,7 @@ static int __init reipl_fcp_init(void)
|
|||
/* sysfs: create fcp kset for mixing attr group and bin attrs */
|
||||
reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL,
|
||||
&reipl_kset->kobj);
|
||||
if (!reipl_kset) {
|
||||
if (!reipl_fcp_kset) {
|
||||
free_page((unsigned long) reipl_block_fcp);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -1618,7 +1618,8 @@ static struct shutdown_action vmcmd_action = {SHUTDOWN_ACTION_VMCMD_STR,
|
|||
|
||||
static void stop_run(struct shutdown_trigger *trigger)
|
||||
{
|
||||
if (strcmp(trigger->name, ON_PANIC_STR) == 0)
|
||||
if (strcmp(trigger->name, ON_PANIC_STR) == 0 ||
|
||||
strcmp(trigger->name, ON_RESTART_STR) == 0)
|
||||
disabled_wait((unsigned long) __builtin_return_address(0));
|
||||
while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
|
||||
cpu_relax();
|
||||
|
@ -1717,7 +1718,7 @@ static void do_panic(void)
|
|||
/* on restart */
|
||||
|
||||
static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR,
|
||||
&reipl_action};
|
||||
&stop_action};
|
||||
|
||||
static ssize_t on_restart_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *page)
|
||||
|
|
|
@ -177,7 +177,7 @@ SYSCALL(sys_getresuid16,sys_ni_syscall,sys32_getresuid16_wrapper) /* 165 old get
|
|||
NI_SYSCALL /* for vm86 */
|
||||
NI_SYSCALL /* old sys_query_module */
|
||||
SYSCALL(sys_poll,sys_poll,sys32_poll_wrapper)
|
||||
SYSCALL(sys_nfsservctl,sys_nfsservctl,compat_sys_nfsservctl_wrapper)
|
||||
NI_SYSCALL /* old nfsservctl */
|
||||
SYSCALL(sys_setresgid16,sys_ni_syscall,sys32_setresgid16_wrapper) /* 170 old setresgid16 syscall */
|
||||
SYSCALL(sys_getresgid16,sys_ni_syscall,sys32_getresgid16_wrapper) /* old getresgid16 syscall */
|
||||
SYSCALL(sys_prctl,sys_prctl,sys32_prctl_wrapper)
|
||||
|
|
|
@ -185,7 +185,7 @@ ENTRY(sys_call_table)
|
|||
.long sys_ni_syscall /* vm86 */
|
||||
.long sys_ni_syscall /* old "query_module" */
|
||||
.long sys_poll
|
||||
.long sys_nfsservctl
|
||||
.long sys_ni_syscall /* was nfsservctl */
|
||||
.long sys_setresgid16 /* 170 */
|
||||
.long sys_getresgid16
|
||||
.long sys_prctl
|
||||
|
|
|
@ -189,7 +189,7 @@ sys_call_table:
|
|||
.long sys_ni_syscall /* vm86 */
|
||||
.long sys_ni_syscall /* old "query_module" */
|
||||
.long sys_poll
|
||||
.long sys_nfsservctl
|
||||
.long sys_ni_syscall /* was nfsservctl */
|
||||
.long sys_setresgid16 /* 170 */
|
||||
.long sys_getresgid16
|
||||
.long sys_prctl
|
||||
|
|
|
@ -45,6 +45,19 @@ typedef struct {
|
|||
int si_mask;
|
||||
} __siginfo32_t;
|
||||
|
||||
#define __SIGC_MAXWIN 7
|
||||
|
||||
typedef struct {
|
||||
unsigned long locals[8];
|
||||
unsigned long ins[8];
|
||||
} __siginfo_reg_window;
|
||||
|
||||
typedef struct {
|
||||
int wsaved;
|
||||
__siginfo_reg_window reg_window[__SIGC_MAXWIN];
|
||||
unsigned long rwbuf_stkptrs[__SIGC_MAXWIN];
|
||||
} __siginfo_rwin_t;
|
||||
|
||||
#ifdef CONFIG_SPARC64
|
||||
typedef struct {
|
||||
unsigned int si_float_regs [64];
|
||||
|
@ -73,6 +86,7 @@ struct sigcontext {
|
|||
unsigned long ss_size;
|
||||
} sigc_stack;
|
||||
unsigned long sigc_mask;
|
||||
__siginfo_rwin_t * sigc_rwin_save;
|
||||
};
|
||||
|
||||
#else
|
||||
|
|
|
@ -32,6 +32,7 @@ obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4c_irq.o sun4d_irq.o
|
|||
|
||||
obj-y += process_$(BITS).o
|
||||
obj-y += signal_$(BITS).o
|
||||
obj-y += sigutil_$(BITS).o
|
||||
obj-$(CONFIG_SPARC32) += ioport.o
|
||||
obj-y += setup_$(BITS).o
|
||||
obj-y += idprom.o
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include <asm/visasm.h>
|
||||
#include <asm/compat_signal.h>
|
||||
|
||||
#include "sigutil.h"
|
||||
|
||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||
|
||||
/* This magic should be in g_upper[0] for all upper parts
|
||||
|
@ -44,14 +46,14 @@ typedef struct {
|
|||
struct signal_frame32 {
|
||||
struct sparc_stackf32 ss;
|
||||
__siginfo32_t info;
|
||||
/* __siginfo_fpu32_t * */ u32 fpu_save;
|
||||
/* __siginfo_fpu_t * */ u32 fpu_save;
|
||||
unsigned int insns[2];
|
||||
unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
|
||||
unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
|
||||
/* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
|
||||
siginfo_extra_v8plus_t v8plus;
|
||||
__siginfo_fpu_t fpu_state;
|
||||
};
|
||||
/* __siginfo_rwin_t * */u32 rwin_save;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
typedef struct compat_siginfo{
|
||||
int si_signo;
|
||||
|
@ -110,18 +112,14 @@ struct rt_signal_frame32 {
|
|||
compat_siginfo_t info;
|
||||
struct pt_regs32 regs;
|
||||
compat_sigset_t mask;
|
||||
/* __siginfo_fpu32_t * */ u32 fpu_save;
|
||||
/* __siginfo_fpu_t * */ u32 fpu_save;
|
||||
unsigned int insns[2];
|
||||
stack_t32 stack;
|
||||
unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
|
||||
/* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
|
||||
siginfo_extra_v8plus_t v8plus;
|
||||
__siginfo_fpu_t fpu_state;
|
||||
};
|
||||
|
||||
/* Align macros */
|
||||
#define SF_ALIGNEDSZ (((sizeof(struct signal_frame32) + 15) & (~15)))
|
||||
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 15) & (~15)))
|
||||
/* __siginfo_rwin_t * */u32 rwin_save;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
|
||||
{
|
||||
|
@ -192,30 +190,13 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||
{
|
||||
unsigned long *fpregs = current_thread_info()->fpregs;
|
||||
unsigned long fprs;
|
||||
int err;
|
||||
|
||||
err = __get_user(fprs, &fpu->si_fprs);
|
||||
fprs_write(0);
|
||||
regs->tstate &= ~TSTATE_PEF;
|
||||
if (fprs & FPRS_DL)
|
||||
err |= copy_from_user(fpregs, &fpu->si_float_regs[0], (sizeof(unsigned int) * 32));
|
||||
if (fprs & FPRS_DU)
|
||||
err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], (sizeof(unsigned int) * 32));
|
||||
err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
|
||||
err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
|
||||
current_thread_info()->fpsaved[0] |= fprs;
|
||||
return err;
|
||||
}
|
||||
|
||||
void do_sigreturn32(struct pt_regs *regs)
|
||||
{
|
||||
struct signal_frame32 __user *sf;
|
||||
compat_uptr_t fpu_save;
|
||||
compat_uptr_t rwin_save;
|
||||
unsigned int psr;
|
||||
unsigned pc, npc, fpu_save;
|
||||
unsigned pc, npc;
|
||||
sigset_t set;
|
||||
unsigned seta[_COMPAT_NSIG_WORDS];
|
||||
int err, i;
|
||||
|
@ -273,8 +254,13 @@ void do_sigreturn32(struct pt_regs *regs)
|
|||
pt_regs_clear_syscall(regs);
|
||||
|
||||
err |= __get_user(fpu_save, &sf->fpu_save);
|
||||
if (fpu_save)
|
||||
err |= restore_fpu_state32(regs, &sf->fpu_state);
|
||||
if (!err && fpu_save)
|
||||
err |= restore_fpu_state(regs, compat_ptr(fpu_save));
|
||||
err |= __get_user(rwin_save, &sf->rwin_save);
|
||||
if (!err && rwin_save) {
|
||||
if (restore_rwin_state(compat_ptr(rwin_save)))
|
||||
goto segv;
|
||||
}
|
||||
err |= __get_user(seta[0], &sf->info.si_mask);
|
||||
err |= copy_from_user(seta+1, &sf->extramask,
|
||||
(_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
|
||||
|
@ -300,7 +286,9 @@ segv:
|
|||
asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
|
||||
{
|
||||
struct rt_signal_frame32 __user *sf;
|
||||
unsigned int psr, pc, npc, fpu_save, u_ss_sp;
|
||||
unsigned int psr, pc, npc, u_ss_sp;
|
||||
compat_uptr_t fpu_save;
|
||||
compat_uptr_t rwin_save;
|
||||
mm_segment_t old_fs;
|
||||
sigset_t set;
|
||||
compat_sigset_t seta;
|
||||
|
@ -359,8 +347,8 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
|
|||
pt_regs_clear_syscall(regs);
|
||||
|
||||
err |= __get_user(fpu_save, &sf->fpu_save);
|
||||
if (fpu_save)
|
||||
err |= restore_fpu_state32(regs, &sf->fpu_state);
|
||||
if (!err && fpu_save)
|
||||
err |= restore_fpu_state(regs, compat_ptr(fpu_save));
|
||||
err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
|
||||
err |= __get_user(u_ss_sp, &sf->stack.ss_sp);
|
||||
st.ss_sp = compat_ptr(u_ss_sp);
|
||||
|
@ -376,6 +364,12 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
|
|||
do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf);
|
||||
set_fs(old_fs);
|
||||
|
||||
err |= __get_user(rwin_save, &sf->rwin_save);
|
||||
if (!err && rwin_save) {
|
||||
if (restore_rwin_state(compat_ptr(rwin_save)))
|
||||
goto segv;
|
||||
}
|
||||
|
||||
switch (_NSIG_WORDS) {
|
||||
case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32);
|
||||
case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32);
|
||||
|
@ -433,26 +427,6 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
|
|||
return (void __user *) sp;
|
||||
}
|
||||
|
||||
static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||
{
|
||||
unsigned long *fpregs = current_thread_info()->fpregs;
|
||||
unsigned long fprs;
|
||||
int err = 0;
|
||||
|
||||
fprs = current_thread_info()->fpsaved[0];
|
||||
if (fprs & FPRS_DL)
|
||||
err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
|
||||
(sizeof(unsigned int) * 32));
|
||||
if (fprs & FPRS_DU)
|
||||
err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
|
||||
(sizeof(unsigned int) * 32));
|
||||
err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
|
||||
err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
|
||||
err |= __put_user(fprs, &fpu->si_fprs);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* The I-cache flush instruction only works in the primary ASI, which
|
||||
* right now is the nucleus, aka. kernel space.
|
||||
*
|
||||
|
@ -515,18 +489,23 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
int signo, sigset_t *oldset)
|
||||
{
|
||||
struct signal_frame32 __user *sf;
|
||||
int i, err, wsaved;
|
||||
void __user *tail;
|
||||
int sigframe_size;
|
||||
u32 psr;
|
||||
int i, err;
|
||||
unsigned int seta[_COMPAT_NSIG_WORDS];
|
||||
|
||||
/* 1. Make sure everything is clean */
|
||||
synchronize_user_stack();
|
||||
save_and_clear_fpu();
|
||||
|
||||
sigframe_size = SF_ALIGNEDSZ;
|
||||
if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
|
||||
sigframe_size -= sizeof(__siginfo_fpu_t);
|
||||
wsaved = get_thread_wsaved();
|
||||
|
||||
sigframe_size = sizeof(*sf);
|
||||
if (current_thread_info()->fpsaved[0] & FPRS_FEF)
|
||||
sigframe_size += sizeof(__siginfo_fpu_t);
|
||||
if (wsaved)
|
||||
sigframe_size += sizeof(__siginfo_rwin_t);
|
||||
|
||||
sf = (struct signal_frame32 __user *)
|
||||
get_sigframe(&ka->sa, regs, sigframe_size);
|
||||
|
@ -534,8 +513,7 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
if (invalid_frame_pointer(sf, sigframe_size))
|
||||
goto sigill;
|
||||
|
||||
if (get_thread_wsaved() != 0)
|
||||
goto sigill;
|
||||
tail = (sf + 1);
|
||||
|
||||
/* 2. Save the current process state */
|
||||
if (test_thread_flag(TIF_32BIT)) {
|
||||
|
@ -560,11 +538,22 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
&sf->v8plus.asi);
|
||||
|
||||
if (psr & PSR_EF) {
|
||||
err |= save_fpu_state32(regs, &sf->fpu_state);
|
||||
err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
|
||||
__siginfo_fpu_t __user *fp = tail;
|
||||
tail += sizeof(*fp);
|
||||
err |= save_fpu_state(regs, fp);
|
||||
err |= __put_user((u64)fp, &sf->fpu_save);
|
||||
} else {
|
||||
err |= __put_user(0, &sf->fpu_save);
|
||||
}
|
||||
if (wsaved) {
|
||||
__siginfo_rwin_t __user *rwp = tail;
|
||||
tail += sizeof(*rwp);
|
||||
err |= save_rwin_state(wsaved, rwp);
|
||||
err |= __put_user((u64)rwp, &sf->rwin_save);
|
||||
set_thread_wsaved(0);
|
||||
} else {
|
||||
err |= __put_user(0, &sf->rwin_save);
|
||||
}
|
||||
|
||||
switch (_NSIG_WORDS) {
|
||||
case 4: seta[7] = (oldset->sig[3] >> 32);
|
||||
|
@ -580,10 +569,21 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
err |= __copy_to_user(sf->extramask, seta + 1,
|
||||
(_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
|
||||
|
||||
if (!wsaved) {
|
||||
err |= copy_in_user((u32 __user *)sf,
|
||||
(u32 __user *)(regs->u_regs[UREG_FP]),
|
||||
sizeof(struct reg_window32));
|
||||
} else {
|
||||
struct reg_window *rp;
|
||||
|
||||
rp = ¤t_thread_info()->reg_window[wsaved - 1];
|
||||
for (i = 0; i < 8; i++)
|
||||
err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
|
||||
for (i = 0; i < 6; i++)
|
||||
err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
|
||||
err |= __put_user(rp->ins[6], &sf->ss.fp);
|
||||
err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
|
||||
}
|
||||
if (err)
|
||||
goto sigsegv;
|
||||
|
||||
|
@ -613,7 +613,6 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
|
||||
if (err)
|
||||
goto sigsegv;
|
||||
|
||||
flush_signal_insns(address);
|
||||
}
|
||||
return 0;
|
||||
|
@ -632,18 +631,23 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
siginfo_t *info)
|
||||
{
|
||||
struct rt_signal_frame32 __user *sf;
|
||||
int i, err, wsaved;
|
||||
void __user *tail;
|
||||
int sigframe_size;
|
||||
u32 psr;
|
||||
int i, err;
|
||||
compat_sigset_t seta;
|
||||
|
||||
/* 1. Make sure everything is clean */
|
||||
synchronize_user_stack();
|
||||
save_and_clear_fpu();
|
||||
|
||||
sigframe_size = RT_ALIGNEDSZ;
|
||||
if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
|
||||
sigframe_size -= sizeof(__siginfo_fpu_t);
|
||||
wsaved = get_thread_wsaved();
|
||||
|
||||
sigframe_size = sizeof(*sf);
|
||||
if (current_thread_info()->fpsaved[0] & FPRS_FEF)
|
||||
sigframe_size += sizeof(__siginfo_fpu_t);
|
||||
if (wsaved)
|
||||
sigframe_size += sizeof(__siginfo_rwin_t);
|
||||
|
||||
sf = (struct rt_signal_frame32 __user *)
|
||||
get_sigframe(&ka->sa, regs, sigframe_size);
|
||||
|
@ -651,8 +655,7 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
if (invalid_frame_pointer(sf, sigframe_size))
|
||||
goto sigill;
|
||||
|
||||
if (get_thread_wsaved() != 0)
|
||||
goto sigill;
|
||||
tail = (sf + 1);
|
||||
|
||||
/* 2. Save the current process state */
|
||||
if (test_thread_flag(TIF_32BIT)) {
|
||||
|
@ -677,11 +680,22 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
&sf->v8plus.asi);
|
||||
|
||||
if (psr & PSR_EF) {
|
||||
err |= save_fpu_state32(regs, &sf->fpu_state);
|
||||
err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
|
||||
__siginfo_fpu_t __user *fp = tail;
|
||||
tail += sizeof(*fp);
|
||||
err |= save_fpu_state(regs, fp);
|
||||
err |= __put_user((u64)fp, &sf->fpu_save);
|
||||
} else {
|
||||
err |= __put_user(0, &sf->fpu_save);
|
||||
}
|
||||
if (wsaved) {
|
||||
__siginfo_rwin_t __user *rwp = tail;
|
||||
tail += sizeof(*rwp);
|
||||
err |= save_rwin_state(wsaved, rwp);
|
||||
err |= __put_user((u64)rwp, &sf->rwin_save);
|
||||
set_thread_wsaved(0);
|
||||
} else {
|
||||
err |= __put_user(0, &sf->rwin_save);
|
||||
}
|
||||
|
||||
/* Update the siginfo structure. */
|
||||
err |= copy_siginfo_to_user32(&sf->info, info);
|
||||
|
@ -703,9 +717,21 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
}
|
||||
err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
|
||||
|
||||
if (!wsaved) {
|
||||
err |= copy_in_user((u32 __user *)sf,
|
||||
(u32 __user *)(regs->u_regs[UREG_FP]),
|
||||
sizeof(struct reg_window32));
|
||||
} else {
|
||||
struct reg_window *rp;
|
||||
|
||||
rp = ¤t_thread_info()->reg_window[wsaved - 1];
|
||||
for (i = 0; i < 8; i++)
|
||||
err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
|
||||
for (i = 0; i < 6; i++)
|
||||
err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
|
||||
err |= __put_user(rp->ins[6], &sf->ss.fp);
|
||||
err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
|
||||
}
|
||||
if (err)
|
||||
goto sigsegv;
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include <asm/pgtable.h>
|
||||
#include <asm/cacheflush.h> /* flush_sig_insns */
|
||||
|
||||
#include "sigutil.h"
|
||||
|
||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||
|
||||
extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
|
||||
|
@ -39,8 +41,8 @@ struct signal_frame {
|
|||
unsigned long insns[2] __attribute__ ((aligned (8)));
|
||||
unsigned int extramask[_NSIG_WORDS - 1];
|
||||
unsigned int extra_size; /* Should be 0 */
|
||||
__siginfo_fpu_t fpu_state;
|
||||
};
|
||||
__siginfo_rwin_t __user *rwin_save;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct rt_signal_frame {
|
||||
struct sparc_stackf ss;
|
||||
|
@ -51,8 +53,8 @@ struct rt_signal_frame {
|
|||
unsigned int insns[2];
|
||||
stack_t stack;
|
||||
unsigned int extra_size; /* Should be 0 */
|
||||
__siginfo_fpu_t fpu_state;
|
||||
};
|
||||
__siginfo_rwin_t __user *rwin_save;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* Align macros */
|
||||
#define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7)))
|
||||
|
@ -79,43 +81,13 @@ asmlinkage int sys_sigsuspend(old_sigset_t set)
|
|||
return _sigpause_common(set);
|
||||
}
|
||||
|
||||
static inline int
|
||||
restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||
{
|
||||
int err;
|
||||
#ifdef CONFIG_SMP
|
||||
if (test_tsk_thread_flag(current, TIF_USEDFPU))
|
||||
regs->psr &= ~PSR_EF;
|
||||
#else
|
||||
if (current == last_task_used_math) {
|
||||
last_task_used_math = NULL;
|
||||
regs->psr &= ~PSR_EF;
|
||||
}
|
||||
#endif
|
||||
set_used_math();
|
||||
clear_tsk_thread_flag(current, TIF_USEDFPU);
|
||||
|
||||
if (!access_ok(VERIFY_READ, fpu, sizeof(*fpu)))
|
||||
return -EFAULT;
|
||||
|
||||
err = __copy_from_user(¤t->thread.float_regs[0], &fpu->si_float_regs[0],
|
||||
(sizeof(unsigned long) * 32));
|
||||
err |= __get_user(current->thread.fsr, &fpu->si_fsr);
|
||||
err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
|
||||
if (current->thread.fpqdepth != 0)
|
||||
err |= __copy_from_user(¤t->thread.fpqueue[0],
|
||||
&fpu->si_fpqueue[0],
|
||||
((sizeof(unsigned long) +
|
||||
(sizeof(unsigned long *)))*16));
|
||||
return err;
|
||||
}
|
||||
|
||||
asmlinkage void do_sigreturn(struct pt_regs *regs)
|
||||
{
|
||||
struct signal_frame __user *sf;
|
||||
unsigned long up_psr, pc, npc;
|
||||
sigset_t set;
|
||||
__siginfo_fpu_t __user *fpu_save;
|
||||
__siginfo_rwin_t __user *rwin_save;
|
||||
int err;
|
||||
|
||||
/* Always make any pending restarted system calls return -EINTR */
|
||||
|
@ -150,9 +122,11 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
|
|||
pt_regs_clear_syscall(regs);
|
||||
|
||||
err |= __get_user(fpu_save, &sf->fpu_save);
|
||||
|
||||
if (fpu_save)
|
||||
err |= restore_fpu_state(regs, fpu_save);
|
||||
err |= __get_user(rwin_save, &sf->rwin_save);
|
||||
if (rwin_save)
|
||||
err |= restore_rwin_state(rwin_save);
|
||||
|
||||
/* This is pretty much atomic, no amount locking would prevent
|
||||
* the races which exist anyways.
|
||||
|
@ -180,6 +154,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
|
|||
struct rt_signal_frame __user *sf;
|
||||
unsigned int psr, pc, npc;
|
||||
__siginfo_fpu_t __user *fpu_save;
|
||||
__siginfo_rwin_t __user *rwin_save;
|
||||
mm_segment_t old_fs;
|
||||
sigset_t set;
|
||||
stack_t st;
|
||||
|
@ -207,8 +182,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
|
|||
pt_regs_clear_syscall(regs);
|
||||
|
||||
err |= __get_user(fpu_save, &sf->fpu_save);
|
||||
|
||||
if (fpu_save)
|
||||
if (!err && fpu_save)
|
||||
err |= restore_fpu_state(regs, fpu_save);
|
||||
err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
|
||||
|
||||
|
@ -228,6 +202,12 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
|
|||
do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf);
|
||||
set_fs(old_fs);
|
||||
|
||||
err |= __get_user(rwin_save, &sf->rwin_save);
|
||||
if (!err && rwin_save) {
|
||||
if (restore_rwin_state(rwin_save))
|
||||
goto segv;
|
||||
}
|
||||
|
||||
sigdelsetmask(&set, ~_BLOCKABLE);
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
current->blocked = set;
|
||||
|
@ -280,53 +260,23 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re
|
|||
return (void __user *) sp;
|
||||
}
|
||||
|
||||
static inline int
|
||||
save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||
{
|
||||
int err = 0;
|
||||
#ifdef CONFIG_SMP
|
||||
if (test_tsk_thread_flag(current, TIF_USEDFPU)) {
|
||||
put_psr(get_psr() | PSR_EF);
|
||||
fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr,
|
||||
¤t->thread.fpqueue[0], ¤t->thread.fpqdepth);
|
||||
regs->psr &= ~(PSR_EF);
|
||||
clear_tsk_thread_flag(current, TIF_USEDFPU);
|
||||
}
|
||||
#else
|
||||
if (current == last_task_used_math) {
|
||||
put_psr(get_psr() | PSR_EF);
|
||||
fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr,
|
||||
¤t->thread.fpqueue[0], ¤t->thread.fpqdepth);
|
||||
last_task_used_math = NULL;
|
||||
regs->psr &= ~(PSR_EF);
|
||||
}
|
||||
#endif
|
||||
err |= __copy_to_user(&fpu->si_float_regs[0],
|
||||
¤t->thread.float_regs[0],
|
||||
(sizeof(unsigned long) * 32));
|
||||
err |= __put_user(current->thread.fsr, &fpu->si_fsr);
|
||||
err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
|
||||
if (current->thread.fpqdepth != 0)
|
||||
err |= __copy_to_user(&fpu->si_fpqueue[0],
|
||||
¤t->thread.fpqueue[0],
|
||||
((sizeof(unsigned long) +
|
||||
(sizeof(unsigned long *)))*16));
|
||||
clear_used_math();
|
||||
return err;
|
||||
}
|
||||
|
||||
static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
|
||||
int signo, sigset_t *oldset)
|
||||
{
|
||||
struct signal_frame __user *sf;
|
||||
int sigframe_size, err;
|
||||
int sigframe_size, err, wsaved;
|
||||
void __user *tail;
|
||||
|
||||
/* 1. Make sure everything is clean */
|
||||
synchronize_user_stack();
|
||||
|
||||
sigframe_size = SF_ALIGNEDSZ;
|
||||
if (!used_math())
|
||||
sigframe_size -= sizeof(__siginfo_fpu_t);
|
||||
wsaved = current_thread_info()->w_saved;
|
||||
|
||||
sigframe_size = sizeof(*sf);
|
||||
if (used_math())
|
||||
sigframe_size += sizeof(__siginfo_fpu_t);
|
||||
if (wsaved)
|
||||
sigframe_size += sizeof(__siginfo_rwin_t);
|
||||
|
||||
sf = (struct signal_frame __user *)
|
||||
get_sigframe(&ka->sa, regs, sigframe_size);
|
||||
|
@ -334,8 +284,7 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
if (invalid_frame_pointer(sf, sigframe_size))
|
||||
goto sigill_and_return;
|
||||
|
||||
if (current_thread_info()->w_saved != 0)
|
||||
goto sigill_and_return;
|
||||
tail = sf + 1;
|
||||
|
||||
/* 2. Save the current process state */
|
||||
err = __copy_to_user(&sf->info.si_regs, regs, sizeof(struct pt_regs));
|
||||
|
@ -343,17 +292,34 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
err |= __put_user(0, &sf->extra_size);
|
||||
|
||||
if (used_math()) {
|
||||
err |= save_fpu_state(regs, &sf->fpu_state);
|
||||
err |= __put_user(&sf->fpu_state, &sf->fpu_save);
|
||||
__siginfo_fpu_t __user *fp = tail;
|
||||
tail += sizeof(*fp);
|
||||
err |= save_fpu_state(regs, fp);
|
||||
err |= __put_user(fp, &sf->fpu_save);
|
||||
} else {
|
||||
err |= __put_user(0, &sf->fpu_save);
|
||||
}
|
||||
if (wsaved) {
|
||||
__siginfo_rwin_t __user *rwp = tail;
|
||||
tail += sizeof(*rwp);
|
||||
err |= save_rwin_state(wsaved, rwp);
|
||||
err |= __put_user(rwp, &sf->rwin_save);
|
||||
} else {
|
||||
err |= __put_user(0, &sf->rwin_save);
|
||||
}
|
||||
|
||||
err |= __put_user(oldset->sig[0], &sf->info.si_mask);
|
||||
err |= __copy_to_user(sf->extramask, &oldset->sig[1],
|
||||
(_NSIG_WORDS - 1) * sizeof(unsigned int));
|
||||
if (!wsaved) {
|
||||
err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
|
||||
sizeof(struct reg_window32));
|
||||
} else {
|
||||
struct reg_window32 *rp;
|
||||
|
||||
rp = ¤t_thread_info()->reg_window[wsaved - 1];
|
||||
err |= __copy_to_user(sf, rp, sizeof(struct reg_window32));
|
||||
}
|
||||
if (err)
|
||||
goto sigsegv;
|
||||
|
||||
|
@ -399,21 +365,24 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
int signo, sigset_t *oldset, siginfo_t *info)
|
||||
{
|
||||
struct rt_signal_frame __user *sf;
|
||||
int sigframe_size;
|
||||
int sigframe_size, wsaved;
|
||||
void __user *tail;
|
||||
unsigned int psr;
|
||||
int err;
|
||||
|
||||
synchronize_user_stack();
|
||||
sigframe_size = RT_ALIGNEDSZ;
|
||||
if (!used_math())
|
||||
sigframe_size -= sizeof(__siginfo_fpu_t);
|
||||
wsaved = current_thread_info()->w_saved;
|
||||
sigframe_size = sizeof(*sf);
|
||||
if (used_math())
|
||||
sigframe_size += sizeof(__siginfo_fpu_t);
|
||||
if (wsaved)
|
||||
sigframe_size += sizeof(__siginfo_rwin_t);
|
||||
sf = (struct rt_signal_frame __user *)
|
||||
get_sigframe(&ka->sa, regs, sigframe_size);
|
||||
if (invalid_frame_pointer(sf, sigframe_size))
|
||||
goto sigill;
|
||||
if (current_thread_info()->w_saved != 0)
|
||||
goto sigill;
|
||||
|
||||
tail = sf + 1;
|
||||
err = __put_user(regs->pc, &sf->regs.pc);
|
||||
err |= __put_user(regs->npc, &sf->regs.npc);
|
||||
err |= __put_user(regs->y, &sf->regs.y);
|
||||
|
@ -425,11 +394,21 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
err |= __put_user(0, &sf->extra_size);
|
||||
|
||||
if (psr & PSR_EF) {
|
||||
err |= save_fpu_state(regs, &sf->fpu_state);
|
||||
err |= __put_user(&sf->fpu_state, &sf->fpu_save);
|
||||
__siginfo_fpu_t *fp = tail;
|
||||
tail += sizeof(*fp);
|
||||
err |= save_fpu_state(regs, fp);
|
||||
err |= __put_user(fp, &sf->fpu_save);
|
||||
} else {
|
||||
err |= __put_user(0, &sf->fpu_save);
|
||||
}
|
||||
if (wsaved) {
|
||||
__siginfo_rwin_t *rwp = tail;
|
||||
tail += sizeof(*rwp);
|
||||
err |= save_rwin_state(wsaved, rwp);
|
||||
err |= __put_user(rwp, &sf->rwin_save);
|
||||
} else {
|
||||
err |= __put_user(0, &sf->rwin_save);
|
||||
}
|
||||
err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));
|
||||
|
||||
/* Setup sigaltstack */
|
||||
|
@ -437,8 +416,15 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
|
||||
err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
|
||||
|
||||
if (!wsaved) {
|
||||
err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
|
||||
sizeof(struct reg_window32));
|
||||
} else {
|
||||
struct reg_window32 *rp;
|
||||
|
||||
rp = ¤t_thread_info()->reg_window[wsaved - 1];
|
||||
err |= __copy_to_user(sf, rp, sizeof(struct reg_window32));
|
||||
}
|
||||
|
||||
err |= copy_siginfo_to_user(&sf->info, info);
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "entry.h"
|
||||
#include "systbls.h"
|
||||
#include "sigutil.h"
|
||||
|
||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||
|
||||
|
@ -236,7 +237,7 @@ struct rt_signal_frame {
|
|||
__siginfo_fpu_t __user *fpu_save;
|
||||
stack_t stack;
|
||||
sigset_t mask;
|
||||
__siginfo_fpu_t fpu_state;
|
||||
__siginfo_rwin_t *rwin_save;
|
||||
};
|
||||
|
||||
static long _sigpause_common(old_sigset_t set)
|
||||
|
@ -266,33 +267,12 @@ asmlinkage long sys_sigsuspend(old_sigset_t set)
|
|||
return _sigpause_common(set);
|
||||
}
|
||||
|
||||
static inline int
|
||||
restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||
{
|
||||
unsigned long *fpregs = current_thread_info()->fpregs;
|
||||
unsigned long fprs;
|
||||
int err;
|
||||
|
||||
err = __get_user(fprs, &fpu->si_fprs);
|
||||
fprs_write(0);
|
||||
regs->tstate &= ~TSTATE_PEF;
|
||||
if (fprs & FPRS_DL)
|
||||
err |= copy_from_user(fpregs, &fpu->si_float_regs[0],
|
||||
(sizeof(unsigned int) * 32));
|
||||
if (fprs & FPRS_DU)
|
||||
err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32],
|
||||
(sizeof(unsigned int) * 32));
|
||||
err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
|
||||
err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
|
||||
current_thread_info()->fpsaved[0] |= fprs;
|
||||
return err;
|
||||
}
|
||||
|
||||
void do_rt_sigreturn(struct pt_regs *regs)
|
||||
{
|
||||
struct rt_signal_frame __user *sf;
|
||||
unsigned long tpc, tnpc, tstate;
|
||||
__siginfo_fpu_t __user *fpu_save;
|
||||
__siginfo_rwin_t __user *rwin_save;
|
||||
sigset_t set;
|
||||
int err;
|
||||
|
||||
|
@ -325,8 +305,8 @@ void do_rt_sigreturn(struct pt_regs *regs)
|
|||
regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));
|
||||
|
||||
err |= __get_user(fpu_save, &sf->fpu_save);
|
||||
if (fpu_save)
|
||||
err |= restore_fpu_state(regs, &sf->fpu_state);
|
||||
if (!err && fpu_save)
|
||||
err |= restore_fpu_state(regs, fpu_save);
|
||||
|
||||
err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
|
||||
err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf);
|
||||
|
@ -334,6 +314,12 @@ void do_rt_sigreturn(struct pt_regs *regs)
|
|||
if (err)
|
||||
goto segv;
|
||||
|
||||
err |= __get_user(rwin_save, &sf->rwin_save);
|
||||
if (!err && rwin_save) {
|
||||
if (restore_rwin_state(rwin_save))
|
||||
goto segv;
|
||||
}
|
||||
|
||||
regs->tpc = tpc;
|
||||
regs->tnpc = tnpc;
|
||||
|
||||
|
@ -351,34 +337,13 @@ segv:
|
|||
}
|
||||
|
||||
/* Checks if the fp is valid */
|
||||
static int invalid_frame_pointer(void __user *fp, int fplen)
|
||||
static int invalid_frame_pointer(void __user *fp)
|
||||
{
|
||||
if (((unsigned long) fp) & 15)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||
{
|
||||
unsigned long *fpregs = current_thread_info()->fpregs;
|
||||
unsigned long fprs;
|
||||
int err = 0;
|
||||
|
||||
fprs = current_thread_info()->fpsaved[0];
|
||||
if (fprs & FPRS_DL)
|
||||
err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
|
||||
(sizeof(unsigned int) * 32));
|
||||
if (fprs & FPRS_DU)
|
||||
err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
|
||||
(sizeof(unsigned int) * 32));
|
||||
err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
|
||||
err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
|
||||
err |= __put_user(fprs, &fpu->si_fprs);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
|
||||
{
|
||||
unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
|
||||
|
@ -414,34 +379,48 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
int signo, sigset_t *oldset, siginfo_t *info)
|
||||
{
|
||||
struct rt_signal_frame __user *sf;
|
||||
int sigframe_size, err;
|
||||
int wsaved, err, sf_size;
|
||||
void __user *tail;
|
||||
|
||||
/* 1. Make sure everything is clean */
|
||||
synchronize_user_stack();
|
||||
save_and_clear_fpu();
|
||||
|
||||
sigframe_size = sizeof(struct rt_signal_frame);
|
||||
if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
|
||||
sigframe_size -= sizeof(__siginfo_fpu_t);
|
||||
wsaved = get_thread_wsaved();
|
||||
|
||||
sf_size = sizeof(struct rt_signal_frame);
|
||||
if (current_thread_info()->fpsaved[0] & FPRS_FEF)
|
||||
sf_size += sizeof(__siginfo_fpu_t);
|
||||
if (wsaved)
|
||||
sf_size += sizeof(__siginfo_rwin_t);
|
||||
sf = (struct rt_signal_frame __user *)
|
||||
get_sigframe(ka, regs, sigframe_size);
|
||||
get_sigframe(ka, regs, sf_size);
|
||||
|
||||
if (invalid_frame_pointer (sf, sigframe_size))
|
||||
if (invalid_frame_pointer (sf))
|
||||
goto sigill;
|
||||
|
||||
if (get_thread_wsaved() != 0)
|
||||
goto sigill;
|
||||
tail = (sf + 1);
|
||||
|
||||
/* 2. Save the current process state */
|
||||
err = copy_to_user(&sf->regs, regs, sizeof (*regs));
|
||||
|
||||
if (current_thread_info()->fpsaved[0] & FPRS_FEF) {
|
||||
err |= save_fpu_state(regs, &sf->fpu_state);
|
||||
err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
|
||||
__siginfo_fpu_t __user *fpu_save = tail;
|
||||
tail += sizeof(__siginfo_fpu_t);
|
||||
err |= save_fpu_state(regs, fpu_save);
|
||||
err |= __put_user((u64)fpu_save, &sf->fpu_save);
|
||||
} else {
|
||||
err |= __put_user(0, &sf->fpu_save);
|
||||
}
|
||||
if (wsaved) {
|
||||
__siginfo_rwin_t __user *rwin_save = tail;
|
||||
tail += sizeof(__siginfo_rwin_t);
|
||||
err |= save_rwin_state(wsaved, rwin_save);
|
||||
err |= __put_user((u64)rwin_save, &sf->rwin_save);
|
||||
set_thread_wsaved(0);
|
||||
} else {
|
||||
err |= __put_user(0, &sf->rwin_save);
|
||||
}
|
||||
|
||||
/* Setup sigaltstack */
|
||||
err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
|
||||
|
@ -450,10 +429,17 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
|
|||
|
||||
err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t));
|
||||
|
||||
if (!wsaved) {
|
||||
err |= copy_in_user((u64 __user *)sf,
|
||||
(u64 __user *)(regs->u_regs[UREG_FP]+STACK_BIAS),
|
||||
(u64 __user *)(regs->u_regs[UREG_FP] +
|
||||
STACK_BIAS),
|
||||
sizeof(struct reg_window));
|
||||
} else {
|
||||
struct reg_window *rp;
|
||||
|
||||
rp = ¤t_thread_info()->reg_window[wsaved - 1];
|
||||
err |= copy_to_user(sf, rp, sizeof(struct reg_window));
|
||||
}
|
||||
if (info)
|
||||
err |= copy_siginfo_to_user(&sf->info, info);
|
||||
else {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef _SIGUTIL_H
|
||||
#define _SIGUTIL_H
|
||||
|
||||
int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu);
|
||||
int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu);
|
||||
int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin);
|
||||
int restore_rwin_state(__siginfo_rwin_t __user *rp);
|
||||
|
||||
#endif /* _SIGUTIL_H */
|
|
@ -0,0 +1,120 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/thread_info.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include <asm/sigcontext.h>
|
||||
#include <asm/fpumacro.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
#include "sigutil.h"
|
||||
|
||||
int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||
{
|
||||
int err = 0;
|
||||
#ifdef CONFIG_SMP
|
||||
if (test_tsk_thread_flag(current, TIF_USEDFPU)) {
|
||||
put_psr(get_psr() | PSR_EF);
|
||||
fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr,
|
||||
¤t->thread.fpqueue[0], ¤t->thread.fpqdepth);
|
||||
regs->psr &= ~(PSR_EF);
|
||||
clear_tsk_thread_flag(current, TIF_USEDFPU);
|
||||
}
|
||||
#else
|
||||
if (current == last_task_used_math) {
|
||||
put_psr(get_psr() | PSR_EF);
|
||||
fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr,
|
||||
¤t->thread.fpqueue[0], ¤t->thread.fpqdepth);
|
||||
last_task_used_math = NULL;
|
||||
regs->psr &= ~(PSR_EF);
|
||||
}
|
||||
#endif
|
||||
err |= __copy_to_user(&fpu->si_float_regs[0],
|
||||
¤t->thread.float_regs[0],
|
||||
(sizeof(unsigned long) * 32));
|
||||
err |= __put_user(current->thread.fsr, &fpu->si_fsr);
|
||||
err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
|
||||
if (current->thread.fpqdepth != 0)
|
||||
err |= __copy_to_user(&fpu->si_fpqueue[0],
|
||||
¤t->thread.fpqueue[0],
|
||||
((sizeof(unsigned long) +
|
||||
(sizeof(unsigned long *)))*16));
|
||||
clear_used_math();
|
||||
return err;
|
||||
}
|
||||
|
||||
int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||
{
|
||||
int err;
|
||||
#ifdef CONFIG_SMP
|
||||
if (test_tsk_thread_flag(current, TIF_USEDFPU))
|
||||
regs->psr &= ~PSR_EF;
|
||||
#else
|
||||
if (current == last_task_used_math) {
|
||||
last_task_used_math = NULL;
|
||||
regs->psr &= ~PSR_EF;
|
||||
}
|
||||
#endif
|
||||
set_used_math();
|
||||
clear_tsk_thread_flag(current, TIF_USEDFPU);
|
||||
|
||||
if (!access_ok(VERIFY_READ, fpu, sizeof(*fpu)))
|
||||
return -EFAULT;
|
||||
|
||||
err = __copy_from_user(¤t->thread.float_regs[0], &fpu->si_float_regs[0],
|
||||
(sizeof(unsigned long) * 32));
|
||||
err |= __get_user(current->thread.fsr, &fpu->si_fsr);
|
||||
err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
|
||||
if (current->thread.fpqdepth != 0)
|
||||
err |= __copy_from_user(¤t->thread.fpqueue[0],
|
||||
&fpu->si_fpqueue[0],
|
||||
((sizeof(unsigned long) +
|
||||
(sizeof(unsigned long *)))*16));
|
||||
return err;
|
||||
}
|
||||
|
||||
int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin)
|
||||
{
|
||||
int i, err = __put_user(wsaved, &rwin->wsaved);
|
||||
|
||||
for (i = 0; i < wsaved; i++) {
|
||||
struct reg_window32 *rp;
|
||||
unsigned long fp;
|
||||
|
||||
rp = ¤t_thread_info()->reg_window[i];
|
||||
fp = current_thread_info()->rwbuf_stkptrs[i];
|
||||
err |= copy_to_user(&rwin->reg_window[i], rp,
|
||||
sizeof(struct reg_window32));
|
||||
err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int restore_rwin_state(__siginfo_rwin_t __user *rp)
|
||||
{
|
||||
struct thread_info *t = current_thread_info();
|
||||
int i, wsaved, err;
|
||||
|
||||
__get_user(wsaved, &rp->wsaved);
|
||||
if (wsaved > NSWINS)
|
||||
return -EFAULT;
|
||||
|
||||
err = 0;
|
||||
for (i = 0; i < wsaved; i++) {
|
||||
err |= copy_from_user(&t->reg_window[i],
|
||||
&rp->reg_window[i],
|
||||
sizeof(struct reg_window32));
|
||||
err |= __get_user(t->rwbuf_stkptrs[i],
|
||||
&rp->rwbuf_stkptrs[i]);
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
t->w_saved = wsaved;
|
||||
synchronize_user_stack();
|
||||
if (t->w_saved)
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/thread_info.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/sigcontext.h>
|
||||
#include <asm/fpumacro.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
#include "sigutil.h"
|
||||
|
||||
int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||
{
|
||||
unsigned long *fpregs = current_thread_info()->fpregs;
|
||||
unsigned long fprs;
|
||||
int err = 0;
|
||||
|
||||
fprs = current_thread_info()->fpsaved[0];
|
||||
if (fprs & FPRS_DL)
|
||||
err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
|
||||
(sizeof(unsigned int) * 32));
|
||||
if (fprs & FPRS_DU)
|
||||
err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
|
||||
(sizeof(unsigned int) * 32));
|
||||
err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
|
||||
err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
|
||||
err |= __put_user(fprs, &fpu->si_fprs);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||
{
|
||||
unsigned long *fpregs = current_thread_info()->fpregs;
|
||||
unsigned long fprs;
|
||||
int err;
|
||||
|
||||
err = __get_user(fprs, &fpu->si_fprs);
|
||||
fprs_write(0);
|
||||
regs->tstate &= ~TSTATE_PEF;
|
||||
if (fprs & FPRS_DL)
|
||||
err |= copy_from_user(fpregs, &fpu->si_float_regs[0],
|
||||
(sizeof(unsigned int) * 32));
|
||||
if (fprs & FPRS_DU)
|
||||
err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32],
|
||||
(sizeof(unsigned int) * 32));
|
||||
err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
|
||||
err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
|
||||
current_thread_info()->fpsaved[0] |= fprs;
|
||||
return err;
|
||||
}
|
||||
|
||||
int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin)
|
||||
{
|
||||
int i, err = __put_user(wsaved, &rwin->wsaved);
|
||||
|
||||
for (i = 0; i < wsaved; i++) {
|
||||
struct reg_window *rp = ¤t_thread_info()->reg_window[i];
|
||||
unsigned long fp = current_thread_info()->rwbuf_stkptrs[i];
|
||||
|
||||
err |= copy_to_user(&rwin->reg_window[i], rp,
|
||||
sizeof(struct reg_window));
|
||||
err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int restore_rwin_state(__siginfo_rwin_t __user *rp)
|
||||
{
|
||||
struct thread_info *t = current_thread_info();
|
||||
int i, wsaved, err;
|
||||
|
||||
__get_user(wsaved, &rp->wsaved);
|
||||
if (wsaved > NSWINS)
|
||||
return -EFAULT;
|
||||
|
||||
err = 0;
|
||||
for (i = 0; i < wsaved; i++) {
|
||||
err |= copy_from_user(&t->reg_window[i],
|
||||
&rp->reg_window[i],
|
||||
sizeof(struct reg_window));
|
||||
err |= __get_user(t->rwbuf_stkptrs[i],
|
||||
&rp->rwbuf_stkptrs[i]);
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
set_thread_wsaved(wsaved);
|
||||
synchronize_user_stack();
|
||||
if (get_thread_wsaved())
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
|
@ -81,7 +81,6 @@ SIGN2(sys32_fadvise64, compat_sys_fadvise64, %o0, %o4)
|
|||
SIGN2(sys32_fadvise64_64, compat_sys_fadvise64_64, %o0, %o5)
|
||||
SIGN2(sys32_bdflush, sys_bdflush, %o0, %o1)
|
||||
SIGN1(sys32_mlockall, sys_mlockall, %o0)
|
||||
SIGN1(sys32_nfsservctl, compat_sys_nfsservctl, %o0)
|
||||
SIGN1(sys32_clock_nanosleep, compat_sys_clock_nanosleep, %o1)
|
||||
SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1)
|
||||
SIGN1(sys32_io_submit, compat_sys_io_submit, %o1)
|
||||
|
|
|
@ -67,7 +67,7 @@ sys_call_table:
|
|||
/*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
|
||||
/*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
|
||||
/*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
|
||||
/*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
|
||||
/*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_ni_syscall
|
||||
/*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
|
||||
/*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
|
||||
/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
|
||||
|
|
|
@ -145,7 +145,7 @@ sys_call_table:
|
|||
.word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
|
||||
/*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
|
||||
.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
|
||||
/*250*/ .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
|
||||
/*250*/ .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall
|
||||
.word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
|
||||
/*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
|
||||
.word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
|
||||
|
|
|
@ -672,7 +672,7 @@ ia32_sys_call_table:
|
|||
.quad sys32_vm86_warning /* vm86 */
|
||||
.quad quiet_ni_syscall /* query_module */
|
||||
.quad sys_poll
|
||||
.quad compat_sys_nfsservctl
|
||||
.quad quiet_ni_syscall /* old nfsservctl */
|
||||
.quad sys_setresgid16 /* 170 */
|
||||
.quad sys_getresgid16
|
||||
.quad sys_prctl
|
||||
|
|
|
@ -414,7 +414,7 @@ __SYSCALL(__NR_query_module, sys_ni_syscall)
|
|||
__SYSCALL(__NR_quotactl, sys_quotactl)
|
||||
|
||||
#define __NR_nfsservctl 180
|
||||
__SYSCALL(__NR_nfsservctl, sys_nfsservctl)
|
||||
__SYSCALL(__NR_nfsservctl, sys_ni_syscall)
|
||||
|
||||
/* reserved for LiS/STREAMS */
|
||||
#define __NR_getpmsg 181
|
||||
|
|
|
@ -207,7 +207,6 @@ static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_ri
|
|||
((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
|
||||
APIC_DM_INIT;
|
||||
uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
|
||||
mdelay(10);
|
||||
|
||||
val = (1UL << UVH_IPI_INT_SEND_SHFT) |
|
||||
(phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) |
|
||||
|
|
|
@ -149,7 +149,6 @@ struct set_mtrr_data {
|
|||
*/
|
||||
static int mtrr_rendezvous_handler(void *info)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
struct set_mtrr_data *data = info;
|
||||
|
||||
/*
|
||||
|
@ -171,7 +170,6 @@ static int mtrr_rendezvous_handler(void *info)
|
|||
} else if (mtrr_aps_delayed_init || !cpu_online(smp_processor_id())) {
|
||||
mtrr_if->set_all();
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include <asm/ftrace.h>
|
||||
#include <asm/irq_vectors.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/alternative-asm.h>
|
||||
|
||||
/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
|
||||
#include <linux/elf-em.h>
|
||||
|
@ -873,12 +874,7 @@ ENTRY(simd_coprocessor_error)
|
|||
661: pushl_cfi $do_general_protection
|
||||
662:
|
||||
.section .altinstructions,"a"
|
||||
.balign 4
|
||||
.long 661b
|
||||
.long 663f
|
||||
.word X86_FEATURE_XMM
|
||||
.byte 662b-661b
|
||||
.byte 664f-663f
|
||||
altinstruction_entry 661b, 663f, X86_FEATURE_XMM, 662b-661b, 664f-663f
|
||||
.previous
|
||||
.section .altinstr_replacement,"ax"
|
||||
663: pushl $do_simd_coprocessor_error
|
||||
|
|
|
@ -168,7 +168,7 @@ ENTRY(sys_call_table)
|
|||
.long ptregs_vm86
|
||||
.long sys_ni_syscall /* Old sys_query_module */
|
||||
.long sys_poll
|
||||
.long sys_nfsservctl
|
||||
.long sys_ni_syscall /* Old nfsservctl */
|
||||
.long sys_setresgid16 /* 170 */
|
||||
.long sys_getresgid16
|
||||
.long sys_prctl
|
||||
|
|
|
@ -689,7 +689,9 @@ static int __init sfi_parse_devs(struct sfi_table_header *table)
|
|||
irq_attr.trigger = 1;
|
||||
irq_attr.polarity = 1;
|
||||
io_apic_set_pci_routing(NULL, pentry->irq, &irq_attr);
|
||||
}
|
||||
} else
|
||||
pentry->irq = 0; /* No irq */
|
||||
|
||||
switch (pentry->type) {
|
||||
case SFI_DEV_TYPE_IPC:
|
||||
/* ID as IRQ is a hack that will go away */
|
||||
|
|
|
@ -161,13 +161,13 @@ restart:
|
|||
if (inbuf && inlen) {
|
||||
/* write data to EC */
|
||||
for (i = 0; i < inlen; i++) {
|
||||
pr_devel("olpc-ec: sending cmd arg 0x%x\n", inbuf[i]);
|
||||
outb(inbuf[i], 0x68);
|
||||
if (wait_on_ibf(0x6c, 0)) {
|
||||
printk(KERN_ERR "olpc-ec: timeout waiting for"
|
||||
" EC accept data!\n");
|
||||
goto err;
|
||||
}
|
||||
pr_devel("olpc-ec: sending cmd arg 0x%x\n", inbuf[i]);
|
||||
outb(inbuf[i], 0x68);
|
||||
}
|
||||
}
|
||||
if (outbuf && outlen) {
|
||||
|
|
|
@ -43,7 +43,7 @@ __kernel_vsyscall:
|
|||
.space 7,0x90
|
||||
|
||||
/* 14: System call restart point is here! (SYSENTER_RETURN-2) */
|
||||
jmp .Lenter_kernel
|
||||
int $0x80
|
||||
/* 16: System call normal return point is here! */
|
||||
VDSO32_SYSENTER_RETURN: /* Symbol used by sysenter.c via vdso32-syms.h */
|
||||
pop %ebp
|
||||
|
|
|
@ -455,7 +455,7 @@ __SYSCALL(203, sys_reboot, 3)
|
|||
#define __NR_quotactl 204
|
||||
__SYSCALL(204, sys_quotactl, 4)
|
||||
#define __NR_nfsservctl 205
|
||||
__SYSCALL(205, sys_nfsservctl, 3)
|
||||
__SYSCALL(205, sys_ni_syscall, 0)
|
||||
#define __NR__sysctl 206
|
||||
__SYSCALL(206, sys_sysctl, 1)
|
||||
#define __NR_bdflush 207
|
||||
|
|
|
@ -397,6 +397,7 @@ static int remove_nodes(struct device *dev,
|
|||
|
||||
static int release_nodes(struct device *dev, struct list_head *first,
|
||||
struct list_head *end, unsigned long flags)
|
||||
__releases(&dev->devres_lock)
|
||||
{
|
||||
LIST_HEAD(todo);
|
||||
int cnt;
|
||||
|
|
|
@ -376,7 +376,7 @@ int devtmpfs_mount(const char *mntdir)
|
|||
return err;
|
||||
}
|
||||
|
||||
static __initdata DECLARE_COMPLETION(setup_done);
|
||||
static DECLARE_COMPLETION(setup_done);
|
||||
|
||||
static int handle(const char *name, mode_t mode, struct device *dev)
|
||||
{
|
||||
|
|
|
@ -521,11 +521,6 @@ static int _request_firmware(const struct firmware **firmware_p,
|
|||
if (!firmware_p)
|
||||
return -EINVAL;
|
||||
|
||||
if (WARN_ON(usermodehelper_is_disabled())) {
|
||||
dev_err(device, "firmware: %s will not be loaded\n", name);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
*firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
|
||||
if (!firmware) {
|
||||
dev_err(device, "%s: kmalloc(struct firmware) failed\n",
|
||||
|
@ -539,6 +534,12 @@ static int _request_firmware(const struct firmware **firmware_p,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (WARN_ON(usermodehelper_is_disabled())) {
|
||||
dev_err(device, "firmware: %s will not be loaded\n", name);
|
||||
retval = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (uevent)
|
||||
dev_dbg(device, "firmware: requesting %s\n", name);
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ EXPORT_SYMBOL_GPL(platform_bus);
|
|||
|
||||
/**
|
||||
* arch_setup_pdev_archdata - Allow manipulation of archdata before its used
|
||||
* @dev: platform device
|
||||
* @pdev: platform device
|
||||
*
|
||||
* This is called before platform_device_add() such that any pdev_archdata may
|
||||
* be setup before the platform_notifier is called. So if a user needs to
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
struct pm_clk_data {
|
||||
struct list_head clock_list;
|
||||
struct mutex lock;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
enum pce_status {
|
||||
|
@ -73,9 +73,9 @@ int pm_clk_add(struct device *dev, const char *con_id)
|
|||
}
|
||||
}
|
||||
|
||||
mutex_lock(&pcd->lock);
|
||||
spin_lock_irq(&pcd->lock);
|
||||
list_add_tail(&ce->node, &pcd->clock_list);
|
||||
mutex_unlock(&pcd->lock);
|
||||
spin_unlock_irq(&pcd->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -83,8 +83,8 @@ int pm_clk_add(struct device *dev, const char *con_id)
|
|||
* __pm_clk_remove - Destroy PM clock entry.
|
||||
* @ce: PM clock entry to destroy.
|
||||
*
|
||||
* This routine must be called under the mutex protecting the PM list of clocks
|
||||
* corresponding the the @ce's device.
|
||||
* This routine must be called under the spinlock protecting the PM list of
|
||||
* clocks corresponding the the @ce's device.
|
||||
*/
|
||||
static void __pm_clk_remove(struct pm_clock_entry *ce)
|
||||
{
|
||||
|
@ -123,7 +123,7 @@ void pm_clk_remove(struct device *dev, const char *con_id)
|
|||
if (!pcd)
|
||||
return;
|
||||
|
||||
mutex_lock(&pcd->lock);
|
||||
spin_lock_irq(&pcd->lock);
|
||||
|
||||
list_for_each_entry(ce, &pcd->clock_list, node) {
|
||||
if (!con_id && !ce->con_id) {
|
||||
|
@ -137,7 +137,7 @@ void pm_clk_remove(struct device *dev, const char *con_id)
|
|||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&pcd->lock);
|
||||
spin_unlock_irq(&pcd->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,7 +158,7 @@ int pm_clk_init(struct device *dev)
|
|||
}
|
||||
|
||||
INIT_LIST_HEAD(&pcd->clock_list);
|
||||
mutex_init(&pcd->lock);
|
||||
spin_lock_init(&pcd->lock);
|
||||
dev->power.subsys_data = pcd;
|
||||
return 0;
|
||||
}
|
||||
|
@ -181,12 +181,12 @@ void pm_clk_destroy(struct device *dev)
|
|||
|
||||
dev->power.subsys_data = NULL;
|
||||
|
||||
mutex_lock(&pcd->lock);
|
||||
spin_lock_irq(&pcd->lock);
|
||||
|
||||
list_for_each_entry_safe_reverse(ce, c, &pcd->clock_list, node)
|
||||
__pm_clk_remove(ce);
|
||||
|
||||
mutex_unlock(&pcd->lock);
|
||||
spin_unlock_irq(&pcd->lock);
|
||||
|
||||
kfree(pcd);
|
||||
}
|
||||
|
@ -220,13 +220,14 @@ int pm_clk_suspend(struct device *dev)
|
|||
{
|
||||
struct pm_clk_data *pcd = __to_pcd(dev);
|
||||
struct pm_clock_entry *ce;
|
||||
unsigned long flags;
|
||||
|
||||
dev_dbg(dev, "%s()\n", __func__);
|
||||
|
||||
if (!pcd)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&pcd->lock);
|
||||
spin_lock_irqsave(&pcd->lock, flags);
|
||||
|
||||
list_for_each_entry_reverse(ce, &pcd->clock_list, node) {
|
||||
if (ce->status == PCE_STATUS_NONE)
|
||||
|
@ -238,7 +239,7 @@ int pm_clk_suspend(struct device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&pcd->lock);
|
||||
spin_unlock_irqrestore(&pcd->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -251,13 +252,14 @@ int pm_clk_resume(struct device *dev)
|
|||
{
|
||||
struct pm_clk_data *pcd = __to_pcd(dev);
|
||||
struct pm_clock_entry *ce;
|
||||
unsigned long flags;
|
||||
|
||||
dev_dbg(dev, "%s()\n", __func__);
|
||||
|
||||
if (!pcd)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&pcd->lock);
|
||||
spin_lock_irqsave(&pcd->lock, flags);
|
||||
|
||||
list_for_each_entry(ce, &pcd->clock_list, node) {
|
||||
if (ce->status == PCE_STATUS_NONE)
|
||||
|
@ -269,7 +271,7 @@ int pm_clk_resume(struct device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&pcd->lock);
|
||||
spin_unlock_irqrestore(&pcd->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -344,6 +346,7 @@ int pm_clk_suspend(struct device *dev)
|
|||
{
|
||||
struct pm_clk_data *pcd = __to_pcd(dev);
|
||||
struct pm_clock_entry *ce;
|
||||
unsigned long flags;
|
||||
|
||||
dev_dbg(dev, "%s()\n", __func__);
|
||||
|
||||
|
@ -351,12 +354,12 @@ int pm_clk_suspend(struct device *dev)
|
|||
if (!pcd || !dev->driver)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&pcd->lock);
|
||||
spin_lock_irqsave(&pcd->lock, flags);
|
||||
|
||||
list_for_each_entry_reverse(ce, &pcd->clock_list, node)
|
||||
clk_disable(ce->clk);
|
||||
|
||||
mutex_unlock(&pcd->lock);
|
||||
spin_unlock_irqrestore(&pcd->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -369,6 +372,7 @@ int pm_clk_resume(struct device *dev)
|
|||
{
|
||||
struct pm_clk_data *pcd = __to_pcd(dev);
|
||||
struct pm_clock_entry *ce;
|
||||
unsigned long flags;
|
||||
|
||||
dev_dbg(dev, "%s()\n", __func__);
|
||||
|
||||
|
@ -376,12 +380,12 @@ int pm_clk_resume(struct device *dev)
|
|||
if (!pcd || !dev->driver)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&pcd->lock);
|
||||
spin_lock_irqsave(&pcd->lock, flags);
|
||||
|
||||
list_for_each_entry(ce, &pcd->clock_list, node)
|
||||
clk_enable(ce->clk);
|
||||
|
||||
mutex_unlock(&pcd->lock);
|
||||
spin_unlock_irqrestore(&pcd->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -379,9 +379,8 @@ static int __init smd_pkt_init(void)
|
|||
for (i = 0; i < NUM_SMD_PKT_PORTS; ++i) {
|
||||
smd_pkt_devp[i] = kzalloc(sizeof(struct smd_pkt_dev),
|
||||
GFP_KERNEL);
|
||||
if (IS_ERR(smd_pkt_devp[i])) {
|
||||
r = PTR_ERR(smd_pkt_devp[i]);
|
||||
pr_err("kmalloc() failed %d\n", r);
|
||||
if (!smd_pkt_devp[i]) {
|
||||
pr_err("kmalloc() failed\n");
|
||||
goto clean_cdevs;
|
||||
}
|
||||
|
||||
|
|
|
@ -1198,6 +1198,10 @@ static int sbp2_remove(struct device *dev)
|
|||
{
|
||||
struct fw_unit *unit = fw_unit(dev);
|
||||
struct sbp2_target *tgt = dev_get_drvdata(&unit->device);
|
||||
struct sbp2_logical_unit *lu;
|
||||
|
||||
list_for_each_entry(lu, &tgt->lu_list, link)
|
||||
cancel_delayed_work_sync(&lu->work);
|
||||
|
||||
sbp2_target_put(tgt);
|
||||
return 0;
|
||||
|
|
|
@ -420,7 +420,7 @@ static efi_status_t gsmi_get_next_variable(unsigned long *name_size,
|
|||
|
||||
static efi_status_t gsmi_set_variable(efi_char16_t *name,
|
||||
efi_guid_t *vendor,
|
||||
unsigned long attr,
|
||||
u32 attr,
|
||||
unsigned long data_size,
|
||||
void *data)
|
||||
{
|
||||
|
|
|
@ -878,7 +878,7 @@ static void assert_panel_unlocked(struct drm_i915_private *dev_priv,
|
|||
int pp_reg, lvds_reg;
|
||||
u32 val;
|
||||
enum pipe panel_pipe = PIPE_A;
|
||||
bool locked = locked;
|
||||
bool locked = true;
|
||||
|
||||
if (HAS_PCH_SPLIT(dev_priv->dev)) {
|
||||
pp_reg = PCH_PP_CONTROL;
|
||||
|
@ -7238,8 +7238,6 @@ static void intel_setup_outputs(struct drm_device *dev)
|
|||
intel_encoder_clones(dev, encoder->clone_mask);
|
||||
}
|
||||
|
||||
intel_panel_setup_backlight(dev);
|
||||
|
||||
/* disable all the possible outputs/crtcs before entering KMS mode */
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
}
|
||||
|
|
|
@ -466,6 +466,16 @@ static bool radeon_connector_needs_extended_probe(struct radeon_device *dev,
|
|||
(supported_device == ATOM_DEVICE_DFP2_SUPPORT))
|
||||
return true;
|
||||
}
|
||||
/* TOSHIBA Satellite L300D with ATI Mobility Radeon x1100
|
||||
* (RS690M) sends data to i2c bus for a HDMI connector that
|
||||
* is not implemented */
|
||||
if ((dev->pdev->device == 0x791f) &&
|
||||
(dev->pdev->subsystem_vendor == 0x1179) &&
|
||||
(dev->pdev->subsystem_device == 0xff68)) {
|
||||
if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) &&
|
||||
(supported_device == ATOM_DEVICE_DFP2_SUPPORT))
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Default: no EDID header probe required for DDC probing */
|
||||
return false;
|
||||
|
|
|
@ -301,6 +301,8 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64
|
|||
mc->mc_vram_size = mc->aper_size;
|
||||
}
|
||||
mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
|
||||
if (radeon_vram_limit && radeon_vram_limit < mc->real_vram_size)
|
||||
mc->real_vram_size = radeon_vram_limit;
|
||||
dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n",
|
||||
mc->mc_vram_size >> 20, mc->vram_start,
|
||||
mc->vram_end, mc->real_vram_size >> 20);
|
||||
|
|
|
@ -40,10 +40,14 @@ void radeon_test_moves(struct radeon_device *rdev)
|
|||
size = 1024 * 1024;
|
||||
|
||||
/* Number of tests =
|
||||
* (Total GTT - IB pool - writeback page - ring buffer) / test size
|
||||
* (Total GTT - IB pool - writeback page - ring buffers) / test size
|
||||
*/
|
||||
n = ((u32)(rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE -
|
||||
rdev->cp.ring_size)) / size;
|
||||
n = rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - rdev->cp.ring_size;
|
||||
if (rdev->wb.wb_obj)
|
||||
n -= RADEON_GPU_PAGE_SIZE;
|
||||
if (rdev->ih.ring_obj)
|
||||
n -= rdev->ih.ring_size;
|
||||
n /= size;
|
||||
|
||||
gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL);
|
||||
if (!gtt_obj) {
|
||||
|
@ -132,9 +136,15 @@ void radeon_test_moves(struct radeon_device *rdev)
|
|||
gtt_start++, vram_start++) {
|
||||
if (*vram_start != gtt_start) {
|
||||
DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, "
|
||||
"expected 0x%p (GTT map 0x%p-0x%p)\n",
|
||||
i, *vram_start, gtt_start, gtt_map,
|
||||
gtt_end);
|
||||
"expected 0x%p (GTT/VRAM offset "
|
||||
"0x%16llx/0x%16llx)\n",
|
||||
i, *vram_start, gtt_start,
|
||||
(unsigned long long)
|
||||
(gtt_addr - rdev->mc.gtt_start +
|
||||
(void*)gtt_start - gtt_map),
|
||||
(unsigned long long)
|
||||
(vram_addr - rdev->mc.vram_start +
|
||||
(void*)gtt_start - gtt_map));
|
||||
radeon_bo_kunmap(vram_obj);
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
@ -175,9 +185,15 @@ void radeon_test_moves(struct radeon_device *rdev)
|
|||
gtt_start++, vram_start++) {
|
||||
if (*gtt_start != vram_start) {
|
||||
DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, "
|
||||
"expected 0x%p (VRAM map 0x%p-0x%p)\n",
|
||||
i, *gtt_start, vram_start, vram_map,
|
||||
vram_end);
|
||||
"expected 0x%p (VRAM/GTT offset "
|
||||
"0x%16llx/0x%16llx)\n",
|
||||
i, *gtt_start, vram_start,
|
||||
(unsigned long long)
|
||||
(vram_addr - rdev->mc.vram_start +
|
||||
(void*)vram_start - vram_map),
|
||||
(unsigned long long)
|
||||
(gtt_addr - rdev->mc.gtt_start +
|
||||
(void*)vram_start - vram_map));
|
||||
radeon_bo_kunmap(gtt_obj[i]);
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
|
|
@ -450,6 +450,29 @@ static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_
|
|||
return -EINVAL;
|
||||
mem->bus.base = rdev->mc.aper_base;
|
||||
mem->bus.is_iomem = true;
|
||||
#ifdef __alpha__
|
||||
/*
|
||||
* Alpha: use bus.addr to hold the ioremap() return,
|
||||
* so we can modify bus.base below.
|
||||
*/
|
||||
if (mem->placement & TTM_PL_FLAG_WC)
|
||||
mem->bus.addr =
|
||||
ioremap_wc(mem->bus.base + mem->bus.offset,
|
||||
mem->bus.size);
|
||||
else
|
||||
mem->bus.addr =
|
||||
ioremap_nocache(mem->bus.base + mem->bus.offset,
|
||||
mem->bus.size);
|
||||
|
||||
/*
|
||||
* Alpha: Use just the bus offset plus
|
||||
* the hose/domain memory base for bus.base.
|
||||
* It then can be used to build PTEs for VRAM
|
||||
* access, as done in ttm_bo_vm_fault().
|
||||
*/
|
||||
mem->bus.base = (mem->bus.base & 0x0ffffffffUL) +
|
||||
rdev->ddev->hose->dense_mem_base;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
|
|
@ -353,8 +353,10 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc)
|
|||
|
||||
ret = ttm_tt_set_user(bo->ttm, current,
|
||||
bo->buffer_start, bo->num_pages);
|
||||
if (unlikely(ret != 0))
|
||||
if (unlikely(ret != 0)) {
|
||||
ttm_tt_destroy(bo->ttm);
|
||||
bo->ttm = NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR TTM_PFX "Illegal buffer object type\n");
|
||||
|
@ -390,10 +392,12 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
|
|||
* Create and bind a ttm if required.
|
||||
*/
|
||||
|
||||
if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED) && (bo->ttm == NULL)) {
|
||||
if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) {
|
||||
if (bo->ttm == NULL) {
|
||||
ret = ttm_bo_add_ttm(bo, false);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement);
|
||||
if (ret)
|
||||
|
|
|
@ -635,13 +635,13 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ttm_bo_free_old_node(bo);
|
||||
if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
|
||||
(bo->ttm != NULL)) {
|
||||
ttm_tt_unbind(bo->ttm);
|
||||
ttm_tt_destroy(bo->ttm);
|
||||
bo->ttm = NULL;
|
||||
}
|
||||
ttm_bo_free_old_node(bo);
|
||||
} else {
|
||||
/**
|
||||
* This should help pipeline ordinary buffer moves.
|
||||
|
|
|
@ -589,6 +589,7 @@ config HID_WACOM_POWER_SUPPLY
|
|||
config HID_WIIMOTE
|
||||
tristate "Nintendo Wii Remote support"
|
||||
depends on BT_HIDP
|
||||
depends on LEDS_CLASS
|
||||
---help---
|
||||
Support for the Nintendo Wii Remote bluetooth device.
|
||||
|
||||
|
|
|
@ -444,6 +444,12 @@ static const struct hid_device_id apple_devices[] = {
|
|||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
|
||||
APPLE_RDESC_JIS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
|
||||
.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO),
|
||||
|
|
|
@ -1340,6 +1340,9 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
|||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
|
||||
|
|
|
@ -109,6 +109,9 @@
|
|||
#define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247
|
||||
#define USB_DEVICE_ID_APPLE_ALU_REVB_ANSI 0x024f
|
||||
#define USB_DEVICE_ID_APPLE_ALU_REVB_ISO 0x0250
|
||||
#define USB_DEVICE_ID_APPLE_ALU_REVB_JIS 0x0251
|
||||
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239
|
||||
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a
|
||||
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b
|
||||
|
@ -576,6 +579,9 @@
|
|||
#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
|
||||
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
|
||||
|
||||
#define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f
|
||||
#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002
|
||||
|
||||
#define USB_VENDOR_ID_SKYCABLE 0x1223
|
||||
#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07
|
||||
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
* any later version.
|
||||
*/
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include "hid-ids.h"
|
||||
|
@ -33,9 +33,9 @@ struct wiimote_state {
|
|||
};
|
||||
|
||||
struct wiimote_data {
|
||||
atomic_t ready;
|
||||
struct hid_device *hdev;
|
||||
struct input_dev *input;
|
||||
struct led_classdev *leds[4];
|
||||
|
||||
spinlock_t qlock;
|
||||
__u8 head;
|
||||
|
@ -53,8 +53,15 @@ struct wiimote_data {
|
|||
#define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \
|
||||
WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4)
|
||||
|
||||
/* return flag for led \num */
|
||||
#define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1))
|
||||
|
||||
enum wiiproto_reqs {
|
||||
WIIPROTO_REQ_NULL = 0x0,
|
||||
WIIPROTO_REQ_LED = 0x11,
|
||||
WIIPROTO_REQ_DRM = 0x12,
|
||||
WIIPROTO_REQ_STATUS = 0x20,
|
||||
WIIPROTO_REQ_RETURN = 0x22,
|
||||
WIIPROTO_REQ_DRM_K = 0x30,
|
||||
};
|
||||
|
||||
|
@ -87,9 +94,6 @@ static __u16 wiiproto_keymap[] = {
|
|||
BTN_MODE, /* WIIPROTO_KEY_HOME */
|
||||
};
|
||||
|
||||
#define dev_to_wii(pdev) hid_get_drvdata(container_of(pdev, struct hid_device, \
|
||||
dev))
|
||||
|
||||
static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
|
||||
size_t count)
|
||||
{
|
||||
|
@ -192,66 +196,96 @@ static void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
|
|||
wiimote_queue(wdata, cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
#define wiifs_led_show_set(num) \
|
||||
static ssize_t wiifs_led_show_##num(struct device *dev, \
|
||||
struct device_attribute *attr, char *buf) \
|
||||
{ \
|
||||
struct wiimote_data *wdata = dev_to_wii(dev); \
|
||||
unsigned long flags; \
|
||||
int state; \
|
||||
\
|
||||
if (!atomic_read(&wdata->ready)) \
|
||||
return -EBUSY; \
|
||||
\
|
||||
spin_lock_irqsave(&wdata->state.lock, flags); \
|
||||
state = !!(wdata->state.flags & WIIPROTO_FLAG_LED##num); \
|
||||
spin_unlock_irqrestore(&wdata->state.lock, flags); \
|
||||
\
|
||||
return sprintf(buf, "%d\n", state); \
|
||||
} \
|
||||
static ssize_t wiifs_led_set_##num(struct device *dev, \
|
||||
struct device_attribute *attr, const char *buf, size_t count) \
|
||||
{ \
|
||||
struct wiimote_data *wdata = dev_to_wii(dev); \
|
||||
int tmp = simple_strtoul(buf, NULL, 10); \
|
||||
unsigned long flags; \
|
||||
__u8 state; \
|
||||
\
|
||||
if (!atomic_read(&wdata->ready)) \
|
||||
return -EBUSY; \
|
||||
\
|
||||
spin_lock_irqsave(&wdata->state.lock, flags); \
|
||||
\
|
||||
state = wdata->state.flags; \
|
||||
\
|
||||
if (tmp) \
|
||||
wiiproto_req_leds(wdata, state | WIIPROTO_FLAG_LED##num);\
|
||||
else \
|
||||
wiiproto_req_leds(wdata, state & ~WIIPROTO_FLAG_LED##num);\
|
||||
\
|
||||
spin_unlock_irqrestore(&wdata->state.lock, flags); \
|
||||
\
|
||||
return count; \
|
||||
} \
|
||||
static DEVICE_ATTR(led##num, S_IRUGO | S_IWUSR, wiifs_led_show_##num, \
|
||||
wiifs_led_set_##num)
|
||||
/*
|
||||
* Check what peripherals of the wiimote are currently
|
||||
* active and select a proper DRM that supports all of
|
||||
* the requested data inputs.
|
||||
*/
|
||||
static __u8 select_drm(struct wiimote_data *wdata)
|
||||
{
|
||||
return WIIPROTO_REQ_DRM_K;
|
||||
}
|
||||
|
||||
wiifs_led_show_set(1);
|
||||
wiifs_led_show_set(2);
|
||||
wiifs_led_show_set(3);
|
||||
wiifs_led_show_set(4);
|
||||
static void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm)
|
||||
{
|
||||
__u8 cmd[3];
|
||||
|
||||
if (drm == WIIPROTO_REQ_NULL)
|
||||
drm = select_drm(wdata);
|
||||
|
||||
cmd[0] = WIIPROTO_REQ_DRM;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = drm;
|
||||
|
||||
wiimote_queue(wdata, cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static enum led_brightness wiimote_leds_get(struct led_classdev *led_dev)
|
||||
{
|
||||
struct wiimote_data *wdata;
|
||||
struct device *dev = led_dev->dev->parent;
|
||||
int i;
|
||||
unsigned long flags;
|
||||
bool value = false;
|
||||
|
||||
wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
if (wdata->leds[i] == led_dev) {
|
||||
spin_lock_irqsave(&wdata->state.lock, flags);
|
||||
value = wdata->state.flags & WIIPROTO_FLAG_LED(i + 1);
|
||||
spin_unlock_irqrestore(&wdata->state.lock, flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return value ? LED_FULL : LED_OFF;
|
||||
}
|
||||
|
||||
static void wiimote_leds_set(struct led_classdev *led_dev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
struct wiimote_data *wdata;
|
||||
struct device *dev = led_dev->dev->parent;
|
||||
int i;
|
||||
unsigned long flags;
|
||||
__u8 state, flag;
|
||||
|
||||
wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
if (wdata->leds[i] == led_dev) {
|
||||
flag = WIIPROTO_FLAG_LED(i + 1);
|
||||
spin_lock_irqsave(&wdata->state.lock, flags);
|
||||
state = wdata->state.flags;
|
||||
if (value == LED_OFF)
|
||||
wiiproto_req_leds(wdata, state & ~flag);
|
||||
else
|
||||
wiiproto_req_leds(wdata, state | flag);
|
||||
spin_unlock_irqrestore(&wdata->state.lock, flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int wiimote_input_event(struct input_dev *dev, unsigned int type,
|
||||
unsigned int code, int value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wiimote_input_open(struct input_dev *dev)
|
||||
{
|
||||
struct wiimote_data *wdata = input_get_drvdata(dev);
|
||||
|
||||
if (!atomic_read(&wdata->ready))
|
||||
return -EBUSY;
|
||||
/* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
|
||||
smp_rmb();
|
||||
return hid_hw_open(wdata->hdev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
static void wiimote_input_close(struct input_dev *dev)
|
||||
{
|
||||
struct wiimote_data *wdata = input_get_drvdata(dev);
|
||||
|
||||
hid_hw_close(wdata->hdev);
|
||||
}
|
||||
|
||||
static void handler_keys(struct wiimote_data *wdata, const __u8 *payload)
|
||||
|
@ -281,6 +315,26 @@ static void handler_keys(struct wiimote_data *wdata, const __u8 *payload)
|
|||
input_sync(wdata->input);
|
||||
}
|
||||
|
||||
static void handler_status(struct wiimote_data *wdata, const __u8 *payload)
|
||||
{
|
||||
handler_keys(wdata, payload);
|
||||
|
||||
/* on status reports the drm is reset so we need to resend the drm */
|
||||
wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
|
||||
}
|
||||
|
||||
static void handler_return(struct wiimote_data *wdata, const __u8 *payload)
|
||||
{
|
||||
__u8 err = payload[3];
|
||||
__u8 cmd = payload[2];
|
||||
|
||||
handler_keys(wdata, payload);
|
||||
|
||||
if (err)
|
||||
hid_warn(wdata->hdev, "Remote error %hhu on req %hhu\n", err,
|
||||
cmd);
|
||||
}
|
||||
|
||||
struct wiiproto_handler {
|
||||
__u8 id;
|
||||
size_t size;
|
||||
|
@ -288,6 +342,8 @@ struct wiiproto_handler {
|
|||
};
|
||||
|
||||
static struct wiiproto_handler handlers[] = {
|
||||
{ .id = WIIPROTO_REQ_STATUS, .size = 6, .func = handler_status },
|
||||
{ .id = WIIPROTO_REQ_RETURN, .size = 4, .func = handler_return },
|
||||
{ .id = WIIPROTO_REQ_DRM_K, .size = 2, .func = handler_keys },
|
||||
{ .id = 0 }
|
||||
};
|
||||
|
@ -300,11 +356,6 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
|
|||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
if (!atomic_read(&wdata->ready))
|
||||
return -EBUSY;
|
||||
/* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
|
||||
smp_rmb();
|
||||
|
||||
if (size < 1)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -321,6 +372,58 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void wiimote_leds_destroy(struct wiimote_data *wdata)
|
||||
{
|
||||
int i;
|
||||
struct led_classdev *led;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
if (wdata->leds[i]) {
|
||||
led = wdata->leds[i];
|
||||
wdata->leds[i] = NULL;
|
||||
led_classdev_unregister(led);
|
||||
kfree(led);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int wiimote_leds_create(struct wiimote_data *wdata)
|
||||
{
|
||||
int i, ret;
|
||||
struct device *dev = &wdata->hdev->dev;
|
||||
size_t namesz = strlen(dev_name(dev)) + 9;
|
||||
struct led_classdev *led;
|
||||
char *name;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL);
|
||||
if (!led) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
name = (void*)&led[1];
|
||||
snprintf(name, namesz, "%s:blue:p%d", dev_name(dev), i);
|
||||
led->name = name;
|
||||
led->brightness = 0;
|
||||
led->max_brightness = 1;
|
||||
led->brightness_get = wiimote_leds_get;
|
||||
led->brightness_set = wiimote_leds_set;
|
||||
|
||||
ret = led_classdev_register(dev, led);
|
||||
if (ret) {
|
||||
kfree(led);
|
||||
goto err;
|
||||
}
|
||||
wdata->leds[i] = led;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
wiimote_leds_destroy(wdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct wiimote_data *wiimote_create(struct hid_device *hdev)
|
||||
{
|
||||
struct wiimote_data *wdata;
|
||||
|
@ -341,6 +444,8 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
|
|||
|
||||
input_set_drvdata(wdata->input, wdata);
|
||||
wdata->input->event = wiimote_input_event;
|
||||
wdata->input->open = wiimote_input_open;
|
||||
wdata->input->close = wiimote_input_close;
|
||||
wdata->input->dev.parent = &wdata->hdev->dev;
|
||||
wdata->input->id.bustype = wdata->hdev->bus;
|
||||
wdata->input->id.vendor = wdata->hdev->vendor;
|
||||
|
@ -362,6 +467,12 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
|
|||
|
||||
static void wiimote_destroy(struct wiimote_data *wdata)
|
||||
{
|
||||
wiimote_leds_destroy(wdata);
|
||||
|
||||
input_unregister_device(wdata->input);
|
||||
cancel_work_sync(&wdata->worker);
|
||||
hid_hw_stop(wdata->hdev);
|
||||
|
||||
kfree(wdata);
|
||||
}
|
||||
|
||||
|
@ -377,19 +488,6 @@ static int wiimote_hid_probe(struct hid_device *hdev,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = device_create_file(&hdev->dev, &dev_attr_led1);
|
||||
if (ret)
|
||||
goto err;
|
||||
ret = device_create_file(&hdev->dev, &dev_attr_led2);
|
||||
if (ret)
|
||||
goto err;
|
||||
ret = device_create_file(&hdev->dev, &dev_attr_led3);
|
||||
if (ret)
|
||||
goto err;
|
||||
ret = device_create_file(&hdev->dev, &dev_attr_led4);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
hid_err(hdev, "HID parse failed\n");
|
||||
|
@ -408,9 +506,10 @@ static int wiimote_hid_probe(struct hid_device *hdev,
|
|||
goto err_stop;
|
||||
}
|
||||
|
||||
/* smp_wmb: Write wdata->xy first before wdata->ready is set to 1 */
|
||||
smp_wmb();
|
||||
atomic_set(&wdata->ready, 1);
|
||||
ret = wiimote_leds_create(wdata);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
||||
hid_info(hdev, "New device registered\n");
|
||||
|
||||
/* by default set led1 after device initialization */
|
||||
|
@ -420,15 +519,15 @@ static int wiimote_hid_probe(struct hid_device *hdev,
|
|||
|
||||
return 0;
|
||||
|
||||
err_free:
|
||||
wiimote_destroy(wdata);
|
||||
return ret;
|
||||
|
||||
err_stop:
|
||||
hid_hw_stop(hdev);
|
||||
err:
|
||||
input_free_device(wdata->input);
|
||||
device_remove_file(&hdev->dev, &dev_attr_led1);
|
||||
device_remove_file(&hdev->dev, &dev_attr_led2);
|
||||
device_remove_file(&hdev->dev, &dev_attr_led3);
|
||||
device_remove_file(&hdev->dev, &dev_attr_led4);
|
||||
wiimote_destroy(wdata);
|
||||
kfree(wdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -437,16 +536,6 @@ static void wiimote_hid_remove(struct hid_device *hdev)
|
|||
struct wiimote_data *wdata = hid_get_drvdata(hdev);
|
||||
|
||||
hid_info(hdev, "Device removed\n");
|
||||
|
||||
device_remove_file(&hdev->dev, &dev_attr_led1);
|
||||
device_remove_file(&hdev->dev, &dev_attr_led2);
|
||||
device_remove_file(&hdev->dev, &dev_attr_led3);
|
||||
device_remove_file(&hdev->dev, &dev_attr_led4);
|
||||
|
||||
hid_hw_stop(hdev);
|
||||
input_unregister_device(wdata->input);
|
||||
|
||||
cancel_work_sync(&wdata->worker);
|
||||
wiimote_destroy(wdata);
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ static const struct hid_blacklist {
|
|||
|
||||
{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
|
|
@ -114,7 +114,6 @@ struct i5k_amb_data {
|
|||
void __iomem *amb_mmio;
|
||||
struct i5k_device_attribute *attrs;
|
||||
unsigned int num_attrs;
|
||||
unsigned long chipset_id;
|
||||
};
|
||||
|
||||
static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
|
||||
|
@ -444,8 +443,6 @@ static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data,
|
|||
goto out;
|
||||
}
|
||||
|
||||
data->chipset_id = devid;
|
||||
|
||||
res = 0;
|
||||
out:
|
||||
pci_dev_put(pcidev);
|
||||
|
@ -478,23 +475,13 @@ out:
|
|||
return res;
|
||||
}
|
||||
|
||||
static unsigned long i5k_channel_pci_id(struct i5k_amb_data *data,
|
||||
unsigned long channel)
|
||||
{
|
||||
switch (data->chipset_id) {
|
||||
case PCI_DEVICE_ID_INTEL_5000_ERR:
|
||||
return PCI_DEVICE_ID_INTEL_5000_FBD0 + channel;
|
||||
case PCI_DEVICE_ID_INTEL_5400_ERR:
|
||||
return PCI_DEVICE_ID_INTEL_5400_FBD0 + channel;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long chipset_ids[] = {
|
||||
PCI_DEVICE_ID_INTEL_5000_ERR,
|
||||
PCI_DEVICE_ID_INTEL_5400_ERR,
|
||||
0
|
||||
static struct {
|
||||
unsigned long err;
|
||||
unsigned long fbd0;
|
||||
} chipset_ids[] __devinitdata = {
|
||||
{ PCI_DEVICE_ID_INTEL_5000_ERR, PCI_DEVICE_ID_INTEL_5000_FBD0 },
|
||||
{ PCI_DEVICE_ID_INTEL_5400_ERR, PCI_DEVICE_ID_INTEL_5400_FBD0 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
#ifdef MODULE
|
||||
|
@ -510,8 +497,7 @@ static int __devinit i5k_amb_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct i5k_amb_data *data;
|
||||
struct resource *reso;
|
||||
int i;
|
||||
int res = -ENODEV;
|
||||
int i, res;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
|
@ -520,22 +506,22 @@ static int __devinit i5k_amb_probe(struct platform_device *pdev)
|
|||
/* Figure out where the AMB registers live */
|
||||
i = 0;
|
||||
do {
|
||||
res = i5k_find_amb_registers(data, chipset_ids[i]);
|
||||
res = i5k_find_amb_registers(data, chipset_ids[i].err);
|
||||
if (res == 0)
|
||||
break;
|
||||
i++;
|
||||
} while (res && chipset_ids[i]);
|
||||
} while (chipset_ids[i].err);
|
||||
|
||||
if (res)
|
||||
goto err;
|
||||
|
||||
/* Copy the DIMM presence map for the first two channels */
|
||||
res = i5k_channel_probe(&data->amb_present[0],
|
||||
i5k_channel_pci_id(data, 0));
|
||||
res = i5k_channel_probe(&data->amb_present[0], chipset_ids[i].fbd0);
|
||||
if (res)
|
||||
goto err;
|
||||
|
||||
/* Copy the DIMM presence map for the optional second two channels */
|
||||
i5k_channel_probe(&data->amb_present[2],
|
||||
i5k_channel_pci_id(data, 1));
|
||||
i5k_channel_probe(&data->amb_present[2], chipset_ids[i].fbd0 + 1);
|
||||
|
||||
/* Set up resource regions */
|
||||
reso = request_mem_region(data->amb_base, data->amb_len, DRVNAME);
|
||||
|
|
|
@ -211,8 +211,7 @@ static int lookup_comp(struct ntc_data *data,
|
|||
if (data->comp[mid].ohm <= ohm) {
|
||||
*i_low = mid;
|
||||
*i_high = mid - 1;
|
||||
}
|
||||
if (data->comp[mid].ohm > ohm) {
|
||||
} else {
|
||||
*i_low = mid + 1;
|
||||
*i_high = mid;
|
||||
}
|
||||
|
|
|
@ -146,6 +146,7 @@ struct i2c_nmk_client {
|
|||
* @stop: stop condition
|
||||
* @xfer_complete: acknowledge completion for a I2C message
|
||||
* @result: controller propogated result
|
||||
* @regulator: pointer to i2c regulator
|
||||
* @busy: Busy doing transfer
|
||||
*/
|
||||
struct nmk_i2c_dev {
|
||||
|
@ -417,12 +418,12 @@ static int read_i2c(struct nmk_i2c_dev *dev)
|
|||
writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
|
||||
dev->virtbase + I2C_IMSCR);
|
||||
|
||||
timeout = wait_for_completion_interruptible_timeout(
|
||||
timeout = wait_for_completion_timeout(
|
||||
&dev->xfer_complete, dev->adap.timeout);
|
||||
|
||||
if (timeout < 0) {
|
||||
dev_err(&dev->pdev->dev,
|
||||
"wait_for_completion_interruptible_timeout"
|
||||
"wait_for_completion_timeout"
|
||||
"returned %d waiting for event\n", timeout);
|
||||
status = timeout;
|
||||
}
|
||||
|
@ -504,12 +505,12 @@ static int write_i2c(struct nmk_i2c_dev *dev)
|
|||
writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
|
||||
dev->virtbase + I2C_IMSCR);
|
||||
|
||||
timeout = wait_for_completion_interruptible_timeout(
|
||||
timeout = wait_for_completion_timeout(
|
||||
&dev->xfer_complete, dev->adap.timeout);
|
||||
|
||||
if (timeout < 0) {
|
||||
dev_err(&dev->pdev->dev,
|
||||
"wait_for_completion_interruptible_timeout"
|
||||
"wait_for_completion_timeout "
|
||||
"returned %d waiting for event\n", timeout);
|
||||
status = timeout;
|
||||
}
|
||||
|
|
|
@ -1139,41 +1139,12 @@ omap_i2c_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
static int omap_i2c_suspend(struct device *dev)
|
||||
{
|
||||
if (!pm_runtime_suspended(dev))
|
||||
if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend)
|
||||
dev->bus->pm->runtime_suspend(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_i2c_resume(struct device *dev)
|
||||
{
|
||||
if (!pm_runtime_suspended(dev))
|
||||
if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume)
|
||||
dev->bus->pm->runtime_resume(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dev_pm_ops omap_i2c_pm_ops = {
|
||||
.suspend = omap_i2c_suspend,
|
||||
.resume = omap_i2c_resume,
|
||||
};
|
||||
#define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops)
|
||||
#else
|
||||
#define OMAP_I2C_PM_OPS NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver omap_i2c_driver = {
|
||||
.probe = omap_i2c_probe,
|
||||
.remove = omap_i2c_remove,
|
||||
.driver = {
|
||||
.name = "omap_i2c",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = OMAP_I2C_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ struct analog_port {
|
|||
#include <linux/i8253.h>
|
||||
|
||||
#define GET_TIME(x) do { if (cpu_has_tsc) rdtscl(x); else x = get_time_pit(); } while (0)
|
||||
#define DELTA(x,y) (cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? CLOCK_TICK_RATE / HZ : 0)))
|
||||
#define DELTA(x,y) (cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? PIT_TICK_RATE / HZ : 0)))
|
||||
#define TIME_NAME (cpu_has_tsc?"TSC":"PIT")
|
||||
static unsigned int get_time_pit(void)
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
* flag.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/clk.h>
|
||||
|
|
|
@ -702,7 +702,7 @@ err_iounmap:
|
|||
err_free_mem_region:
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
err_free_mem:
|
||||
input_free_device(kbc->idev);
|
||||
input_free_device(input_dev);
|
||||
kfree(kbc);
|
||||
|
||||
return err;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* AD714X CapTouch Programmable Controller driver (I2C bus)
|
||||
*
|
||||
* Copyright 2009 Analog Devices Inc.
|
||||
* Copyright 2009-2011 Analog Devices Inc.
|
||||
*
|
||||
* Licensed under the GPL-2 or later.
|
||||
*/
|
||||
|
@ -27,54 +27,49 @@ static int ad714x_i2c_resume(struct device *dev)
|
|||
|
||||
static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume);
|
||||
|
||||
static int ad714x_i2c_write(struct device *dev, unsigned short reg,
|
||||
unsigned short data)
|
||||
static int ad714x_i2c_write(struct ad714x_chip *chip,
|
||||
unsigned short reg, unsigned short data)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
int ret = 0;
|
||||
u8 *_reg = (u8 *)®
|
||||
u8 *_data = (u8 *)&data;
|
||||
struct i2c_client *client = to_i2c_client(chip->dev);
|
||||
int error;
|
||||
|
||||
u8 tx[4] = {
|
||||
_reg[1],
|
||||
_reg[0],
|
||||
_data[1],
|
||||
_data[0]
|
||||
};
|
||||
chip->xfer_buf[0] = cpu_to_be16(reg);
|
||||
chip->xfer_buf[1] = cpu_to_be16(data);
|
||||
|
||||
ret = i2c_master_send(client, tx, 4);
|
||||
if (ret < 0)
|
||||
dev_err(&client->dev, "I2C write error\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ad714x_i2c_read(struct device *dev, unsigned short reg,
|
||||
unsigned short *data)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
int ret = 0;
|
||||
u8 *_reg = (u8 *)®
|
||||
u8 *_data = (u8 *)data;
|
||||
|
||||
u8 tx[2] = {
|
||||
_reg[1],
|
||||
_reg[0]
|
||||
};
|
||||
u8 rx[2];
|
||||
|
||||
ret = i2c_master_send(client, tx, 2);
|
||||
if (ret >= 0)
|
||||
ret = i2c_master_recv(client, rx, 2);
|
||||
|
||||
if (unlikely(ret < 0)) {
|
||||
dev_err(&client->dev, "I2C read error\n");
|
||||
} else {
|
||||
_data[0] = rx[1];
|
||||
_data[1] = rx[0];
|
||||
error = i2c_master_send(client, (u8 *)chip->xfer_buf,
|
||||
2 * sizeof(*chip->xfer_buf));
|
||||
if (unlikely(error < 0)) {
|
||||
dev_err(&client->dev, "I2C write error: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ad714x_i2c_read(struct ad714x_chip *chip,
|
||||
unsigned short reg, unsigned short *data, size_t len)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(chip->dev);
|
||||
int i;
|
||||
int error;
|
||||
|
||||
chip->xfer_buf[0] = cpu_to_be16(reg);
|
||||
|
||||
error = i2c_master_send(client, (u8 *)chip->xfer_buf,
|
||||
sizeof(*chip->xfer_buf));
|
||||
if (error >= 0)
|
||||
error = i2c_master_recv(client, (u8 *)chip->xfer_buf,
|
||||
len * sizeof(*chip->xfer_buf));
|
||||
|
||||
if (unlikely(error < 0)) {
|
||||
dev_err(&client->dev, "I2C read error: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
data[i] = be16_to_cpu(chip->xfer_buf[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit ad714x_i2c_probe(struct i2c_client *client,
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* AD714X CapTouch Programmable Controller driver (SPI bus)
|
||||
*
|
||||
* Copyright 2009 Analog Devices Inc.
|
||||
* Copyright 2009-2011 Analog Devices Inc.
|
||||
*
|
||||
* Licensed under the GPL-2 or later.
|
||||
*/
|
||||
|
||||
#include <linux/input.h> /* BUS_I2C */
|
||||
#include <linux/input.h> /* BUS_SPI */
|
||||
#include <linux/module.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/pm.h>
|
||||
|
@ -30,30 +30,68 @@ static int ad714x_spi_resume(struct device *dev)
|
|||
|
||||
static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume);
|
||||
|
||||
static int ad714x_spi_read(struct device *dev, unsigned short reg,
|
||||
unsigned short *data)
|
||||
static int ad714x_spi_read(struct ad714x_chip *chip,
|
||||
unsigned short reg, unsigned short *data, size_t len)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
unsigned short tx = AD714x_SPI_CMD_PREFIX | AD714x_SPI_READ | reg;
|
||||
struct spi_device *spi = to_spi_device(chip->dev);
|
||||
struct spi_message message;
|
||||
struct spi_transfer xfer[2];
|
||||
int i;
|
||||
int error;
|
||||
|
||||
return spi_write_then_read(spi, (u8 *)&tx, 2, (u8 *)data, 2);
|
||||
spi_message_init(&message);
|
||||
memset(xfer, 0, sizeof(xfer));
|
||||
|
||||
chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX |
|
||||
AD714x_SPI_READ | reg);
|
||||
xfer[0].tx_buf = &chip->xfer_buf[0];
|
||||
xfer[0].len = sizeof(chip->xfer_buf[0]);
|
||||
spi_message_add_tail(&xfer[0], &message);
|
||||
|
||||
xfer[1].rx_buf = &chip->xfer_buf[1];
|
||||
xfer[1].len = sizeof(chip->xfer_buf[1]) * len;
|
||||
spi_message_add_tail(&xfer[1], &message);
|
||||
|
||||
error = spi_sync(spi, &message);
|
||||
if (unlikely(error)) {
|
||||
dev_err(chip->dev, "SPI read error: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
data[i] = be16_to_cpu(chip->xfer_buf[i + 1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ad714x_spi_write(struct device *dev, unsigned short reg,
|
||||
unsigned short data)
|
||||
static int ad714x_spi_write(struct ad714x_chip *chip,
|
||||
unsigned short reg, unsigned short data)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
unsigned short tx[2] = {
|
||||
AD714x_SPI_CMD_PREFIX | reg,
|
||||
data
|
||||
};
|
||||
struct spi_device *spi = to_spi_device(chip->dev);
|
||||
int error;
|
||||
|
||||
return spi_write(spi, (u8 *)tx, 4);
|
||||
chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg);
|
||||
chip->xfer_buf[1] = cpu_to_be16(data);
|
||||
|
||||
error = spi_write(spi, (u8 *)chip->xfer_buf,
|
||||
2 * sizeof(*chip->xfer_buf));
|
||||
if (unlikely(error)) {
|
||||
dev_err(chip->dev, "SPI write error: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit ad714x_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
struct ad714x_chip *chip;
|
||||
int err;
|
||||
|
||||
spi->bits_per_word = 8;
|
||||
err = spi_setup(spi);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
chip = ad714x_probe(&spi->dev, BUS_SPI, spi->irq,
|
||||
ad714x_spi_read, ad714x_spi_write);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* AD714X CapTouch Programmable Controller driver supporting AD7142/3/7/8/7A
|
||||
*
|
||||
* Copyright 2009 Analog Devices Inc.
|
||||
* Copyright 2009-2011 Analog Devices Inc.
|
||||
*
|
||||
* Licensed under the GPL-2 or later.
|
||||
*/
|
||||
|
@ -59,7 +59,6 @@
|
|||
#define STAGE11_AMBIENT 0x27D
|
||||
|
||||
#define PER_STAGE_REG_NUM 36
|
||||
#define STAGE_NUM 12
|
||||
#define STAGE_CFGREG_NUM 8
|
||||
#define SYS_CFGREG_NUM 8
|
||||
|
||||
|
@ -124,27 +123,6 @@ struct ad714x_driver_data {
|
|||
* information to integrate all things which will be private data
|
||||
* of spi/i2c device
|
||||
*/
|
||||
struct ad714x_chip {
|
||||
unsigned short h_state;
|
||||
unsigned short l_state;
|
||||
unsigned short c_state;
|
||||
unsigned short adc_reg[STAGE_NUM];
|
||||
unsigned short amb_reg[STAGE_NUM];
|
||||
unsigned short sensor_val[STAGE_NUM];
|
||||
|
||||
struct ad714x_platform_data *hw;
|
||||
struct ad714x_driver_data *sw;
|
||||
|
||||
int irq;
|
||||
struct device *dev;
|
||||
ad714x_read_t read;
|
||||
ad714x_write_t write;
|
||||
|
||||
struct mutex mutex;
|
||||
|
||||
unsigned product;
|
||||
unsigned version;
|
||||
};
|
||||
|
||||
static void ad714x_use_com_int(struct ad714x_chip *ad714x,
|
||||
int start_stage, int end_stage)
|
||||
|
@ -154,13 +132,13 @@ static void ad714x_use_com_int(struct ad714x_chip *ad714x,
|
|||
|
||||
mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
|
||||
|
||||
ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data);
|
||||
ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
|
||||
data |= 1 << end_stage;
|
||||
ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data);
|
||||
ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
|
||||
|
||||
ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data);
|
||||
ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
|
||||
data &= ~mask;
|
||||
ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data);
|
||||
ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
|
||||
}
|
||||
|
||||
static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
|
||||
|
@ -171,13 +149,13 @@ static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
|
|||
|
||||
mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
|
||||
|
||||
ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data);
|
||||
ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
|
||||
data &= ~(1 << end_stage);
|
||||
ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data);
|
||||
ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
|
||||
|
||||
ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data);
|
||||
ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
|
||||
data |= mask;
|
||||
ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data);
|
||||
ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
|
||||
}
|
||||
|
||||
static int ad714x_cal_highest_stage(struct ad714x_chip *ad714x,
|
||||
|
@ -273,15 +251,16 @@ static void ad714x_slider_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
|
|||
struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
|
||||
int i;
|
||||
|
||||
for (i = hw->start_stage; i <= hw->end_stage; i++) {
|
||||
ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
|
||||
&ad714x->adc_reg[i]);
|
||||
ad714x->read(ad714x->dev,
|
||||
STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
|
||||
&ad714x->amb_reg[i]);
|
||||
ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
|
||||
&ad714x->adc_reg[hw->start_stage],
|
||||
hw->end_stage - hw->start_stage + 1);
|
||||
|
||||
ad714x->sensor_val[i] = abs(ad714x->adc_reg[i] -
|
||||
ad714x->amb_reg[i]);
|
||||
for (i = hw->start_stage; i <= hw->end_stage; i++) {
|
||||
ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
|
||||
&ad714x->amb_reg[i], 1);
|
||||
|
||||
ad714x->sensor_val[i] =
|
||||
abs(ad714x->adc_reg[i] - ad714x->amb_reg[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -444,15 +423,16 @@ static void ad714x_wheel_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
|
|||
struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
|
||||
int i;
|
||||
|
||||
ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
|
||||
&ad714x->adc_reg[hw->start_stage],
|
||||
hw->end_stage - hw->start_stage + 1);
|
||||
|
||||
for (i = hw->start_stage; i <= hw->end_stage; i++) {
|
||||
ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
|
||||
&ad714x->adc_reg[i]);
|
||||
ad714x->read(ad714x->dev,
|
||||
STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
|
||||
&ad714x->amb_reg[i]);
|
||||
ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
|
||||
&ad714x->amb_reg[i], 1);
|
||||
if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
|
||||
ad714x->sensor_val[i] = ad714x->adc_reg[i] -
|
||||
ad714x->amb_reg[i];
|
||||
ad714x->sensor_val[i] =
|
||||
ad714x->adc_reg[i] - ad714x->amb_reg[i];
|
||||
else
|
||||
ad714x->sensor_val[i] = 0;
|
||||
}
|
||||
|
@ -597,15 +577,16 @@ static void touchpad_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
|
|||
struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
|
||||
int i;
|
||||
|
||||
ad714x->read(ad714x, CDC_RESULT_S0 + hw->x_start_stage,
|
||||
&ad714x->adc_reg[hw->x_start_stage],
|
||||
hw->x_end_stage - hw->x_start_stage + 1);
|
||||
|
||||
for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) {
|
||||
ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
|
||||
&ad714x->adc_reg[i]);
|
||||
ad714x->read(ad714x->dev,
|
||||
STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
|
||||
&ad714x->amb_reg[i]);
|
||||
ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
|
||||
&ad714x->amb_reg[i], 1);
|
||||
if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
|
||||
ad714x->sensor_val[i] = ad714x->adc_reg[i] -
|
||||
ad714x->amb_reg[i];
|
||||
ad714x->sensor_val[i] =
|
||||
ad714x->adc_reg[i] - ad714x->amb_reg[i];
|
||||
else
|
||||
ad714x->sensor_val[i] = 0;
|
||||
}
|
||||
|
@ -891,7 +872,7 @@ static int ad714x_hw_detect(struct ad714x_chip *ad714x)
|
|||
{
|
||||
unsigned short data;
|
||||
|
||||
ad714x->read(ad714x->dev, AD714X_PARTID_REG, &data);
|
||||
ad714x->read(ad714x, AD714X_PARTID_REG, &data, 1);
|
||||
switch (data & 0xFFF0) {
|
||||
case AD7142_PARTID:
|
||||
ad714x->product = 0x7142;
|
||||
|
@ -940,23 +921,20 @@ static void ad714x_hw_init(struct ad714x_chip *ad714x)
|
|||
for (i = 0; i < STAGE_NUM; i++) {
|
||||
reg_base = AD714X_STAGECFG_REG + i * STAGE_CFGREG_NUM;
|
||||
for (j = 0; j < STAGE_CFGREG_NUM; j++)
|
||||
ad714x->write(ad714x->dev, reg_base + j,
|
||||
ad714x->write(ad714x, reg_base + j,
|
||||
ad714x->hw->stage_cfg_reg[i][j]);
|
||||
}
|
||||
|
||||
for (i = 0; i < SYS_CFGREG_NUM; i++)
|
||||
ad714x->write(ad714x->dev, AD714X_SYSCFG_REG + i,
|
||||
ad714x->write(ad714x, AD714X_SYSCFG_REG + i,
|
||||
ad714x->hw->sys_cfg_reg[i]);
|
||||
for (i = 0; i < SYS_CFGREG_NUM; i++)
|
||||
ad714x->read(ad714x->dev, AD714X_SYSCFG_REG + i,
|
||||
&data);
|
||||
ad714x->read(ad714x, AD714X_SYSCFG_REG + i, &data, 1);
|
||||
|
||||
ad714x->write(ad714x->dev, AD714X_STG_CAL_EN_REG, 0xFFF);
|
||||
ad714x->write(ad714x, AD714X_STG_CAL_EN_REG, 0xFFF);
|
||||
|
||||
/* clear all interrupts */
|
||||
ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data);
|
||||
ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data);
|
||||
ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data);
|
||||
ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
|
||||
}
|
||||
|
||||
static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
|
||||
|
@ -966,9 +944,7 @@ static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
|
|||
|
||||
mutex_lock(&ad714x->mutex);
|
||||
|
||||
ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &ad714x->l_state);
|
||||
ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &ad714x->h_state);
|
||||
ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &ad714x->c_state);
|
||||
ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
|
||||
|
||||
for (i = 0; i < ad714x->hw->button_num; i++)
|
||||
ad714x_button_state_machine(ad714x, i);
|
||||
|
@ -1245,7 +1221,7 @@ int ad714x_disable(struct ad714x_chip *ad714x)
|
|||
mutex_lock(&ad714x->mutex);
|
||||
|
||||
data = ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL] | 0x3;
|
||||
ad714x->write(ad714x->dev, AD714X_PWR_CTRL, data);
|
||||
ad714x->write(ad714x, AD714X_PWR_CTRL, data);
|
||||
|
||||
mutex_unlock(&ad714x->mutex);
|
||||
|
||||
|
@ -1255,24 +1231,20 @@ EXPORT_SYMBOL(ad714x_disable);
|
|||
|
||||
int ad714x_enable(struct ad714x_chip *ad714x)
|
||||
{
|
||||
unsigned short data;
|
||||
|
||||
dev_dbg(ad714x->dev, "%s enter\n", __func__);
|
||||
|
||||
mutex_lock(&ad714x->mutex);
|
||||
|
||||
/* resume to non-shutdown mode */
|
||||
|
||||
ad714x->write(ad714x->dev, AD714X_PWR_CTRL,
|
||||
ad714x->write(ad714x, AD714X_PWR_CTRL,
|
||||
ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL]);
|
||||
|
||||
/* make sure the interrupt output line is not low level after resume,
|
||||
* otherwise we will get no chance to enter falling-edge irq again
|
||||
*/
|
||||
|
||||
ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data);
|
||||
ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data);
|
||||
ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data);
|
||||
ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
|
||||
|
||||
mutex_unlock(&ad714x->mutex);
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue