forked from Minki/linux
Merge branches 'non_hwmod_compliant_fix_3.1rc', 'omap3_clock_fixes_3.1rc', 'omap4_clock_fixes_3.1rc', 'missing_2430_musb_adds_terminator_fix_3.1rc' and 'pwrdm_clkdm_fixes_3.1rc' into prcm-fixes-a-3.1rc
This commit is contained in:
commit
876355014c
@ -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
|
||||
@ -4971,7 +4971,7 @@ M: Paul Mackerras <paulus@samba.org>
|
||||
M: Ingo Molnar <mingo@elte.hu>
|
||||
M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
|
||||
S: Supported
|
||||
F: kernel/perf_event*.c
|
||||
F: kernel/events/*
|
||||
F: include/linux/perf_event.h
|
||||
F: arch/*/kernel/perf_event*.c
|
||||
F: arch/*/kernel/*/perf_event*.c
|
||||
@ -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/
|
||||
|
4
Makefile
4
Makefile
@ -1,8 +1,8 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc2
|
||||
NAME = Wet Seal
|
||||
EXTRAVERSION = -rc4
|
||||
NAME = "Divemaster Edition"
|
||||
|
||||
# *DOCUMENTATION*
|
||||
# To see a list of typical targets execute "make help"
|
||||
|
@ -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,9 +634,10 @@ 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;
|
||||
if (put_user(w, (unsigned int __user *)buffer))
|
||||
return -EFAULT;
|
||||
w = (current_thread_info()->flags >> ALPHA_UAC_SHIFT) &
|
||||
UAC_BITMASK;
|
||||
if (put_user(w, (unsigned int __user *)buffer))
|
||||
return -EFAULT;
|
||||
return 1;
|
||||
|
||||
case GSI_PROC_TYPE:
|
||||
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -3078,6 +3078,7 @@ static struct clk gpt12_fck = {
|
||||
.name = "gpt12_fck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &secure_32k_fck,
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
@ -3085,6 +3086,7 @@ static struct clk wdt1_fck = {
|
||||
.name = "wdt1_fck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &secure_32k_fck,
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
|
@ -3376,6 +3376,8 @@ int __init omap4xxx_clk_init(void)
|
||||
} else if (cpu_is_omap446x()) {
|
||||
cpu_mask = RATE_IN_4460;
|
||||
cpu_clkflg = CK_446X;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
clk_init(&omap2_clk_functions);
|
||||
|
@ -747,6 +747,7 @@ int clkdm_wakeup(struct clockdomain *clkdm)
|
||||
spin_lock_irqsave(&clkdm->lock, flags);
|
||||
clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
|
||||
ret = arch_clkdm->clkdm_wakeup(clkdm);
|
||||
ret |= pwrdm_state_switch(clkdm->pwrdm.ptr);
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
@ -818,6 +819,7 @@ void clkdm_deny_idle(struct clockdomain *clkdm)
|
||||
spin_lock_irqsave(&clkdm->lock, flags);
|
||||
clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
|
||||
arch_clkdm->clkdm_deny_idle(clkdm);
|
||||
pwrdm_state_switch(clkdm->pwrdm.ptr);
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
}
|
||||
|
||||
|
@ -192,6 +192,7 @@ static struct omap_hwmod_addr_space omap2430_usbhsotg_addrs[] = {
|
||||
.pa_end = OMAP243X_HS_BASE + SZ_4K - 1,
|
||||
.flags = ADDR_TYPE_RT
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
/* l4_core ->usbhsotg interface */
|
||||
|
@ -130,7 +130,6 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
|
||||
} else {
|
||||
hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
|
||||
clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
|
||||
pwrdm_wait_transition(pwrdm);
|
||||
sleep_switch = FORCEWAKEUP_SWITCH;
|
||||
}
|
||||
}
|
||||
@ -156,7 +155,6 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
|
||||
return ret;
|
||||
}
|
||||
|
||||
pwrdm_wait_transition(pwrdm);
|
||||
pwrdm_state_switch(pwrdm);
|
||||
err:
|
||||
return ret;
|
||||
|
@ -195,28 +195,35 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
|
||||
|
||||
/**
|
||||
* pwrdm_init - set up the powerdomain layer
|
||||
* @pwrdm_list: array of struct powerdomain pointers to register
|
||||
* @pwrdms: array of struct powerdomain pointers to register
|
||||
* @custom_funcs: func pointers for arch specific implementations
|
||||
*
|
||||
* Loop through the array of powerdomains @pwrdm_list, registering all
|
||||
* that are available on the current CPU. If pwrdm_list is supplied
|
||||
* and not null, all of the referenced powerdomains will be
|
||||
* registered. No return value. XXX pwrdm_list is not really a
|
||||
* "list"; it is an array. Rename appropriately.
|
||||
* Loop through the array of powerdomains @pwrdms, registering all
|
||||
* that are available on the current CPU. Also, program all
|
||||
* powerdomain target state as ON; this is to prevent domains from
|
||||
* hitting low power states (if bootloader has target states set to
|
||||
* something other than ON) and potentially even losing context while
|
||||
* PM is not fully initialized. The PM late init code can then program
|
||||
* the desired target state for all the power domains. No return
|
||||
* value.
|
||||
*/
|
||||
void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs)
|
||||
void pwrdm_init(struct powerdomain **pwrdms, struct pwrdm_ops *custom_funcs)
|
||||
{
|
||||
struct powerdomain **p = NULL;
|
||||
struct powerdomain *temp_p;
|
||||
|
||||
if (!custom_funcs)
|
||||
WARN(1, "powerdomain: No custom pwrdm functions registered\n");
|
||||
else
|
||||
arch_pwrdm = custom_funcs;
|
||||
|
||||
if (pwrdm_list) {
|
||||
for (p = pwrdm_list; *p; p++)
|
||||
if (pwrdms) {
|
||||
for (p = pwrdms; *p; p++)
|
||||
_pwrdm_register(*p);
|
||||
}
|
||||
|
||||
list_for_each_entry(temp_p, &pwrdm_list, node)
|
||||
pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1412,6 +1412,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)
|
||||
|
@ -1588,6 +1588,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
|
||||
|
9
arch/cris/include/asm/serial.h
Normal file
9
arch/cris/include/asm/serial.h
Normal file
@ -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));
|
||||
|
||||
err |= copy_in_user((u32 __user *)sf,
|
||||
(u32 __user *)(regs->u_regs[UREG_FP]),
|
||||
sizeof(struct reg_window32));
|
||||
|
||||
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));
|
||||
|
||||
err |= copy_in_user((u32 __user *)sf,
|
||||
(u32 __user *)(regs->u_regs[UREG_FP]),
|
||||
sizeof(struct reg_window32));
|
||||
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));
|
||||
err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
|
||||
sizeof(struct reg_window32));
|
||||
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);
|
||||
|
||||
err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
|
||||
sizeof(struct reg_window32));
|
||||
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);
|
||||
|
||||
if (invalid_frame_pointer (sf, sigframe_size))
|
||||
get_sigframe(ka, regs, sf_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));
|
||||
|
||||
err |= copy_in_user((u64 __user *)sf,
|
||||
(u64 __user *)(regs->u_regs[UREG_FP]+STACK_BIAS),
|
||||
sizeof(struct reg_window));
|
||||
if (!wsaved) {
|
||||
err |= copy_in_user((u64 __user *)sf,
|
||||
(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 {
|
||||
|
9
arch/sparc/kernel/sigutil.h
Normal file
9
arch/sparc/kernel/sigutil.h
Normal file
@ -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 */
|
120
arch/sparc/kernel/sigutil_32.c
Normal file
120
arch/sparc/kernel/sigutil_32.c
Normal file
@ -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;
|
||||
|
||||
}
|
93
arch/sparc/kernel/sigutil_64.c
Normal file
93
arch/sparc/kernel/sigutil_64.c
Normal file
@ -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
|
||||
|
@ -39,7 +39,7 @@ typedef struct xpaddr {
|
||||
((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE))
|
||||
|
||||
extern unsigned long *machine_to_phys_mapping;
|
||||
extern unsigned int machine_to_phys_order;
|
||||
extern unsigned long machine_to_phys_nr;
|
||||
|
||||
extern unsigned long get_phys_to_machine(unsigned long pfn);
|
||||
extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
|
||||
@ -87,7 +87,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
|
||||
if (xen_feature(XENFEAT_auto_translated_physmap))
|
||||
return mfn;
|
||||
|
||||
if (unlikely((mfn >> machine_to_phys_order) != 0)) {
|
||||
if (unlikely(mfn >= machine_to_phys_nr)) {
|
||||
pfn = ~0;
|
||||
goto try_override;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -15,7 +15,7 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \
|
||||
grant-table.o suspend.o platform-pci-unplug.o \
|
||||
p2m.o
|
||||
|
||||
obj-$(CONFIG_FTRACE) += trace.o
|
||||
obj-$(CONFIG_EVENT_TRACING) += trace.o
|
||||
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
|
||||
|
@ -77,8 +77,8 @@ EXPORT_SYMBOL_GPL(xen_domain_type);
|
||||
|
||||
unsigned long *machine_to_phys_mapping = (void *)MACH2PHYS_VIRT_START;
|
||||
EXPORT_SYMBOL(machine_to_phys_mapping);
|
||||
unsigned int machine_to_phys_order;
|
||||
EXPORT_SYMBOL(machine_to_phys_order);
|
||||
unsigned long machine_to_phys_nr;
|
||||
EXPORT_SYMBOL(machine_to_phys_nr);
|
||||
|
||||
struct start_info *xen_start_info;
|
||||
EXPORT_SYMBOL_GPL(xen_start_info);
|
||||
|
@ -1713,15 +1713,19 @@ static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
|
||||
void __init xen_setup_machphys_mapping(void)
|
||||
{
|
||||
struct xen_machphys_mapping mapping;
|
||||
unsigned long machine_to_phys_nr_ents;
|
||||
|
||||
if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) {
|
||||
machine_to_phys_mapping = (unsigned long *)mapping.v_start;
|
||||
machine_to_phys_nr_ents = mapping.max_mfn + 1;
|
||||
machine_to_phys_nr = mapping.max_mfn + 1;
|
||||
} else {
|
||||
machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
|
||||
machine_to_phys_nr = MACH2PHYS_NR_ENTRIES;
|
||||
}
|
||||
machine_to_phys_order = fls(machine_to_phys_nr_ents - 1);
|
||||
#ifdef CONFIG_X86_32
|
||||
if ((machine_to_phys_mapping + machine_to_phys_nr)
|
||||
< machine_to_phys_mapping)
|
||||
machine_to_phys_nr = (unsigned long *)NULL
|
||||
- machine_to_phys_mapping;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
|
@ -521,8 +521,6 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus)
|
||||
native_smp_prepare_cpus(max_cpus);
|
||||
WARN_ON(xen_smp_intr_init(0));
|
||||
|
||||
if (!xen_have_vector_callback)
|
||||
return;
|
||||
xen_init_lock_cpu(0);
|
||||
xen_init_spinlocks();
|
||||
}
|
||||
@ -546,6 +544,8 @@ static void xen_hvm_cpu_die(unsigned int cpu)
|
||||
|
||||
void __init xen_hvm_smp_init(void)
|
||||
{
|
||||
if (!xen_have_vector_callback)
|
||||
return;
|
||||
smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus;
|
||||
smp_ops.smp_send_reschedule = xen_smp_send_reschedule;
|
||||
smp_ops.cpu_up = xen_hvm_cpu_up;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -455,15 +455,20 @@ static struct device_attribute fw_device_attributes[] = {
|
||||
static int read_rom(struct fw_device *device,
|
||||
int generation, int index, u32 *data)
|
||||
{
|
||||
int rcode;
|
||||
u64 offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4;
|
||||
int i, rcode;
|
||||
|
||||
/* device->node_id, accessed below, must not be older than generation */
|
||||
smp_rmb();
|
||||
|
||||
rcode = fw_run_transaction(device->card, TCODE_READ_QUADLET_REQUEST,
|
||||
device->node_id, generation, device->max_speed,
|
||||
(CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4,
|
||||
data, 4);
|
||||
for (i = 10; i < 100; i += 10) {
|
||||
rcode = fw_run_transaction(device->card,
|
||||
TCODE_READ_QUADLET_REQUEST, device->node_id,
|
||||
generation, device->max_speed, offset, data, 4);
|
||||
if (rcode != RCODE_BUSY)
|
||||
break;
|
||||
msleep(i);
|
||||
}
|
||||
be32_to_cpus(data);
|
||||
|
||||
return rcode;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -375,6 +375,7 @@
|
||||
# define MI_FLUSH_ENABLE (1 << 11)
|
||||
|
||||
#define GFX_MODE 0x02520
|
||||
#define GFX_MODE_GEN7 0x0229c
|
||||
#define GFX_RUN_LIST_ENABLE (1<<15)
|
||||
#define GFX_TLB_INVALIDATE_ALWAYS (1<<13)
|
||||
#define GFX_SURFACE_FAULT_ENABLE (1<<12)
|
||||
@ -382,6 +383,9 @@
|
||||
#define GFX_PSMI_GRANULARITY (1<<10)
|
||||
#define GFX_PPGTT_ENABLE (1<<9)
|
||||
|
||||
#define GFX_MODE_ENABLE(bit) (((bit) << 16) | (bit))
|
||||
#define GFX_MODE_DISABLE(bit) (((bit) << 16) | (0))
|
||||
|
||||
#define SCPD0 0x0209c /* 915+ only */
|
||||
#define IER 0x020a0
|
||||
#define IIR 0x020a4
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -290,6 +290,10 @@ static int init_render_ring(struct intel_ring_buffer *ring)
|
||||
if (IS_GEN6(dev) || IS_GEN7(dev))
|
||||
mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE;
|
||||
I915_WRITE(MI_MODE, mode);
|
||||
if (IS_GEN7(dev))
|
||||
I915_WRITE(GFX_MODE_GEN7,
|
||||
GFX_MODE_DISABLE(GFX_TLB_INVALIDATE_ALWAYS) |
|
||||
GFX_MODE_ENABLE(GFX_REPLAY_MODE));
|
||||
}
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 6) {
|
||||
|
@ -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)) {
|
||||
ret = ttm_bo_add_ttm(bo, false);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
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)
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user