Merge branch 'zImage_DTB_append' of git://git.linaro.org/people/nico/linux into devel-stable

This commit is contained in:
Russell King 2011-09-15 00:02:28 +01:00
commit 1db3706b05
352 changed files with 3471 additions and 1866 deletions

View File

@ -1,13 +1,21 @@
00-INDEX 00-INDEX
- this file - this file
3c359.txt
- information on the 3Com TokenLink Velocity XL (3c5359) driver.
3c505.txt 3c505.txt
- information on the 3Com EtherLink Plus (3c505) driver. - information on the 3Com EtherLink Plus (3c505) driver.
3c509.txt
- information on the 3Com Etherlink III Series Ethernet cards.
6pack.txt 6pack.txt
- info on the 6pack protocol, an alternative to KISS for AX.25 - info on the 6pack protocol, an alternative to KISS for AX.25
DLINK.txt DLINK.txt
- info on the D-Link DE-600/DE-620 parallel port pocket adapters - info on the D-Link DE-600/DE-620 parallel port pocket adapters
PLIP.txt PLIP.txt
- PLIP: The Parallel Line Internet Protocol device driver - 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 README.sb1000
- info on General Instrument/NextLevel SURFboard1000 cable modem. - info on General Instrument/NextLevel SURFboard1000 cable modem.
alias.txt alias.txt
@ -20,8 +28,12 @@ atm.txt
- info on where to get ATM programs and support for Linux. - info on where to get ATM programs and support for Linux.
ax25.txt ax25.txt
- info on using AX.25 and NET/ROM code for Linux - 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 baycom.txt
- info on the driver for Baycom style amateur radio modems - info on the driver for Baycom style amateur radio modems
bonding.txt
- Linux Ethernet Bonding Driver HOWTO: link aggregation in Linux.
bridge.txt bridge.txt
- where to get user space programs for ethernet bridging with Linux. - where to get user space programs for ethernet bridging with Linux.
can.txt can.txt
@ -34,32 +46,60 @@ cxacru.txt
- Conexant AccessRunner USB ADSL Modem - Conexant AccessRunner USB ADSL Modem
cxacru-cf.py cxacru-cf.py
- Conexant AccessRunner USB ADSL Modem configuration file parser - 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 de4x5.txt
- the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver - the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver
decnet.txt decnet.txt
- info on using the DECnet networking layer in Linux. - info on using the DECnet networking layer in Linux.
depca.txt depca.txt
- the Digital DEPCA/EtherWORKS DE1?? and DE2?? LANCE Ethernet driver - 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 dmfe.txt
- info on the Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver. - 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 e100.txt
- info on Intel's EtherExpress PRO/100 line of 10/100 boards - info on Intel's EtherExpress PRO/100 line of 10/100 boards
e1000.txt e1000.txt
- info on Intel's E1000 line of gigabit ethernet boards - info on Intel's E1000 line of gigabit ethernet boards
e1000e.txt
- README for the Intel Gigabit Ethernet Driver (e1000e).
eql.txt eql.txt
- serial IP load balancing - serial IP load balancing
ewrk3.txt ewrk3.txt
- the Digital EtherWORKS 3 DE203/4/5 Ethernet driver - the Digital EtherWORKS 3 DE203/4/5 Ethernet driver
fib_trie.txt
- Level Compressed Trie (LC-trie) notes: a structure for routing.
filter.txt filter.txt
- Linux Socket Filtering - Linux Socket Filtering
fore200e.txt fore200e.txt
- FORE Systems PCA-200E/SBA-200E ATM NIC driver info. - FORE Systems PCA-200E/SBA-200E ATM NIC driver info.
framerelay.txt framerelay.txt
- info on using Frame Relay/Data Link Connection Identifier (DLCI). - 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 generic_netlink.txt
- info on Generic Netlink - info on Generic Netlink
gianfar.txt
- Gianfar Ethernet Driver.
ieee802154.txt ieee802154.txt
- Linux IEEE 802.15.4 implementation, API and drivers - 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 ip-sysctl.txt
- /proc/sys/net/ipv4/* variables - /proc/sys/net/ipv4/* variables
ip_dynaddr.txt ip_dynaddr.txt
@ -68,41 +108,117 @@ ipddp.txt
- AppleTalk-IP Decapsulation and AppleTalk-IP Encapsulation - AppleTalk-IP Decapsulation and AppleTalk-IP Encapsulation
iphase.txt iphase.txt
- Interphase PCI ATM (i)Chip IA Linux driver info. - 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 irda.txt
- where to get IrDA (infrared) utilities and info for Linux. - 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 lapb-module.txt
- programming information of the LAPB module. - programming information of the LAPB module.
ltpc.txt ltpc.txt
- the Apple or Farallon LocalTalk PC card driver - the Apple or Farallon LocalTalk PC card driver
mac80211-injection.txt
- HOWTO use packet injection with mac80211
multicast.txt multicast.txt
- Behaviour of cards under Multicast - 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 netdevices.txt
- info on network device driver functions exported to the kernel. - 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 olympic.txt
- IBM PCI Pit/Pit-Phy/Olympic Token Ring driver info. - 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 policy-routing.txt
- IP policy-based routing - 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 ray_cs.txt
- Raylink Wireless LAN card driver info. - 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 skfp.txt
- SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info. - SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
smc9.txt smc9.txt
- the driver for SMC's 9000 series of Ethernet cards - the driver for SMC's 9000 series of Ethernet cards
smctr.txt smctr.txt
- SMC TokenCard TokenRing Linux driver info. - 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 tcp.txt
- short blurb on how TCP output takes place. - short blurb on how TCP output takes place.
tcp-thin.txt
- kernel tuning options for low rate 'thin' TCP streams.
tlan.txt tlan.txt
- ThunderLAN (Compaq Netelligent 10/100, Olicom OC-2xxx) driver info. - ThunderLAN (Compaq Netelligent 10/100, Olicom OC-2xxx) driver info.
tms380tr.txt tms380tr.txt
- SysKonnect Token Ring ISA/PCI adapter driver info. - SysKonnect Token Ring ISA/PCI adapter driver info.
tproxy.txt
- Transparent proxy support user guide.
tuntap.txt tuntap.txt
- TUN/TAP device driver, allowing user space Rx/Tx of packets. - TUN/TAP device driver, allowing user space Rx/Tx of packets.
udplite.txt
- UDP-Lite protocol (RFC 3828) introduction.
vortex.txt vortex.txt
- info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) Ethernet cards. - info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) Ethernet cards.
vxge.txt
- README for the Neterion X3100 PCIe Server Adapter.
x25.txt x25.txt
- general info on X.25 development. - general info on X.25 development.
x25-iface.txt x25-iface.txt
- description of the X.25 Packet Layer to LAPB device interface. - 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 z8530drv.txt
- info about Linux driver for Z8530 based HDLC cards for AX.25 - info about Linux driver for Z8530 based HDLC cards for AX.25

View File

@ -992,7 +992,7 @@ bindv6only - BOOLEAN
TRUE: disable IPv4-mapped address feature TRUE: disable IPv4-mapped address feature
FALSE: enable IPv4-mapped address feature FALSE: enable IPv4-mapped address feature
Default: FALSE (as specified in RFC2553bis) Default: FALSE (as specified in RFC3493)
IPv6 Fragmentation: IPv6 Fragmentation:

View File

@ -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 configure. In the bnx2x driver, for instance, this parameter is called
num_queues. A typical RSS configuration would be to have one receive queue 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 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 The indirection table of an RSS device, which resolves a queue by masked
hash, is usually programmed by the driver at initialization. The 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 interrupt processing forms a bottleneck. Spreading load between CPUs
decreases queue length. For low latency networking, the optimal setting 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 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 NIC maximum, if lower). The most efficient high-rate configuration
with each additional queue, the most efficient high-rate configuration
is likely the one with the smallest number of receive queues where no is likely the one with the smallest number of receive queues where no
CPU that processes receive interrupts reaches 100% utilization. Per-cpu receive queue overflows due to a saturated CPU, because in default
load can be observed using the mpstat utility. 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 RPS: Receive Packet Steering
@ -145,7 +152,7 @@ the bitmap.
== Suggested Configuration == Suggested Configuration
For a single queue device, a typical RPS configuration would be to set 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 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 the system. At high interrupt rate, it might be wise to exclude the
interrupting CPU from the map since that already performs much work. 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 receive queue is mapped to each CPU, then RPS is probably redundant
and unnecessary. If there are fewer hardware queues than CPUs, then 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 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 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). corresponding socket structure for the flow (e.g. a TCP connection).
This transmit queue is used for subsequent packets sent on the flow to 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 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 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 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 there are no outstanding packets in the flow, so the transmit queue can

View File

@ -431,8 +431,7 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
void pm_runtime_irq_safe(struct device *dev); void pm_runtime_irq_safe(struct device *dev);
- set the power.irq_safe flag for the device, causing the runtime-PM - 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 callbacks to be invoked with interrupts off
with interrupts disabled
void pm_runtime_mark_last_busy(struct device *dev); void pm_runtime_mark_last_busy(struct device *dev);
- set the power.last_busy field to the current time - set the power.last_busy field to the current time

View File

@ -1883,7 +1883,7 @@ S: Maintained
F: drivers/connector/ F: drivers/connector/
CONTROL GROUPS (CGROUPS) CONTROL GROUPS (CGROUPS)
M: Paul Menage <menage@google.com> M: Paul Menage <paul@paulmenage.org>
M: Li Zefan <lizf@cn.fujitsu.com> M: Li Zefan <lizf@cn.fujitsu.com>
L: containers@lists.linux-foundation.org L: containers@lists.linux-foundation.org
S: Maintained S: Maintained
@ -1932,7 +1932,7 @@ S: Maintained
F: tools/power/cpupower F: tools/power/cpupower
CPUSETS CPUSETS
M: Paul Menage <menage@google.com> M: Paul Menage <paul@paulmenage.org>
W: http://www.bullopensource.org/cpuset/ W: http://www.bullopensource.org/cpuset/
W: http://oss.sgi.com/projects/cpusets/ W: http://oss.sgi.com/projects/cpusets/
S: Supported S: Supported
@ -5532,6 +5532,7 @@ F: include/media/*7146*
SAMSUNG AUDIO (ASoC) DRIVERS SAMSUNG AUDIO (ASoC) DRIVERS
M: Jassi Brar <jassisinghbrar@gmail.com> M: Jassi Brar <jassisinghbrar@gmail.com>
M: Sangbeom Kim <sbkim73@samsung.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers) L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Supported S: Supported
F: sound/soc/samsung F: sound/soc/samsung
@ -7087,7 +7088,7 @@ S: Supported
F: drivers/mmc/host/vub300.c F: drivers/mmc/host/vub300.c
W1 DALLAS'S 1-WIRE BUS W1 DALLAS'S 1-WIRE BUS
M: Evgeniy Polyakov <johnpol@2ka.mipt.ru> M: Evgeniy Polyakov <zbr@ioremap.net>
S: Maintained S: Maintained
F: Documentation/w1/ F: Documentation/w1/
F: drivers/w1/ F: drivers/w1/

View File

@ -1,7 +1,7 @@
VERSION = 3 VERSION = 3
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -rc3 EXTRAVERSION = -rc4
NAME = "Divemaster Edition" NAME = "Divemaster Edition"
# *DOCUMENTATION* # *DOCUMENTATION*

View File

@ -27,13 +27,4 @@
#define UAC_NOFIX 2 #define UAC_NOFIX 2
#define UAC_SIGBUS 4 #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 */ #endif /* __ASM_ALPHA_SYSINFO_H */

View File

@ -74,9 +74,9 @@ register struct thread_info *__current_thread_info __asm__("$8");
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_POLLING_NRFLAG 8 /* poll_idle is polling NEED_RESCHED */ #define TIF_POLLING_NRFLAG 8 /* poll_idle is polling NEED_RESCHED */
#define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */ #define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */
#define TIF_UAC_NOPRINT 10 /* see sysinfo.h */ #define TIF_UAC_NOPRINT 10 /* ! Preserve sequence of following */
#define TIF_UAC_NOFIX 11 #define TIF_UAC_NOFIX 11 /* ! flags as they match */
#define TIF_UAC_SIGBUS 12 #define TIF_UAC_SIGBUS 12 /* ! userspace part of 'osf_sysinfo' */
#define TIF_MEMDIE 13 /* is terminating due to OOM killer */ #define TIF_MEMDIE 13 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 14 /* restore signal mask in do_signal */ #define TIF_RESTORE_SIGMASK 14 /* restore signal mask in do_signal */
#define TIF_FREEZE 16 /* is freezing for suspend */ #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 \ #define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \
| _TIF_SYSCALL_TRACE) | _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 | \ #define ALPHA_UAC_MASK (1 << TIF_UAC_NOPRINT | 1 << TIF_UAC_NOFIX | \
1 << TIF_UAC_SIGBUS) 1 << TIF_UAC_SIGBUS)

View File

@ -42,6 +42,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/sysinfo.h> #include <asm/sysinfo.h>
#include <asm/thread_info.h>
#include <asm/hwrpb.h> #include <asm/hwrpb.h>
#include <asm/processor.h> #include <asm/processor.h>
@ -633,9 +634,10 @@ SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer,
case GSI_UACPROC: case GSI_UACPROC:
if (nbytes < sizeof(unsigned int)) if (nbytes < sizeof(unsigned int))
return -EINVAL; return -EINVAL;
w = (current_thread_info()->flags >> UAC_SHIFT) & UAC_BITMASK; w = (current_thread_info()->flags >> ALPHA_UAC_SHIFT) &
if (put_user(w, (unsigned int __user *)buffer)) UAC_BITMASK;
return -EFAULT; if (put_user(w, (unsigned int __user *)buffer))
return -EFAULT;
return 1; return 1;
case GSI_PROC_TYPE: case GSI_PROC_TYPE:
@ -756,8 +758,8 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer,
case SSIN_UACPROC: case SSIN_UACPROC:
again: again:
old = current_thread_info()->flags; old = current_thread_info()->flags;
new = old & ~(UAC_BITMASK << UAC_SHIFT); new = old & ~(UAC_BITMASK << ALPHA_UAC_SHIFT);
new = new | (w & UAC_BITMASK) << UAC_SHIFT; new = new | (w & UAC_BITMASK) << ALPHA_UAC_SHIFT;
if (cmpxchg(&current_thread_info()->flags, if (cmpxchg(&current_thread_info()->flags,
old, new) != old) old, new) != old)
goto again; goto again;

View File

@ -360,7 +360,7 @@ sys_call_table:
.quad sys_newuname .quad sys_newuname
.quad sys_nanosleep /* 340 */ .quad sys_nanosleep /* 340 */
.quad sys_mremap .quad sys_mremap
.quad sys_nfsservctl .quad sys_ni_syscall /* old nfsservctl */
.quad sys_setresuid .quad sys_setresuid
.quad sys_getresuid .quad sys_getresuid
.quad sys_pciconfig_read /* 345 */ .quad sys_pciconfig_read /* 345 */

View File

@ -1781,6 +1781,38 @@ config ZBOOT_ROM_SH_MOBILE_SDHI
endchoice endchoice
config ARM_APPENDED_DTB
bool "Use appended device tree blob to zImage (EXPERIMENTAL)"
depends on OF && !ZBOOT_ROM && EXPERIMENTAL
help
With this option, the boot code will look for a device tree binary
(DTB) appended to zImage
(e.g. cat zImage <filename>.dtb > zImage_w_dtb).
This is meant as a backward compatibility convenience for those
systems with a bootloader that can't be upgraded to accommodate
the documented boot protocol using a device tree.
Beware that there is very little in terms of protection against
this option being confused by leftover garbage in memory that might
look like a DTB header after a reboot if no actual DTB is appended
to zImage. Do not leave this option active in a production kernel
if you don't intend to always append a DTB. Proper passing of the
location into r2 of a bootloader provided DTB is always preferable
to this option.
config ARM_ATAG_DTB_COMPAT
bool "Supplement the appended DTB with traditional ATAG information"
depends on ARM_APPENDED_DTB
help
Some old bootloaders can't be updated to a DTB capable one, yet
they provide ATAGs with memory configuration, the ramdisk address,
the kernel cmdline string, etc. Such information is dynamically
provided by the bootloader and can't always be stored in a static
DTB. To allow a device tree enabled kernel to be used with such
bootloaders, this option allows zImage to extract the information
from the ATAG list and store it at run time into the appended DTB.
config CMDLINE config CMDLINE
string "Default kernel command string" string "Default kernel command string"
default "" default ""

View File

@ -5,3 +5,12 @@ piggy.lzo
piggy.lzma piggy.lzma
vmlinux vmlinux
vmlinux.lds vmlinux.lds
# borrowed libfdt files
fdt.c
fdt.h
fdt_ro.c
fdt_rw.c
fdt_wip.c
libfdt.h
libfdt_internal.h

View File

@ -26,6 +26,10 @@ HEAD = head.o
OBJS += misc.o decompress.o OBJS += misc.o decompress.o
FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
# string library code (-Os is enforced to keep it much smaller)
OBJS += string.o
CFLAGS_string.o := -Os
# #
# Architecture dependencies # Architecture dependencies
# #
@ -89,21 +93,41 @@ suffix_$(CONFIG_KERNEL_GZIP) = gzip
suffix_$(CONFIG_KERNEL_LZO) = lzo suffix_$(CONFIG_KERNEL_LZO) = lzo
suffix_$(CONFIG_KERNEL_LZMA) = lzma suffix_$(CONFIG_KERNEL_LZMA) = lzma
# Borrowed libfdt files for the ATAG compatibility mode
libfdt := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c
libfdt_hdrs := fdt.h libfdt.h libfdt_internal.h
libfdt_objs := $(addsuffix .o, $(basename $(libfdt)))
$(addprefix $(obj)/,$(libfdt) $(libfdt_hdrs)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/%
$(call cmd,shipped)
$(addprefix $(obj)/,$(libfdt_objs) atags_to_fdt.o): \
$(addprefix $(obj)/,$(libfdt_hdrs))
ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
OBJS += $(libfdt_objs) atags_to_fdt.o
endif
targets := vmlinux vmlinux.lds \ targets := vmlinux vmlinux.lds \
piggy.$(suffix_y) piggy.$(suffix_y).o \ piggy.$(suffix_y) piggy.$(suffix_y).o \
font.o font.c head.o misc.o $(OBJS) lib1funcs.o lib1funcs.S font.o font.c head.o misc.o $(OBJS)
# Make sure files are removed during clean # Make sure files are removed during clean
extra-y += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S extra-y += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S $(libfdt) $(libfdt_hdrs)
ifeq ($(CONFIG_FUNCTION_TRACER),y) ifeq ($(CONFIG_FUNCTION_TRACER),y)
ORIG_CFLAGS := $(KBUILD_CFLAGS) ORIG_CFLAGS := $(KBUILD_CFLAGS)
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
endif endif
ccflags-y := -fpic -fno-builtin ccflags-y := -fpic -fno-builtin -I$(obj)
asflags-y := -Wa,-march=all asflags-y := -Wa,-march=all
# Supply kernel BSS size to the decompressor via a linker symbol.
KBSS_SZ = $(shell size $(obj)/../../../../vmlinux | awk 'END{print $$3}')
LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
# Supply ZRELADDR to the decompressor via a linker symbol. # Supply ZRELADDR to the decompressor via a linker symbol.
ifneq ($(CONFIG_AUTO_ZRELADDR),y) ifneq ($(CONFIG_AUTO_ZRELADDR),y)
LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR) LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
@ -123,7 +147,7 @@ LDFLAGS_vmlinux += -T
# For __aeabi_uidivmod # For __aeabi_uidivmod
lib1funcs = $(obj)/lib1funcs.o lib1funcs = $(obj)/lib1funcs.o
$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
$(call cmd,shipped) $(call cmd,shipped)
# We need to prevent any GOTOFF relocs being used with references # We need to prevent any GOTOFF relocs being used with references

View File

@ -0,0 +1,97 @@
#include <asm/setup.h>
#include <libfdt.h>
static int node_offset(void *fdt, const char *node_path)
{
int offset = fdt_path_offset(fdt, node_path);
if (offset == -FDT_ERR_NOTFOUND)
offset = fdt_add_subnode(fdt, 0, node_path);
return offset;
}
static int setprop(void *fdt, const char *node_path, const char *property,
uint32_t *val_array, int size)
{
int offset = node_offset(fdt, node_path);
if (offset < 0)
return offset;
return fdt_setprop(fdt, offset, property, val_array, size);
}
static int setprop_string(void *fdt, const char *node_path,
const char *property, const char *string)
{
int offset = node_offset(fdt, node_path);
if (offset < 0)
return offset;
return fdt_setprop_string(fdt, offset, property, string);
}
static int setprop_cell(void *fdt, const char *node_path,
const char *property, uint32_t val)
{
int offset = node_offset(fdt, node_path);
if (offset < 0)
return offset;
return fdt_setprop_cell(fdt, offset, property, val);
}
/*
* Convert and fold provided ATAGs into the provided FDT.
*
* REturn values:
* = 0 -> pretend success
* = 1 -> bad ATAG (may retry with another possible ATAG pointer)
* < 0 -> error from libfdt
*/
int atags_to_fdt(void *atag_list, void *fdt, int total_space)
{
struct tag *atag = atag_list;
uint32_t mem_reg_property[2 * NR_BANKS];
int memcount = 0;
int ret;
/* make sure we've got an aligned pointer */
if ((u32)atag_list & 0x3)
return 1;
/* if we get a DTB here we're done already */
if (*(u32 *)atag_list == fdt32_to_cpu(FDT_MAGIC))
return 0;
/* validate the ATAG */
if (atag->hdr.tag != ATAG_CORE ||
(atag->hdr.size != tag_size(tag_core) &&
atag->hdr.size != 2))
return 1;
/* let's give it all the room it could need */
ret = fdt_open_into(fdt, fdt, total_space);
if (ret < 0)
return ret;
for_each_tag(atag, atag_list) {
if (atag->hdr.tag == ATAG_CMDLINE) {
setprop_string(fdt, "/chosen", "bootargs",
atag->u.cmdline.cmdline);
} else if (atag->hdr.tag == ATAG_MEM) {
if (memcount >= sizeof(mem_reg_property)/4)
continue;
mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start);
mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size);
} else if (atag->hdr.tag == ATAG_INITRD2) {
uint32_t initrd_start, initrd_size;
initrd_start = atag->u.initrd.start;
initrd_size = atag->u.initrd.size;
setprop_cell(fdt, "/chosen", "linux,initrd-start",
initrd_start);
setprop_cell(fdt, "/chosen", "linux,initrd-end",
initrd_start + initrd_size);
}
}
if (memcount)
setprop(fdt, "/memory", "reg", mem_reg_property, 4*memcount);
return fdt_pack(fdt);
}

View File

@ -216,6 +216,103 @@ restart: adr r0, LC0
mov r10, r6 mov r10, r6
#endif #endif
mov r5, #0 @ init dtb size to 0
#ifdef CONFIG_ARM_APPENDED_DTB
/*
* r0 = delta
* r2 = BSS start
* r3 = BSS end
* r4 = final kernel address
* r5 = appended dtb size (still unknown)
* r6 = _edata
* r7 = architecture ID
* r8 = atags/device tree pointer
* r9 = size of decompressed image
* r10 = end of this image, including bss/stack/malloc space if non XIP
* r11 = GOT start
* r12 = GOT end
* sp = stack pointer
*
* if there are device trees (dtb) appended to zImage, advance r10 so that the
* dtb data will get relocated along with the kernel if necessary.
*/
ldr lr, [r6, #0]
#ifndef __ARMEB__
ldr r1, =0xedfe0dd0 @ sig is 0xd00dfeed big endian
#else
ldr r1, =0xd00dfeed
#endif
cmp lr, r1
bne dtb_check_done @ not found
#ifdef CONFIG_ARM_ATAG_DTB_COMPAT
/*
* OK... Let's do some funky business here.
* If we do have a DTB appended to zImage, and we do have
* an ATAG list around, we want the later to be translated
* and folded into the former here. To be on the safe side,
* let's temporarily move the stack away into the malloc
* area. No GOT fixup has occurred yet, but none of the
* code we're about to call uses any global variable.
*/
add sp, sp, #0x10000
stmfd sp!, {r0-r3, ip, lr}
mov r0, r8
mov r1, r6
sub r2, sp, r6
bl atags_to_fdt
/*
* If returned value is 1, there is no ATAG at the location
* pointed by r8. Try the typical 0x100 offset from start
* of RAM and hope for the best.
*/
cmp r0, #1
sub r0, r4, #(TEXT_OFFSET - 0x100)
mov r1, r6
sub r2, sp, r6
blne atags_to_fdt
ldmfd sp!, {r0-r3, ip, lr}
sub sp, sp, #0x10000
#endif
mov r8, r6 @ use the appended device tree
/*
* Make sure that the DTB doesn't end up in the final
* kernel's .bss area. To do so, we adjust the decompressed
* kernel size to compensate if that .bss size is larger
* than the relocated code.
*/
ldr r5, =_kernel_bss_size
adr r1, wont_overwrite
sub r1, r6, r1
subs r1, r5, r1
addhi r9, r9, r1
/* Get the dtb's size */
ldr r5, [r6, #4]
#ifndef __ARMEB__
/* convert r5 (dtb size) to little endian */
eor r1, r5, r5, ror #16
bic r1, r1, #0x00ff0000
mov r5, r5, ror #8
eor r5, r5, r1, lsr #8
#endif
/* preserve 64-bit alignment */
add r5, r5, #7
bic r5, r5, #7
/* relocate some pointers past the appended dtb */
add r6, r6, r5
add r10, r10, r5
add sp, sp, r5
dtb_check_done:
#endif
/* /*
* Check to see if we will overwrite ourselves. * Check to see if we will overwrite ourselves.
* r4 = final kernel address * r4 = final kernel address
@ -223,15 +320,14 @@ restart: adr r0, LC0
* r10 = end of this image, including bss/stack/malloc space if non XIP * r10 = end of this image, including bss/stack/malloc space if non XIP
* We basically want: * We basically want:
* r4 - 16k page directory >= r10 -> OK * r4 - 16k page directory >= r10 -> OK
* r4 + image length <= current position (pc) -> OK * r4 + image length <= address of wont_overwrite -> OK
*/ */
add r10, r10, #16384 add r10, r10, #16384
cmp r4, r10 cmp r4, r10
bhs wont_overwrite bhs wont_overwrite
add r10, r4, r9 add r10, r4, r9
ARM( cmp r10, pc ) adr r9, wont_overwrite
THUMB( mov lr, pc ) cmp r10, r9
THUMB( cmp r10, lr )
bls wont_overwrite bls wont_overwrite
/* /*
@ -285,14 +381,16 @@ wont_overwrite:
* r2 = BSS start * r2 = BSS start
* r3 = BSS end * r3 = BSS end
* r4 = kernel execution address * r4 = kernel execution address
* r5 = appended dtb size (0 if not present)
* r7 = architecture ID * r7 = architecture ID
* r8 = atags pointer * r8 = atags pointer
* r11 = GOT start * r11 = GOT start
* r12 = GOT end * r12 = GOT end
* sp = stack pointer * sp = stack pointer
*/ */
teq r0, #0 orrs r1, r0, r5
beq not_relocated beq not_relocated
add r11, r11, r0 add r11, r11, r0
add r12, r12, r0 add r12, r12, r0
@ -307,12 +405,21 @@ wont_overwrite:
/* /*
* Relocate all entries in the GOT table. * Relocate all entries in the GOT table.
* Bump bss entries to _edata + dtb size
*/ */
1: ldr r1, [r11, #0] @ relocate entries in the GOT 1: ldr r1, [r11, #0] @ relocate entries in the GOT
add r1, r1, r0 @ table. This fixes up the add r1, r1, r0 @ This fixes up C references
str r1, [r11], #4 @ C references. cmp r1, r2 @ if entry >= bss_start &&
cmphs r3, r1 @ bss_end > entry
addhi r1, r1, r5 @ entry += dtb size
str r1, [r11], #4 @ next entry
cmp r11, r12 cmp r11, r12
blo 1b blo 1b
/* bump our bss pointers too */
add r2, r2, r5
add r3, r3, r5
#else #else
/* /*

View File

@ -0,0 +1,15 @@
#ifndef _ARM_LIBFDT_ENV_H
#define _ARM_LIBFDT_ENV_H
#include <linux/types.h>
#include <linux/string.h>
#include <asm/byteorder.h>
#define fdt16_to_cpu(x) be16_to_cpu(x)
#define cpu_to_fdt16(x) cpu_to_be16(x)
#define fdt32_to_cpu(x) be32_to_cpu(x)
#define cpu_to_fdt32(x) cpu_to_be32(x)
#define fdt64_to_cpu(x) be64_to_cpu(x)
#define cpu_to_fdt64(x) cpu_to_be64(x)
#endif

View File

@ -18,14 +18,9 @@
unsigned int __machine_arch_type; unsigned int __machine_arch_type;
#define _LINUX_STRING_H_
#include <linux/compiler.h> /* for inline */ #include <linux/compiler.h> /* for inline */
#include <linux/types.h> /* for size_t */ #include <linux/types.h>
#include <linux/stddef.h> /* for NULL */
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/string.h>
static void putstr(const char *ptr); static void putstr(const char *ptr);
extern void error(char *x); extern void error(char *x);
@ -101,41 +96,6 @@ static void putstr(const char *ptr)
flush(); flush();
} }
void *memcpy(void *__dest, __const void *__src, size_t __n)
{
int i = 0;
unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
for (i = __n >> 3; i > 0; i--) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (__n & 1 << 2) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (__n & 1 << 1) {
*d++ = *s++;
*d++ = *s++;
}
if (__n & 1)
*d++ = *s++;
return __dest;
}
/* /*
* gzip declarations * gzip declarations
*/ */

View File

@ -0,0 +1,127 @@
/*
* arch/arm/boot/compressed/string.c
*
* Small subset of simple string routines
*/
#include <linux/string.h>
void *memcpy(void *__dest, __const void *__src, size_t __n)
{
int i = 0;
unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
for (i = __n >> 3; i > 0; i--) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (__n & 1 << 2) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (__n & 1 << 1) {
*d++ = *s++;
*d++ = *s++;
}
if (__n & 1)
*d++ = *s++;
return __dest;
}
void *memmove(void *__dest, __const void *__src, size_t count)
{
unsigned char *d = __dest;
const unsigned char *s = __src;
if (__dest == __src)
return __dest;
if (__dest < __src)
return memcpy(__dest, __src, count);
while (count--)
d[count] = s[count];
return __dest;
}
size_t strlen(const char *s)
{
const char *sc = s;
while (*sc != '\0')
sc++;
return sc - s;
}
int memcmp(const void *cs, const void *ct, size_t count)
{
const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
int res = 0;
while (su1 < end) {
res = *su1++ - *su2++;
if (res)
break;
}
return res;
}
int strcmp(const char *cs, const char *ct)
{
unsigned char c1, c2;
int res = 0;
do {
c1 = *cs++;
c2 = *ct++;
res = c1 - c2;
if (res)
break;
} while (c1);
return res;
}
void *memchr(const void *s, int c, size_t count)
{
const unsigned char *p = s;
while (count--)
if ((unsigned char)c == *p++)
return (void *)(p - 1);
return NULL;
}
char *strchr(const char *s, int c)
{
while (*s != (char)c)
if (*s++ == '\0')
return NULL;
return (char *)s;
}
#undef memset
void *memset(void *s, int c, size_t count)
{
char *xs = s;
while (count--)
*xs++ = c;
return s;
}
void __memzero(void *s, size_t count)
{
memset(s, 0, count);
}

View File

@ -51,6 +51,10 @@ SECTIONS
_got_start = .; _got_start = .;
.got : { *(.got) } .got : { *(.got) }
_got_end = .; _got_end = .;
/* ensure the zImage file size is always a multiple of 64 bits */
/* (without a dummy byte, ld just ignores the empty section) */
.pad : { BYTE(0); . = ALIGN(8); }
_edata = .; _edata = .;
. = BSS_START; . = BSS_START;

View File

@ -178,7 +178,7 @@
CALL(sys_ni_syscall) /* vm86 */ CALL(sys_ni_syscall) /* vm86 */
CALL(sys_ni_syscall) /* was sys_query_module */ CALL(sys_ni_syscall) /* was sys_query_module */
CALL(sys_poll) CALL(sys_poll)
CALL(sys_nfsservctl) CALL(sys_ni_syscall) /* was nfsservctl */
/* 170 */ CALL(sys_setresgid16) /* 170 */ CALL(sys_setresgid16)
CALL(sys_getresgid16) CALL(sys_getresgid16)
CALL(sys_prctl) CALL(sys_prctl)

View File

@ -1415,6 +1415,7 @@ static void __init ap4evb_init(void)
fsi_init_pm_clock(); fsi_init_pm_clock();
sh7372_pm_init(); sh7372_pm_init();
pm_clk_add(&fsi_device.dev, "spu2"); pm_clk_add(&fsi_device.dev, "spu2");
pm_clk_add(&lcdc1_device.dev, "hdmi");
} }
static void __init ap4evb_timer_init(void) static void __init ap4evb_timer_init(void)

View File

@ -1591,6 +1591,7 @@ static void __init mackerel_init(void)
hdmi_init_pm_clock(); hdmi_init_pm_clock();
sh7372_pm_init(); sh7372_pm_init();
pm_clk_add(&fsi_device.dev, "spu2"); pm_clk_add(&fsi_device.dev, "spu2");
pm_clk_add(&hdmi_lcdc_device.dev, "hdmi");
} }
static void __init mackerel_timer_init(void) static void __init mackerel_timer_init(void)

View File

@ -655,6 +655,8 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */ CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ 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("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]), CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]), CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),

View File

@ -622,7 +622,8 @@ static struct dev_pm_domain omap_device_pm_domain = {
SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume, SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
_od_runtime_idle) _od_runtime_idle)
USE_PLATFORM_PM_SLEEP_OPS 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,
} }
}; };

View File

@ -158,7 +158,7 @@ sys_call_table:
.long sys_sched_rr_get_interval .long sys_sched_rr_get_interval
.long sys_nanosleep .long sys_nanosleep
.long sys_poll .long sys_poll
.long sys_nfsservctl /* 145 */ .long sys_ni_syscall /* 145 was nfsservctl */
.long sys_setresgid .long sys_setresgid
.long sys_getresgid .long sys_getresgid
.long sys_prctl .long sys_prctl

View File

@ -1543,7 +1543,7 @@ ENTRY(_sys_call_table)
.long _sys_ni_syscall /* for vm86 */ .long _sys_ni_syscall /* for vm86 */
.long _sys_ni_syscall /* old "query_module" */ .long _sys_ni_syscall /* old "query_module" */
.long _sys_ni_syscall /* sys_poll */ .long _sys_ni_syscall /* sys_poll */
.long _sys_nfsservctl .long _sys_ni_syscall /* old nfsservctl */
.long _sys_setresgid /* setresgid16 */ /* 170 */ .long _sys_setresgid /* setresgid16 */ /* 170 */
.long _sys_getresgid /* getresgid16 */ .long _sys_getresgid /* getresgid16 */
.long _sys_prctl .long _sys_prctl

View File

@ -771,7 +771,7 @@ sys_call_table:
.long sys_ni_syscall /* sys_vm86 */ .long sys_ni_syscall /* sys_vm86 */
.long sys_ni_syscall /* Old sys_query_module */ .long sys_ni_syscall /* Old sys_query_module */
.long sys_poll .long sys_poll
.long sys_nfsservctl .long sys_ni_syscall /* old nfsservctl */
.long sys_setresgid16 /* 170 */ .long sys_setresgid16 /* 170 */
.long sys_getresgid16 .long sys_getresgid16
.long sys_prctl .long sys_prctl

View File

@ -714,7 +714,7 @@ sys_call_table:
.long sys_ni_syscall /* sys_vm86 */ .long sys_ni_syscall /* sys_vm86 */
.long sys_ni_syscall /* Old sys_query_module */ .long sys_ni_syscall /* Old sys_query_module */
.long sys_poll .long sys_poll
.long sys_nfsservctl .long sys_ni_syscall /* Old nfsservctl */
.long sys_setresgid16 /* 170 */ .long sys_setresgid16 /* 170 */
.long sys_getresgid16 .long sys_getresgid16
.long sys_prctl .long sys_prctl

View 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 */

View File

@ -1358,7 +1358,7 @@ sys_call_table:
.long sys_ni_syscall /* for vm86 */ .long sys_ni_syscall /* for vm86 */
.long sys_ni_syscall /* Old sys_query_module */ .long sys_ni_syscall /* Old sys_query_module */
.long sys_poll .long sys_poll
.long sys_nfsservctl .long sys_ni_syscall /* Old nfsservctl */
.long sys_setresgid16 /* 170 */ .long sys_setresgid16 /* 170 */
.long sys_getresgid16 .long sys_getresgid16
.long sys_prctl .long sys_prctl

View File

@ -183,7 +183,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_ni_syscall) /* for vm86 */ .long SYMBOL_NAME(sys_ni_syscall) /* for vm86 */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_query_module */ .long SYMBOL_NAME(sys_ni_syscall) /* sys_query_module */
.long SYMBOL_NAME(sys_poll) .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_setresgid16) /* 170 */
.long SYMBOL_NAME(sys_getresgid16) .long SYMBOL_NAME(sys_getresgid16)
.long SYMBOL_NAME(sys_prctl) .long SYMBOL_NAME(sys_prctl)

View File

@ -1614,7 +1614,7 @@ sys_call_table:
data8 sys_sched_get_priority_min data8 sys_sched_get_priority_min
data8 sys_sched_rr_get_interval data8 sys_sched_rr_get_interval
data8 sys_nanosleep data8 sys_nanosleep
data8 sys_nfsservctl data8 sys_ni_syscall // old nfsservctl
data8 sys_prctl // 1170 data8 sys_prctl // 1170
data8 sys_getpagesize data8 sys_getpagesize
data8 sys_mmap2 data8 sys_mmap2

View File

@ -168,7 +168,7 @@ ENTRY(sys_call_table)
.long sys_tas /* vm86 syscall holder */ .long sys_tas /* vm86 syscall holder */
.long sys_ni_syscall /* query_module syscall holder */ .long sys_ni_syscall /* query_module syscall holder */
.long sys_poll .long sys_poll
.long sys_nfsservctl .long sys_ni_syscall /* was nfsservctl */
.long sys_setresgid /* 170 */ .long sys_setresgid /* 170 */
.long sys_getresgid .long sys_getresgid
.long sys_prctl .long sys_prctl

View File

@ -162,7 +162,7 @@ static inline __attribute_const__ int __virt_to_node_shift(void)
pgdat->node_mem_map + (__pfn - pgdat->node_start_pfn); \ pgdat->node_mem_map + (__pfn - pgdat->node_start_pfn); \
}) })
#define page_to_pfn(_page) ({ \ #define page_to_pfn(_page) ({ \
struct page *__p = (_page); \ const struct page *__p = (_page); \
struct pglist_data *pgdat; \ struct pglist_data *pgdat; \
pgdat = &pg_data_map[page_to_nid(__p)]; \ pgdat = &pg_data_map[page_to_nid(__p)]; \
((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \ ((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \

View File

@ -189,7 +189,7 @@ ENTRY(sys_call_table)
.long sys_getpagesize .long sys_getpagesize
.long sys_ni_syscall /* old "query_module" */ .long sys_ni_syscall /* old "query_module" */
.long sys_poll .long sys_poll
.long sys_nfsservctl .long sys_ni_syscall /* old nfsservctl */
.long sys_setresgid16 /* 170 */ .long sys_setresgid16 /* 170 */
.long sys_getresgid16 .long sys_getresgid16
.long sys_prctl .long sys_prctl

View File

@ -173,7 +173,7 @@ ENTRY(sys_call_table)
.long sys_ni_syscall /* sys_vm86 */ .long sys_ni_syscall /* sys_vm86 */
.long sys_ni_syscall /* Old sys_query_module */ .long sys_ni_syscall /* Old sys_query_module */
.long sys_poll .long sys_poll
.long sys_nfsservctl .long sys_ni_syscall /* old nfsservctl */
.long sys_setresgid /* 170 */ .long sys_setresgid /* 170 */
.long sys_getresgid .long sys_getresgid
.long sys_prctl .long sys_prctl

View File

@ -424,7 +424,7 @@ einval: li v0, -ENOSYS
sys sys_getresuid 3 sys sys_getresuid 3
sys sys_ni_syscall 0 /* was sys_query_module */ sys sys_ni_syscall 0 /* was sys_query_module */
sys sys_poll 3 sys sys_poll 3
sys sys_nfsservctl 3 sys sys_ni_syscall 0 /* was nfsservctl */
sys sys_setresgid 3 /* 4190 */ sys sys_setresgid 3 /* 4190 */
sys sys_getresgid 3 sys sys_getresgid 3
sys sys_prctl 5 sys sys_prctl 5

View File

@ -299,7 +299,7 @@ sys_call_table:
PTR sys_ni_syscall /* 5170, was get_kernel_syms */ PTR sys_ni_syscall /* 5170, was get_kernel_syms */
PTR sys_ni_syscall /* was query_module */ PTR sys_ni_syscall /* was query_module */
PTR sys_quotactl PTR sys_quotactl
PTR sys_nfsservctl PTR sys_ni_syscall /* was nfsservctl */
PTR sys_ni_syscall /* res. for getpmsg */ PTR sys_ni_syscall /* res. for getpmsg */
PTR sys_ni_syscall /* 5175 for putpmsg */ PTR sys_ni_syscall /* 5175 for putpmsg */
PTR sys_ni_syscall /* res. for afs_syscall */ PTR sys_ni_syscall /* res. for afs_syscall */

View File

@ -294,7 +294,7 @@ EXPORT(sysn32_call_table)
PTR sys_ni_syscall /* 6170, was get_kernel_syms */ PTR sys_ni_syscall /* 6170, was get_kernel_syms */
PTR sys_ni_syscall /* was query_module */ PTR sys_ni_syscall /* was query_module */
PTR sys_quotactl PTR sys_quotactl
PTR compat_sys_nfsservctl PTR sys_ni_syscall /* was nfsservctl */
PTR sys_ni_syscall /* res. for getpmsg */ PTR sys_ni_syscall /* res. for getpmsg */
PTR sys_ni_syscall /* 6175 for putpmsg */ PTR sys_ni_syscall /* 6175 for putpmsg */
PTR sys_ni_syscall /* res. for afs_syscall */ PTR sys_ni_syscall /* res. for afs_syscall */

View File

@ -392,7 +392,7 @@ sys_call_table:
PTR sys_getresuid PTR sys_getresuid
PTR sys_ni_syscall /* was query_module */ PTR sys_ni_syscall /* was query_module */
PTR sys_poll PTR sys_poll
PTR compat_sys_nfsservctl PTR sys_ni_syscall /* was nfsservctl */
PTR sys_setresgid /* 4190 */ PTR sys_setresgid /* 4190 */
PTR sys_getresgid PTR sys_getresgid
PTR sys_prctl PTR sys_prctl

View File

@ -589,7 +589,7 @@ ENTRY(sys_call_table)
.long sys_ni_syscall /* vm86 */ .long sys_ni_syscall /* vm86 */
.long sys_ni_syscall /* Old sys_query_module */ .long sys_ni_syscall /* Old sys_query_module */
.long sys_poll .long sys_poll
.long sys_nfsservctl .long sys_ni_syscall /* was nfsservctl */
.long sys_setresgid16 /* 170 */ .long sys_setresgid16 /* 170 */
.long sys_getresgid16 .long sys_getresgid16
.long sys_prctl .long sys_prctl

View File

@ -54,6 +54,7 @@
#define ODSR_CLEAR 0x1c00 #define ODSR_CLEAR 0x1c00
#define LTLEECSR_ENABLE_ALL 0xFFC000FC #define LTLEECSR_ENABLE_ALL 0xFFC000FC
#define ESCSR_CLEAR 0x07120204 #define ESCSR_CLEAR 0x07120204
#define IECSR_CLEAR 0x80000000
#define RIO_PORT1_EDCSR 0x0640 #define RIO_PORT1_EDCSR 0x0640
#define RIO_PORT2_EDCSR 0x0680 #define RIO_PORT2_EDCSR 0x0680
@ -1089,11 +1090,11 @@ static void port_error_handler(struct rio_mport *port, int offset)
if (offset == 0) { if (offset == 0) {
out_be32((u32 *)(rio_regs_win + RIO_PORT1_EDCSR), 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); out_be32((u32 *)(rio_regs_win + RIO_ESCSR), ESCSR_CLEAR);
} else { } else {
out_be32((u32 *)(rio_regs_win + RIO_PORT2_EDCSR), 0); 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); out_be32((u32 *)(rio_regs_win + RIO_PORT2_ESCSR), ESCSR_CLEAR);
} }
} }

View File

@ -665,12 +665,6 @@ ENTRY(sys32_poll_wrapper)
lgfr %r4,%r4 # long lgfr %r4,%r4 # long
jg sys_poll # branch to system call 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) ENTRY(sys32_setresgid16_wrapper)
llgfr %r2,%r2 # __kernel_old_gid_emu31_t llgfr %r2,%r2 # __kernel_old_gid_emu31_t
llgfr %r3,%r3 # __kernel_old_gid_emu31_t llgfr %r3,%r3 # __kernel_old_gid_emu31_t

View File

@ -396,17 +396,19 @@ static __init void detect_machine_facilities(void)
static __init void rescue_initrd(void) static __init void rescue_initrd(void)
{ {
#ifdef CONFIG_BLK_DEV_INITRD #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 * Just like in case of IPL from VM reader we make sure there is a
* within the bss section. So we don't overwrite it when the bss * gap of 4MB between end of kernel and start of initrd.
* section gets cleared. * That way we can also be sure that saving an NSS will succeed,
* which however only requires different segments.
*/ */
if (!INITRD_START || !INITRD_SIZE) if (!INITRD_START || !INITRD_SIZE)
return; return;
if (INITRD_START >= (unsigned long) __bss_stop) if (INITRD_START >= min_initrd_addr)
return; return;
memmove(__bss_stop, (void *) INITRD_START, INITRD_SIZE); memmove((void *) min_initrd_addr, (void *) INITRD_START, INITRD_SIZE);
INITRD_START = (unsigned long) __bss_stop; INITRD_START = min_initrd_addr;
#endif #endif
} }

View File

@ -1220,7 +1220,7 @@ static int __init reipl_fcp_init(void)
/* sysfs: create fcp kset for mixing attr group and bin attrs */ /* sysfs: create fcp kset for mixing attr group and bin attrs */
reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL, reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL,
&reipl_kset->kobj); &reipl_kset->kobj);
if (!reipl_kset) { if (!reipl_fcp_kset) {
free_page((unsigned long) reipl_block_fcp); free_page((unsigned long) reipl_block_fcp);
return -ENOMEM; return -ENOMEM;
} }
@ -1618,7 +1618,8 @@ static struct shutdown_action vmcmd_action = {SHUTDOWN_ACTION_VMCMD_STR,
static void stop_run(struct shutdown_trigger *trigger) 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)); disabled_wait((unsigned long) __builtin_return_address(0));
while (sigp(smp_processor_id(), sigp_stop) == sigp_busy) while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
cpu_relax(); cpu_relax();
@ -1717,7 +1718,7 @@ static void do_panic(void)
/* on restart */ /* on restart */
static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR, static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR,
&reipl_action}; &stop_action};
static ssize_t on_restart_show(struct kobject *kobj, static ssize_t on_restart_show(struct kobject *kobj,
struct kobj_attribute *attr, char *page) struct kobj_attribute *attr, char *page)

View File

@ -177,7 +177,7 @@ SYSCALL(sys_getresuid16,sys_ni_syscall,sys32_getresuid16_wrapper) /* 165 old get
NI_SYSCALL /* for vm86 */ NI_SYSCALL /* for vm86 */
NI_SYSCALL /* old sys_query_module */ NI_SYSCALL /* old sys_query_module */
SYSCALL(sys_poll,sys_poll,sys32_poll_wrapper) 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_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_getresgid16,sys_ni_syscall,sys32_getresgid16_wrapper) /* old getresgid16 syscall */
SYSCALL(sys_prctl,sys_prctl,sys32_prctl_wrapper) SYSCALL(sys_prctl,sys_prctl,sys32_prctl_wrapper)

View File

@ -185,7 +185,7 @@ ENTRY(sys_call_table)
.long sys_ni_syscall /* vm86 */ .long sys_ni_syscall /* vm86 */
.long sys_ni_syscall /* old "query_module" */ .long sys_ni_syscall /* old "query_module" */
.long sys_poll .long sys_poll
.long sys_nfsservctl .long sys_ni_syscall /* was nfsservctl */
.long sys_setresgid16 /* 170 */ .long sys_setresgid16 /* 170 */
.long sys_getresgid16 .long sys_getresgid16
.long sys_prctl .long sys_prctl

View File

@ -189,7 +189,7 @@ sys_call_table:
.long sys_ni_syscall /* vm86 */ .long sys_ni_syscall /* vm86 */
.long sys_ni_syscall /* old "query_module" */ .long sys_ni_syscall /* old "query_module" */
.long sys_poll .long sys_poll
.long sys_nfsservctl .long sys_ni_syscall /* was nfsservctl */
.long sys_setresgid16 /* 170 */ .long sys_setresgid16 /* 170 */
.long sys_getresgid16 .long sys_getresgid16
.long sys_prctl .long sys_prctl

View File

@ -45,6 +45,19 @@ typedef struct {
int si_mask; int si_mask;
} __siginfo32_t; } __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 #ifdef CONFIG_SPARC64
typedef struct { typedef struct {
unsigned int si_float_regs [64]; unsigned int si_float_regs [64];
@ -73,6 +86,7 @@ struct sigcontext {
unsigned long ss_size; unsigned long ss_size;
} sigc_stack; } sigc_stack;
unsigned long sigc_mask; unsigned long sigc_mask;
__siginfo_rwin_t * sigc_rwin_save;
}; };
#else #else

View File

@ -32,6 +32,7 @@ obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4c_irq.o sun4d_irq.o
obj-y += process_$(BITS).o obj-y += process_$(BITS).o
obj-y += signal_$(BITS).o obj-y += signal_$(BITS).o
obj-y += sigutil_$(BITS).o
obj-$(CONFIG_SPARC32) += ioport.o obj-$(CONFIG_SPARC32) += ioport.o
obj-y += setup_$(BITS).o obj-y += setup_$(BITS).o
obj-y += idprom.o obj-y += idprom.o

View File

@ -29,6 +29,8 @@
#include <asm/visasm.h> #include <asm/visasm.h>
#include <asm/compat_signal.h> #include <asm/compat_signal.h>
#include "sigutil.h"
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
/* This magic should be in g_upper[0] for all upper parts /* This magic should be in g_upper[0] for all upper parts
@ -44,14 +46,14 @@ typedef struct {
struct signal_frame32 { struct signal_frame32 {
struct sparc_stackf32 ss; struct sparc_stackf32 ss;
__siginfo32_t info; __siginfo32_t info;
/* __siginfo_fpu32_t * */ u32 fpu_save; /* __siginfo_fpu_t * */ u32 fpu_save;
unsigned int insns[2]; unsigned int insns[2];
unsigned int extramask[_COMPAT_NSIG_WORDS - 1]; unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
/* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
siginfo_extra_v8plus_t v8plus; siginfo_extra_v8plus_t v8plus;
__siginfo_fpu_t fpu_state; /* __siginfo_rwin_t * */u32 rwin_save;
}; } __attribute__((aligned(8)));
typedef struct compat_siginfo{ typedef struct compat_siginfo{
int si_signo; int si_signo;
@ -110,18 +112,14 @@ struct rt_signal_frame32 {
compat_siginfo_t info; compat_siginfo_t info;
struct pt_regs32 regs; struct pt_regs32 regs;
compat_sigset_t mask; compat_sigset_t mask;
/* __siginfo_fpu32_t * */ u32 fpu_save; /* __siginfo_fpu_t * */ u32 fpu_save;
unsigned int insns[2]; unsigned int insns[2];
stack_t32 stack; stack_t32 stack;
unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
/* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
siginfo_extra_v8plus_t v8plus; siginfo_extra_v8plus_t v8plus;
__siginfo_fpu_t fpu_state; /* __siginfo_rwin_t * */u32 rwin_save;
}; } __attribute__((aligned(8)));
/* Align macros */
#define SF_ALIGNEDSZ (((sizeof(struct signal_frame32) + 15) & (~15)))
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 15) & (~15)))
int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) 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; 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) void do_sigreturn32(struct pt_regs *regs)
{ {
struct signal_frame32 __user *sf; struct signal_frame32 __user *sf;
compat_uptr_t fpu_save;
compat_uptr_t rwin_save;
unsigned int psr; unsigned int psr;
unsigned pc, npc, fpu_save; unsigned pc, npc;
sigset_t set; sigset_t set;
unsigned seta[_COMPAT_NSIG_WORDS]; unsigned seta[_COMPAT_NSIG_WORDS];
int err, i; int err, i;
@ -273,8 +254,13 @@ void do_sigreturn32(struct pt_regs *regs)
pt_regs_clear_syscall(regs); pt_regs_clear_syscall(regs);
err |= __get_user(fpu_save, &sf->fpu_save); err |= __get_user(fpu_save, &sf->fpu_save);
if (fpu_save) if (!err && fpu_save)
err |= restore_fpu_state32(regs, &sf->fpu_state); 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 |= __get_user(seta[0], &sf->info.si_mask);
err |= copy_from_user(seta+1, &sf->extramask, err |= copy_from_user(seta+1, &sf->extramask,
(_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
@ -300,7 +286,9 @@ segv:
asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
{ {
struct rt_signal_frame32 __user *sf; 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; mm_segment_t old_fs;
sigset_t set; sigset_t set;
compat_sigset_t seta; compat_sigset_t seta;
@ -359,8 +347,8 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
pt_regs_clear_syscall(regs); pt_regs_clear_syscall(regs);
err |= __get_user(fpu_save, &sf->fpu_save); err |= __get_user(fpu_save, &sf->fpu_save);
if (fpu_save) if (!err && fpu_save)
err |= restore_fpu_state32(regs, &sf->fpu_state); err |= restore_fpu_state(regs, compat_ptr(fpu_save));
err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t)); err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
err |= __get_user(u_ss_sp, &sf->stack.ss_sp); err |= __get_user(u_ss_sp, &sf->stack.ss_sp);
st.ss_sp = compat_ptr(u_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); do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf);
set_fs(old_fs); 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) { switch (_NSIG_WORDS) {
case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32); 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); 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; 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 /* The I-cache flush instruction only works in the primary ASI, which
* right now is the nucleus, aka. kernel space. * 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) int signo, sigset_t *oldset)
{ {
struct signal_frame32 __user *sf; struct signal_frame32 __user *sf;
int i, err, wsaved;
void __user *tail;
int sigframe_size; int sigframe_size;
u32 psr; u32 psr;
int i, err;
unsigned int seta[_COMPAT_NSIG_WORDS]; unsigned int seta[_COMPAT_NSIG_WORDS];
/* 1. Make sure everything is clean */ /* 1. Make sure everything is clean */
synchronize_user_stack(); synchronize_user_stack();
save_and_clear_fpu(); save_and_clear_fpu();
sigframe_size = SF_ALIGNEDSZ; wsaved = get_thread_wsaved();
if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
sigframe_size -= sizeof(__siginfo_fpu_t); 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 *) sf = (struct signal_frame32 __user *)
get_sigframe(&ka->sa, regs, sigframe_size); 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)) if (invalid_frame_pointer(sf, sigframe_size))
goto sigill; goto sigill;
if (get_thread_wsaved() != 0) tail = (sf + 1);
goto sigill;
/* 2. Save the current process state */ /* 2. Save the current process state */
if (test_thread_flag(TIF_32BIT)) { 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); &sf->v8plus.asi);
if (psr & PSR_EF) { if (psr & PSR_EF) {
err |= save_fpu_state32(regs, &sf->fpu_state); __siginfo_fpu_t __user *fp = tail;
err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save); tail += sizeof(*fp);
err |= save_fpu_state(regs, fp);
err |= __put_user((u64)fp, &sf->fpu_save);
} else { } else {
err |= __put_user(0, &sf->fpu_save); 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) { switch (_NSIG_WORDS) {
case 4: seta[7] = (oldset->sig[3] >> 32); 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, err |= __copy_to_user(sf->extramask, seta + 1,
(_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
err |= copy_in_user((u32 __user *)sf, if (!wsaved) {
(u32 __user *)(regs->u_regs[UREG_FP]), err |= copy_in_user((u32 __user *)sf,
sizeof(struct reg_window32)); (u32 __user *)(regs->u_regs[UREG_FP]),
sizeof(struct reg_window32));
} else {
struct reg_window *rp;
rp = &current_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) if (err)
goto sigsegv; 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*/ err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
if (err) if (err)
goto sigsegv; goto sigsegv;
flush_signal_insns(address); flush_signal_insns(address);
} }
return 0; return 0;
@ -632,18 +631,23 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
siginfo_t *info) siginfo_t *info)
{ {
struct rt_signal_frame32 __user *sf; struct rt_signal_frame32 __user *sf;
int i, err, wsaved;
void __user *tail;
int sigframe_size; int sigframe_size;
u32 psr; u32 psr;
int i, err;
compat_sigset_t seta; compat_sigset_t seta;
/* 1. Make sure everything is clean */ /* 1. Make sure everything is clean */
synchronize_user_stack(); synchronize_user_stack();
save_and_clear_fpu(); save_and_clear_fpu();
sigframe_size = RT_ALIGNEDSZ; wsaved = get_thread_wsaved();
if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
sigframe_size -= sizeof(__siginfo_fpu_t); 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 *) sf = (struct rt_signal_frame32 __user *)
get_sigframe(&ka->sa, regs, sigframe_size); 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)) if (invalid_frame_pointer(sf, sigframe_size))
goto sigill; goto sigill;
if (get_thread_wsaved() != 0) tail = (sf + 1);
goto sigill;
/* 2. Save the current process state */ /* 2. Save the current process state */
if (test_thread_flag(TIF_32BIT)) { 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); &sf->v8plus.asi);
if (psr & PSR_EF) { if (psr & PSR_EF) {
err |= save_fpu_state32(regs, &sf->fpu_state); __siginfo_fpu_t __user *fp = tail;
err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save); tail += sizeof(*fp);
err |= save_fpu_state(regs, fp);
err |= __put_user((u64)fp, &sf->fpu_save);
} else { } else {
err |= __put_user(0, &sf->fpu_save); 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. */ /* Update the siginfo structure. */
err |= copy_siginfo_to_user32(&sf->info, info); 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_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
err |= copy_in_user((u32 __user *)sf, if (!wsaved) {
(u32 __user *)(regs->u_regs[UREG_FP]), err |= copy_in_user((u32 __user *)sf,
sizeof(struct reg_window32)); (u32 __user *)(regs->u_regs[UREG_FP]),
sizeof(struct reg_window32));
} else {
struct reg_window *rp;
rp = &current_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) if (err)
goto sigsegv; goto sigsegv;

View File

@ -26,6 +26,8 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/cacheflush.h> /* flush_sig_insns */ #include <asm/cacheflush.h> /* flush_sig_insns */
#include "sigutil.h"
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
extern void fpsave(unsigned long *fpregs, unsigned long *fsr, extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
@ -39,8 +41,8 @@ struct signal_frame {
unsigned long insns[2] __attribute__ ((aligned (8))); unsigned long insns[2] __attribute__ ((aligned (8)));
unsigned int extramask[_NSIG_WORDS - 1]; unsigned int extramask[_NSIG_WORDS - 1];
unsigned int extra_size; /* Should be 0 */ 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 rt_signal_frame {
struct sparc_stackf ss; struct sparc_stackf ss;
@ -51,8 +53,8 @@ struct rt_signal_frame {
unsigned int insns[2]; unsigned int insns[2];
stack_t stack; stack_t stack;
unsigned int extra_size; /* Should be 0 */ unsigned int extra_size; /* Should be 0 */
__siginfo_fpu_t fpu_state; __siginfo_rwin_t __user *rwin_save;
}; } __attribute__((aligned(8)));
/* Align macros */ /* Align macros */
#define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7))) #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); 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(&current->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(&current->thread.fpqueue[0],
&fpu->si_fpqueue[0],
((sizeof(unsigned long) +
(sizeof(unsigned long *)))*16));
return err;
}
asmlinkage void do_sigreturn(struct pt_regs *regs) asmlinkage void do_sigreturn(struct pt_regs *regs)
{ {
struct signal_frame __user *sf; struct signal_frame __user *sf;
unsigned long up_psr, pc, npc; unsigned long up_psr, pc, npc;
sigset_t set; sigset_t set;
__siginfo_fpu_t __user *fpu_save; __siginfo_fpu_t __user *fpu_save;
__siginfo_rwin_t __user *rwin_save;
int err; int err;
/* Always make any pending restarted system calls return -EINTR */ /* 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); pt_regs_clear_syscall(regs);
err |= __get_user(fpu_save, &sf->fpu_save); err |= __get_user(fpu_save, &sf->fpu_save);
if (fpu_save) if (fpu_save)
err |= restore_fpu_state(regs, 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 /* This is pretty much atomic, no amount locking would prevent
* the races which exist anyways. * the races which exist anyways.
@ -180,6 +154,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
struct rt_signal_frame __user *sf; struct rt_signal_frame __user *sf;
unsigned int psr, pc, npc; unsigned int psr, pc, npc;
__siginfo_fpu_t __user *fpu_save; __siginfo_fpu_t __user *fpu_save;
__siginfo_rwin_t __user *rwin_save;
mm_segment_t old_fs; mm_segment_t old_fs;
sigset_t set; sigset_t set;
stack_t st; stack_t st;
@ -207,8 +182,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
pt_regs_clear_syscall(regs); pt_regs_clear_syscall(regs);
err |= __get_user(fpu_save, &sf->fpu_save); err |= __get_user(fpu_save, &sf->fpu_save);
if (!err && fpu_save)
if (fpu_save)
err |= restore_fpu_state(regs, fpu_save); err |= restore_fpu_state(regs, fpu_save);
err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); 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); do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf);
set_fs(old_fs); 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); sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
current->blocked = set; current->blocked = set;
@ -280,53 +260,23 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re
return (void __user *) sp; 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(&current->thread.float_regs[0], &current->thread.fsr,
&current->thread.fpqueue[0], &current->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(&current->thread.float_regs[0], &current->thread.fsr,
&current->thread.fpqueue[0], &current->thread.fpqdepth);
last_task_used_math = NULL;
regs->psr &= ~(PSR_EF);
}
#endif
err |= __copy_to_user(&fpu->si_float_regs[0],
&current->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],
&current->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, static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset) int signo, sigset_t *oldset)
{ {
struct signal_frame __user *sf; struct signal_frame __user *sf;
int sigframe_size, err; int sigframe_size, err, wsaved;
void __user *tail;
/* 1. Make sure everything is clean */ /* 1. Make sure everything is clean */
synchronize_user_stack(); synchronize_user_stack();
sigframe_size = SF_ALIGNEDSZ; wsaved = current_thread_info()->w_saved;
if (!used_math())
sigframe_size -= sizeof(__siginfo_fpu_t); 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 *) sf = (struct signal_frame __user *)
get_sigframe(&ka->sa, regs, sigframe_size); 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)) if (invalid_frame_pointer(sf, sigframe_size))
goto sigill_and_return; goto sigill_and_return;
if (current_thread_info()->w_saved != 0) tail = sf + 1;
goto sigill_and_return;
/* 2. Save the current process state */ /* 2. Save the current process state */
err = __copy_to_user(&sf->info.si_regs, regs, sizeof(struct pt_regs)); 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); err |= __put_user(0, &sf->extra_size);
if (used_math()) { if (used_math()) {
err |= save_fpu_state(regs, &sf->fpu_state); __siginfo_fpu_t __user *fp = tail;
err |= __put_user(&sf->fpu_state, &sf->fpu_save); tail += sizeof(*fp);
err |= save_fpu_state(regs, fp);
err |= __put_user(fp, &sf->fpu_save);
} else { } else {
err |= __put_user(0, &sf->fpu_save); 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 |= __put_user(oldset->sig[0], &sf->info.si_mask);
err |= __copy_to_user(sf->extramask, &oldset->sig[1], err |= __copy_to_user(sf->extramask, &oldset->sig[1],
(_NSIG_WORDS - 1) * sizeof(unsigned int)); (_NSIG_WORDS - 1) * sizeof(unsigned int));
err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], if (!wsaved) {
sizeof(struct reg_window32)); err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
sizeof(struct reg_window32));
} else {
struct reg_window32 *rp;
rp = &current_thread_info()->reg_window[wsaved - 1];
err |= __copy_to_user(sf, rp, sizeof(struct reg_window32));
}
if (err) if (err)
goto sigsegv; 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) int signo, sigset_t *oldset, siginfo_t *info)
{ {
struct rt_signal_frame __user *sf; struct rt_signal_frame __user *sf;
int sigframe_size; int sigframe_size, wsaved;
void __user *tail;
unsigned int psr; unsigned int psr;
int err; int err;
synchronize_user_stack(); synchronize_user_stack();
sigframe_size = RT_ALIGNEDSZ; wsaved = current_thread_info()->w_saved;
if (!used_math()) sigframe_size = sizeof(*sf);
sigframe_size -= sizeof(__siginfo_fpu_t); if (used_math())
sigframe_size += sizeof(__siginfo_fpu_t);
if (wsaved)
sigframe_size += sizeof(__siginfo_rwin_t);
sf = (struct rt_signal_frame __user *) sf = (struct rt_signal_frame __user *)
get_sigframe(&ka->sa, regs, sigframe_size); get_sigframe(&ka->sa, regs, sigframe_size);
if (invalid_frame_pointer(sf, sigframe_size)) if (invalid_frame_pointer(sf, sigframe_size))
goto sigill; 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->pc, &sf->regs.pc);
err |= __put_user(regs->npc, &sf->regs.npc); err |= __put_user(regs->npc, &sf->regs.npc);
err |= __put_user(regs->y, &sf->regs.y); 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); err |= __put_user(0, &sf->extra_size);
if (psr & PSR_EF) { if (psr & PSR_EF) {
err |= save_fpu_state(regs, &sf->fpu_state); __siginfo_fpu_t *fp = tail;
err |= __put_user(&sf->fpu_state, &sf->fpu_save); tail += sizeof(*fp);
err |= save_fpu_state(regs, fp);
err |= __put_user(fp, &sf->fpu_save);
} else { } else {
err |= __put_user(0, &sf->fpu_save); 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)); err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));
/* Setup sigaltstack */ /* 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(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], if (!wsaved) {
sizeof(struct reg_window32)); err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
sizeof(struct reg_window32));
} else {
struct reg_window32 *rp;
rp = &current_thread_info()->reg_window[wsaved - 1];
err |= __copy_to_user(sf, rp, sizeof(struct reg_window32));
}
err |= copy_siginfo_to_user(&sf->info, info); err |= copy_siginfo_to_user(&sf->info, info);

View File

@ -34,6 +34,7 @@
#include "entry.h" #include "entry.h"
#include "systbls.h" #include "systbls.h"
#include "sigutil.h"
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
@ -236,7 +237,7 @@ struct rt_signal_frame {
__siginfo_fpu_t __user *fpu_save; __siginfo_fpu_t __user *fpu_save;
stack_t stack; stack_t stack;
sigset_t mask; sigset_t mask;
__siginfo_fpu_t fpu_state; __siginfo_rwin_t *rwin_save;
}; };
static long _sigpause_common(old_sigset_t set) static long _sigpause_common(old_sigset_t set)
@ -266,33 +267,12 @@ asmlinkage long sys_sigsuspend(old_sigset_t set)
return _sigpause_common(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) void do_rt_sigreturn(struct pt_regs *regs)
{ {
struct rt_signal_frame __user *sf; struct rt_signal_frame __user *sf;
unsigned long tpc, tnpc, tstate; unsigned long tpc, tnpc, tstate;
__siginfo_fpu_t __user *fpu_save; __siginfo_fpu_t __user *fpu_save;
__siginfo_rwin_t __user *rwin_save;
sigset_t set; sigset_t set;
int err; int err;
@ -325,8 +305,8 @@ void do_rt_sigreturn(struct pt_regs *regs)
regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC)); regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));
err |= __get_user(fpu_save, &sf->fpu_save); err |= __get_user(fpu_save, &sf->fpu_save);
if (fpu_save) if (!err && fpu_save)
err |= restore_fpu_state(regs, &sf->fpu_state); err |= restore_fpu_state(regs, fpu_save);
err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf); err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf);
@ -334,6 +314,12 @@ void do_rt_sigreturn(struct pt_regs *regs)
if (err) if (err)
goto segv; 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->tpc = tpc;
regs->tnpc = tnpc; regs->tnpc = tnpc;
@ -351,34 +337,13 @@ segv:
} }
/* Checks if the fp is valid */ /* 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) if (((unsigned long) fp) & 15)
return 1; return 1;
return 0; 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) 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; 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) int signo, sigset_t *oldset, siginfo_t *info)
{ {
struct rt_signal_frame __user *sf; struct rt_signal_frame __user *sf;
int sigframe_size, err; int wsaved, err, sf_size;
void __user *tail;
/* 1. Make sure everything is clean */ /* 1. Make sure everything is clean */
synchronize_user_stack(); synchronize_user_stack();
save_and_clear_fpu(); save_and_clear_fpu();
sigframe_size = sizeof(struct rt_signal_frame); wsaved = get_thread_wsaved();
if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
sigframe_size -= sizeof(__siginfo_fpu_t);
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 *) sf = (struct rt_signal_frame __user *)
get_sigframe(ka, regs, sigframe_size); get_sigframe(ka, regs, sf_size);
if (invalid_frame_pointer (sf, sigframe_size)) if (invalid_frame_pointer (sf))
goto sigill; goto sigill;
if (get_thread_wsaved() != 0) tail = (sf + 1);
goto sigill;
/* 2. Save the current process state */ /* 2. Save the current process state */
err = copy_to_user(&sf->regs, regs, sizeof (*regs)); err = copy_to_user(&sf->regs, regs, sizeof (*regs));
if (current_thread_info()->fpsaved[0] & FPRS_FEF) { if (current_thread_info()->fpsaved[0] & FPRS_FEF) {
err |= save_fpu_state(regs, &sf->fpu_state); __siginfo_fpu_t __user *fpu_save = tail;
err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save); tail += sizeof(__siginfo_fpu_t);
err |= save_fpu_state(regs, fpu_save);
err |= __put_user((u64)fpu_save, &sf->fpu_save);
} else { } else {
err |= __put_user(0, &sf->fpu_save); 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 */ /* Setup sigaltstack */
err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); 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_to_user(&sf->mask, oldset, sizeof(sigset_t));
err |= copy_in_user((u64 __user *)sf, if (!wsaved) {
(u64 __user *)(regs->u_regs[UREG_FP]+STACK_BIAS), err |= copy_in_user((u64 __user *)sf,
sizeof(struct reg_window)); (u64 __user *)(regs->u_regs[UREG_FP] +
STACK_BIAS),
sizeof(struct reg_window));
} else {
struct reg_window *rp;
rp = &current_thread_info()->reg_window[wsaved - 1];
err |= copy_to_user(sf, rp, sizeof(struct reg_window));
}
if (info) if (info)
err |= copy_siginfo_to_user(&sf->info, info); err |= copy_siginfo_to_user(&sf->info, info);
else { else {

View 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 */

View 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(&current->thread.float_regs[0], &current->thread.fsr,
&current->thread.fpqueue[0], &current->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(&current->thread.float_regs[0], &current->thread.fsr,
&current->thread.fpqueue[0], &current->thread.fpqdepth);
last_task_used_math = NULL;
regs->psr &= ~(PSR_EF);
}
#endif
err |= __copy_to_user(&fpu->si_float_regs[0],
&current->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],
&current->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(&current->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(&current->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 = &current_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;
}

View 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 = &current_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;
}

View File

@ -81,7 +81,6 @@ SIGN2(sys32_fadvise64, compat_sys_fadvise64, %o0, %o4)
SIGN2(sys32_fadvise64_64, compat_sys_fadvise64_64, %o0, %o5) SIGN2(sys32_fadvise64_64, compat_sys_fadvise64_64, %o0, %o5)
SIGN2(sys32_bdflush, sys_bdflush, %o0, %o1) SIGN2(sys32_bdflush, sys_bdflush, %o0, %o1)
SIGN1(sys32_mlockall, sys_mlockall, %o0) SIGN1(sys32_mlockall, sys_mlockall, %o0)
SIGN1(sys32_nfsservctl, compat_sys_nfsservctl, %o0)
SIGN1(sys32_clock_nanosleep, compat_sys_clock_nanosleep, %o1) SIGN1(sys32_clock_nanosleep, compat_sys_clock_nanosleep, %o1)
SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1) SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1)
SIGN1(sys32_io_submit, compat_sys_io_submit, %o1) SIGN1(sys32_io_submit, compat_sys_io_submit, %o1)

View File

@ -67,7 +67,7 @@ sys_call_table:
/*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*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 /*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 /*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 /*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 /*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 /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy

View File

@ -145,7 +145,7 @@ sys_call_table:
.word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall .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 /*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 .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 .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 /*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 .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy

View File

@ -672,7 +672,7 @@ ia32_sys_call_table:
.quad sys32_vm86_warning /* vm86 */ .quad sys32_vm86_warning /* vm86 */
.quad quiet_ni_syscall /* query_module */ .quad quiet_ni_syscall /* query_module */
.quad sys_poll .quad sys_poll
.quad compat_sys_nfsservctl .quad quiet_ni_syscall /* old nfsservctl */
.quad sys_setresgid16 /* 170 */ .quad sys_setresgid16 /* 170 */
.quad sys_getresgid16 .quad sys_getresgid16
.quad sys_prctl .quad sys_prctl

View File

@ -414,7 +414,7 @@ __SYSCALL(__NR_query_module, sys_ni_syscall)
__SYSCALL(__NR_quotactl, sys_quotactl) __SYSCALL(__NR_quotactl, sys_quotactl)
#define __NR_nfsservctl 180 #define __NR_nfsservctl 180
__SYSCALL(__NR_nfsservctl, sys_nfsservctl) __SYSCALL(__NR_nfsservctl, sys_ni_syscall)
/* reserved for LiS/STREAMS */ /* reserved for LiS/STREAMS */
#define __NR_getpmsg 181 #define __NR_getpmsg 181

View File

@ -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) | ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
APIC_DM_INIT; APIC_DM_INIT;
uv_write_global_mmr64(pnode, UVH_IPI_INT, val); uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
mdelay(10);
val = (1UL << UVH_IPI_INT_SEND_SHFT) | val = (1UL << UVH_IPI_INT_SEND_SHFT) |
(phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) |

View File

@ -149,7 +149,6 @@ struct set_mtrr_data {
*/ */
static int mtrr_rendezvous_handler(void *info) static int mtrr_rendezvous_handler(void *info)
{ {
#ifdef CONFIG_SMP
struct set_mtrr_data *data = info; 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())) { } else if (mtrr_aps_delayed_init || !cpu_online(smp_processor_id())) {
mtrr_if->set_all(); mtrr_if->set_all();
} }
#endif
return 0; return 0;
} }

View File

@ -54,6 +54,7 @@
#include <asm/ftrace.h> #include <asm/ftrace.h>
#include <asm/irq_vectors.h> #include <asm/irq_vectors.h>
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <asm/alternative-asm.h>
/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */ /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
#include <linux/elf-em.h> #include <linux/elf-em.h>
@ -873,12 +874,7 @@ ENTRY(simd_coprocessor_error)
661: pushl_cfi $do_general_protection 661: pushl_cfi $do_general_protection
662: 662:
.section .altinstructions,"a" .section .altinstructions,"a"
.balign 4 altinstruction_entry 661b, 663f, X86_FEATURE_XMM, 662b-661b, 664f-663f
.long 661b
.long 663f
.word X86_FEATURE_XMM
.byte 662b-661b
.byte 664f-663f
.previous .previous
.section .altinstr_replacement,"ax" .section .altinstr_replacement,"ax"
663: pushl $do_simd_coprocessor_error 663: pushl $do_simd_coprocessor_error

View File

@ -168,7 +168,7 @@ ENTRY(sys_call_table)
.long ptregs_vm86 .long ptregs_vm86
.long sys_ni_syscall /* Old sys_query_module */ .long sys_ni_syscall /* Old sys_query_module */
.long sys_poll .long sys_poll
.long sys_nfsservctl .long sys_ni_syscall /* Old nfsservctl */
.long sys_setresgid16 /* 170 */ .long sys_setresgid16 /* 170 */
.long sys_getresgid16 .long sys_getresgid16
.long sys_prctl .long sys_prctl

View File

@ -689,7 +689,9 @@ static int __init sfi_parse_devs(struct sfi_table_header *table)
irq_attr.trigger = 1; irq_attr.trigger = 1;
irq_attr.polarity = 1; irq_attr.polarity = 1;
io_apic_set_pci_routing(NULL, pentry->irq, &irq_attr); io_apic_set_pci_routing(NULL, pentry->irq, &irq_attr);
} } else
pentry->irq = 0; /* No irq */
switch (pentry->type) { switch (pentry->type) {
case SFI_DEV_TYPE_IPC: case SFI_DEV_TYPE_IPC:
/* ID as IRQ is a hack that will go away */ /* ID as IRQ is a hack that will go away */

View File

@ -161,13 +161,13 @@ restart:
if (inbuf && inlen) { if (inbuf && inlen) {
/* write data to EC */ /* write data to EC */
for (i = 0; i < inlen; i++) { 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)) { if (wait_on_ibf(0x6c, 0)) {
printk(KERN_ERR "olpc-ec: timeout waiting for" printk(KERN_ERR "olpc-ec: timeout waiting for"
" EC accept data!\n"); " EC accept data!\n");
goto err; goto err;
} }
pr_devel("olpc-ec: sending cmd arg 0x%x\n", inbuf[i]);
outb(inbuf[i], 0x68);
} }
} }
if (outbuf && outlen) { if (outbuf && outlen) {

View File

@ -43,7 +43,7 @@ __kernel_vsyscall:
.space 7,0x90 .space 7,0x90
/* 14: System call restart point is here! (SYSENTER_RETURN-2) */ /* 14: System call restart point is here! (SYSENTER_RETURN-2) */
jmp .Lenter_kernel int $0x80
/* 16: System call normal return point is here! */ /* 16: System call normal return point is here! */
VDSO32_SYSENTER_RETURN: /* Symbol used by sysenter.c via vdso32-syms.h */ VDSO32_SYSENTER_RETURN: /* Symbol used by sysenter.c via vdso32-syms.h */
pop %ebp pop %ebp

View File

@ -455,7 +455,7 @@ __SYSCALL(203, sys_reboot, 3)
#define __NR_quotactl 204 #define __NR_quotactl 204
__SYSCALL(204, sys_quotactl, 4) __SYSCALL(204, sys_quotactl, 4)
#define __NR_nfsservctl 205 #define __NR_nfsservctl 205
__SYSCALL(205, sys_nfsservctl, 3) __SYSCALL(205, sys_ni_syscall, 0)
#define __NR__sysctl 206 #define __NR__sysctl 206
__SYSCALL(206, sys_sysctl, 1) __SYSCALL(206, sys_sysctl, 1)
#define __NR_bdflush 207 #define __NR_bdflush 207

View File

@ -397,6 +397,7 @@ static int remove_nodes(struct device *dev,
static int release_nodes(struct device *dev, struct list_head *first, static int release_nodes(struct device *dev, struct list_head *first,
struct list_head *end, unsigned long flags) struct list_head *end, unsigned long flags)
__releases(&dev->devres_lock)
{ {
LIST_HEAD(todo); LIST_HEAD(todo);
int cnt; int cnt;

View File

@ -376,7 +376,7 @@ int devtmpfs_mount(const char *mntdir)
return err; 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) static int handle(const char *name, mode_t mode, struct device *dev)
{ {

View File

@ -521,11 +521,6 @@ static int _request_firmware(const struct firmware **firmware_p,
if (!firmware_p) if (!firmware_p)
return -EINVAL; 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); *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
if (!firmware) { if (!firmware) {
dev_err(device, "%s: kmalloc(struct firmware) failed\n", dev_err(device, "%s: kmalloc(struct firmware) failed\n",
@ -539,6 +534,12 @@ static int _request_firmware(const struct firmware **firmware_p,
return 0; 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) if (uevent)
dev_dbg(device, "firmware: requesting %s\n", name); dev_dbg(device, "firmware: requesting %s\n", name);

View File

@ -33,7 +33,7 @@ EXPORT_SYMBOL_GPL(platform_bus);
/** /**
* arch_setup_pdev_archdata - Allow manipulation of archdata before its used * 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 * 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 * be setup before the platform_notifier is called. So if a user needs to

View File

@ -19,7 +19,7 @@
struct pm_clk_data { struct pm_clk_data {
struct list_head clock_list; struct list_head clock_list;
struct mutex lock; spinlock_t lock;
}; };
enum pce_status { 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); list_add_tail(&ce->node, &pcd->clock_list);
mutex_unlock(&pcd->lock); spin_unlock_irq(&pcd->lock);
return 0; return 0;
} }
@ -83,8 +83,8 @@ int pm_clk_add(struct device *dev, const char *con_id)
* __pm_clk_remove - Destroy PM clock entry. * __pm_clk_remove - Destroy PM clock entry.
* @ce: PM clock entry to destroy. * @ce: PM clock entry to destroy.
* *
* This routine must be called under the mutex protecting the PM list of clocks * This routine must be called under the spinlock protecting the PM list of
* corresponding the the @ce's device. * clocks corresponding the the @ce's device.
*/ */
static void __pm_clk_remove(struct pm_clock_entry *ce) 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) if (!pcd)
return; return;
mutex_lock(&pcd->lock); spin_lock_irq(&pcd->lock);
list_for_each_entry(ce, &pcd->clock_list, node) { list_for_each_entry(ce, &pcd->clock_list, node) {
if (!con_id && !ce->con_id) { 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); INIT_LIST_HEAD(&pcd->clock_list);
mutex_init(&pcd->lock); spin_lock_init(&pcd->lock);
dev->power.subsys_data = pcd; dev->power.subsys_data = pcd;
return 0; return 0;
} }
@ -181,12 +181,12 @@ void pm_clk_destroy(struct device *dev)
dev->power.subsys_data = NULL; 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) list_for_each_entry_safe_reverse(ce, c, &pcd->clock_list, node)
__pm_clk_remove(ce); __pm_clk_remove(ce);
mutex_unlock(&pcd->lock); spin_unlock_irq(&pcd->lock);
kfree(pcd); kfree(pcd);
} }
@ -220,13 +220,14 @@ int pm_clk_suspend(struct device *dev)
{ {
struct pm_clk_data *pcd = __to_pcd(dev); struct pm_clk_data *pcd = __to_pcd(dev);
struct pm_clock_entry *ce; struct pm_clock_entry *ce;
unsigned long flags;
dev_dbg(dev, "%s()\n", __func__); dev_dbg(dev, "%s()\n", __func__);
if (!pcd) if (!pcd)
return 0; return 0;
mutex_lock(&pcd->lock); spin_lock_irqsave(&pcd->lock, flags);
list_for_each_entry_reverse(ce, &pcd->clock_list, node) { list_for_each_entry_reverse(ce, &pcd->clock_list, node) {
if (ce->status == PCE_STATUS_NONE) 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; return 0;
} }
@ -251,13 +252,14 @@ int pm_clk_resume(struct device *dev)
{ {
struct pm_clk_data *pcd = __to_pcd(dev); struct pm_clk_data *pcd = __to_pcd(dev);
struct pm_clock_entry *ce; struct pm_clock_entry *ce;
unsigned long flags;
dev_dbg(dev, "%s()\n", __func__); dev_dbg(dev, "%s()\n", __func__);
if (!pcd) if (!pcd)
return 0; return 0;
mutex_lock(&pcd->lock); spin_lock_irqsave(&pcd->lock, flags);
list_for_each_entry(ce, &pcd->clock_list, node) { list_for_each_entry(ce, &pcd->clock_list, node) {
if (ce->status == PCE_STATUS_NONE) 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; return 0;
} }
@ -344,6 +346,7 @@ int pm_clk_suspend(struct device *dev)
{ {
struct pm_clk_data *pcd = __to_pcd(dev); struct pm_clk_data *pcd = __to_pcd(dev);
struct pm_clock_entry *ce; struct pm_clock_entry *ce;
unsigned long flags;
dev_dbg(dev, "%s()\n", __func__); dev_dbg(dev, "%s()\n", __func__);
@ -351,12 +354,12 @@ int pm_clk_suspend(struct device *dev)
if (!pcd || !dev->driver) if (!pcd || !dev->driver)
return 0; return 0;
mutex_lock(&pcd->lock); spin_lock_irqsave(&pcd->lock, flags);
list_for_each_entry_reverse(ce, &pcd->clock_list, node) list_for_each_entry_reverse(ce, &pcd->clock_list, node)
clk_disable(ce->clk); clk_disable(ce->clk);
mutex_unlock(&pcd->lock); spin_unlock_irqrestore(&pcd->lock, flags);
return 0; return 0;
} }
@ -369,6 +372,7 @@ int pm_clk_resume(struct device *dev)
{ {
struct pm_clk_data *pcd = __to_pcd(dev); struct pm_clk_data *pcd = __to_pcd(dev);
struct pm_clock_entry *ce; struct pm_clock_entry *ce;
unsigned long flags;
dev_dbg(dev, "%s()\n", __func__); dev_dbg(dev, "%s()\n", __func__);
@ -376,12 +380,12 @@ int pm_clk_resume(struct device *dev)
if (!pcd || !dev->driver) if (!pcd || !dev->driver)
return 0; return 0;
mutex_lock(&pcd->lock); spin_lock_irqsave(&pcd->lock, flags);
list_for_each_entry(ce, &pcd->clock_list, node) list_for_each_entry(ce, &pcd->clock_list, node)
clk_enable(ce->clk); clk_enable(ce->clk);
mutex_unlock(&pcd->lock); spin_unlock_irqrestore(&pcd->lock, flags);
return 0; return 0;
} }

View File

@ -379,9 +379,8 @@ static int __init smd_pkt_init(void)
for (i = 0; i < NUM_SMD_PKT_PORTS; ++i) { for (i = 0; i < NUM_SMD_PKT_PORTS; ++i) {
smd_pkt_devp[i] = kzalloc(sizeof(struct smd_pkt_dev), smd_pkt_devp[i] = kzalloc(sizeof(struct smd_pkt_dev),
GFP_KERNEL); GFP_KERNEL);
if (IS_ERR(smd_pkt_devp[i])) { if (!smd_pkt_devp[i]) {
r = PTR_ERR(smd_pkt_devp[i]); pr_err("kmalloc() failed\n");
pr_err("kmalloc() failed %d\n", r);
goto clean_cdevs; goto clean_cdevs;
} }

View File

@ -1198,6 +1198,10 @@ static int sbp2_remove(struct device *dev)
{ {
struct fw_unit *unit = fw_unit(dev); struct fw_unit *unit = fw_unit(dev);
struct sbp2_target *tgt = dev_get_drvdata(&unit->device); 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); sbp2_target_put(tgt);
return 0; return 0;

View File

@ -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, static efi_status_t gsmi_set_variable(efi_char16_t *name,
efi_guid_t *vendor, efi_guid_t *vendor,
unsigned long attr, u32 attr,
unsigned long data_size, unsigned long data_size,
void *data) void *data)
{ {

View File

@ -878,7 +878,7 @@ static void assert_panel_unlocked(struct drm_i915_private *dev_priv,
int pp_reg, lvds_reg; int pp_reg, lvds_reg;
u32 val; u32 val;
enum pipe panel_pipe = PIPE_A; enum pipe panel_pipe = PIPE_A;
bool locked = locked; bool locked = true;
if (HAS_PCH_SPLIT(dev_priv->dev)) { if (HAS_PCH_SPLIT(dev_priv->dev)) {
pp_reg = PCH_PP_CONTROL; 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_encoder_clones(dev, encoder->clone_mask);
} }
intel_panel_setup_backlight(dev);
/* disable all the possible outputs/crtcs before entering KMS mode */ /* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev); drm_helper_disable_unused_functions(dev);
} }

View File

@ -466,6 +466,16 @@ static bool radeon_connector_needs_extended_probe(struct radeon_device *dev,
(supported_device == ATOM_DEVICE_DFP2_SUPPORT)) (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
return true; 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 */ /* Default: no EDID header probe required for DDC probing */
return false; return false;

View File

@ -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->mc_vram_size = mc->aper_size;
} }
mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; 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", dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n",
mc->mc_vram_size >> 20, mc->vram_start, mc->mc_vram_size >> 20, mc->vram_start,
mc->vram_end, mc->real_vram_size >> 20); mc->vram_end, mc->real_vram_size >> 20);

View File

@ -40,10 +40,14 @@ void radeon_test_moves(struct radeon_device *rdev)
size = 1024 * 1024; size = 1024 * 1024;
/* Number of tests = /* 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 - n = rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - rdev->cp.ring_size;
rdev->cp.ring_size)) / 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); gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL);
if (!gtt_obj) { if (!gtt_obj) {
@ -132,9 +136,15 @@ void radeon_test_moves(struct radeon_device *rdev)
gtt_start++, vram_start++) { gtt_start++, vram_start++) {
if (*vram_start != gtt_start) { if (*vram_start != gtt_start) {
DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, " DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, "
"expected 0x%p (GTT map 0x%p-0x%p)\n", "expected 0x%p (GTT/VRAM offset "
i, *vram_start, gtt_start, gtt_map, "0x%16llx/0x%16llx)\n",
gtt_end); 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); radeon_bo_kunmap(vram_obj);
goto out_cleanup; goto out_cleanup;
} }
@ -175,9 +185,15 @@ void radeon_test_moves(struct radeon_device *rdev)
gtt_start++, vram_start++) { gtt_start++, vram_start++) {
if (*gtt_start != vram_start) { if (*gtt_start != vram_start) {
DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, " DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, "
"expected 0x%p (VRAM map 0x%p-0x%p)\n", "expected 0x%p (VRAM/GTT offset "
i, *gtt_start, vram_start, vram_map, "0x%16llx/0x%16llx)\n",
vram_end); 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]); radeon_bo_kunmap(gtt_obj[i]);
goto out_cleanup; goto out_cleanup;
} }

View File

@ -450,6 +450,29 @@ static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_
return -EINVAL; return -EINVAL;
mem->bus.base = rdev->mc.aper_base; mem->bus.base = rdev->mc.aper_base;
mem->bus.is_iomem = true; 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; break;
default: default:
return -EINVAL; return -EINVAL;

View File

@ -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, ret = ttm_tt_set_user(bo->ttm, current,
bo->buffer_start, bo->num_pages); bo->buffer_start, bo->num_pages);
if (unlikely(ret != 0)) if (unlikely(ret != 0)) {
ttm_tt_destroy(bo->ttm); ttm_tt_destroy(bo->ttm);
bo->ttm = NULL;
}
break; break;
default: default:
printk(KERN_ERR TTM_PFX "Illegal buffer object type\n"); 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. * Create and bind a ttm if required.
*/ */
if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED) && (bo->ttm == NULL)) { if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) {
ret = ttm_bo_add_ttm(bo, false); if (bo->ttm == NULL) {
if (ret) ret = ttm_bo_add_ttm(bo, false);
goto out_err; if (ret)
goto out_err;
}
ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement); ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement);
if (ret) if (ret)

View File

@ -635,13 +635,13 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
if (ret) if (ret)
return ret; return ret;
ttm_bo_free_old_node(bo);
if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
(bo->ttm != NULL)) { (bo->ttm != NULL)) {
ttm_tt_unbind(bo->ttm); ttm_tt_unbind(bo->ttm);
ttm_tt_destroy(bo->ttm); ttm_tt_destroy(bo->ttm);
bo->ttm = NULL; bo->ttm = NULL;
} }
ttm_bo_free_old_node(bo);
} else { } else {
/** /**
* This should help pipeline ordinary buffer moves. * This should help pipeline ordinary buffer moves.

View File

@ -589,6 +589,7 @@ config HID_WACOM_POWER_SUPPLY
config HID_WIIMOTE config HID_WIIMOTE
tristate "Nintendo Wii Remote support" tristate "Nintendo Wii Remote support"
depends on BT_HIDP depends on BT_HIDP
depends on LEDS_CLASS
---help--- ---help---
Support for the Nintendo Wii Remote bluetooth device. Support for the Nintendo Wii Remote bluetooth device.

View File

@ -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), { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_RDESC_JIS }, 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), { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO), { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO),

View File

@ -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_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_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_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_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_ISO) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },

View File

@ -109,6 +109,9 @@
#define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245
#define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246
#define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247 #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_ANSI 0x0239
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b #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_IR_REMOTE 0x0001
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 #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_VENDOR_ID_SKYCABLE 0x1223
#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 #define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07

View File

@ -10,10 +10,10 @@
* any later version. * any later version.
*/ */
#include <linux/atomic.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/hid.h> #include <linux/hid.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/leds.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include "hid-ids.h" #include "hid-ids.h"
@ -33,9 +33,9 @@ struct wiimote_state {
}; };
struct wiimote_data { struct wiimote_data {
atomic_t ready;
struct hid_device *hdev; struct hid_device *hdev;
struct input_dev *input; struct input_dev *input;
struct led_classdev *leds[4];
spinlock_t qlock; spinlock_t qlock;
__u8 head; __u8 head;
@ -53,8 +53,15 @@ struct wiimote_data {
#define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \ #define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \
WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4) WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4)
/* return flag for led \num */
#define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1))
enum wiiproto_reqs { enum wiiproto_reqs {
WIIPROTO_REQ_NULL = 0x0,
WIIPROTO_REQ_LED = 0x11, WIIPROTO_REQ_LED = 0x11,
WIIPROTO_REQ_DRM = 0x12,
WIIPROTO_REQ_STATUS = 0x20,
WIIPROTO_REQ_RETURN = 0x22,
WIIPROTO_REQ_DRM_K = 0x30, WIIPROTO_REQ_DRM_K = 0x30,
}; };
@ -87,9 +94,6 @@ static __u16 wiiproto_keymap[] = {
BTN_MODE, /* WIIPROTO_KEY_HOME */ 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, static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
size_t count) size_t count)
{ {
@ -192,66 +196,96 @@ static void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
wiimote_queue(wdata, cmd, sizeof(cmd)); wiimote_queue(wdata, cmd, sizeof(cmd));
} }
#define wiifs_led_show_set(num) \ /*
static ssize_t wiifs_led_show_##num(struct device *dev, \ * Check what peripherals of the wiimote are currently
struct device_attribute *attr, char *buf) \ * active and select a proper DRM that supports all of
{ \ * the requested data inputs.
struct wiimote_data *wdata = dev_to_wii(dev); \ */
unsigned long flags; \ static __u8 select_drm(struct wiimote_data *wdata)
int state; \ {
\ return WIIPROTO_REQ_DRM_K;
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)
wiifs_led_show_set(1); static void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm)
wiifs_led_show_set(2); {
wiifs_led_show_set(3); __u8 cmd[3];
wiifs_led_show_set(4);
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, static int wiimote_input_event(struct input_dev *dev, unsigned int type,
unsigned int code, int value) unsigned int code, int value)
{
return 0;
}
static int wiimote_input_open(struct input_dev *dev)
{ {
struct wiimote_data *wdata = input_get_drvdata(dev); struct wiimote_data *wdata = input_get_drvdata(dev);
if (!atomic_read(&wdata->ready)) return hid_hw_open(wdata->hdev);
return -EBUSY; }
/* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
smp_rmb();
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) 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); 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 { struct wiiproto_handler {
__u8 id; __u8 id;
size_t size; size_t size;
@ -288,6 +342,8 @@ struct wiiproto_handler {
}; };
static struct wiiproto_handler handlers[] = { 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 = WIIPROTO_REQ_DRM_K, .size = 2, .func = handler_keys },
{ .id = 0 } { .id = 0 }
}; };
@ -300,11 +356,6 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
int i; int i;
unsigned long flags; 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) if (size < 1)
return -EINVAL; return -EINVAL;
@ -321,6 +372,58 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
return 0; 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) static struct wiimote_data *wiimote_create(struct hid_device *hdev)
{ {
struct wiimote_data *wdata; struct wiimote_data *wdata;
@ -341,6 +444,8 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
input_set_drvdata(wdata->input, wdata); input_set_drvdata(wdata->input, wdata);
wdata->input->event = wiimote_input_event; 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->dev.parent = &wdata->hdev->dev;
wdata->input->id.bustype = wdata->hdev->bus; wdata->input->id.bustype = wdata->hdev->bus;
wdata->input->id.vendor = wdata->hdev->vendor; 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) 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); kfree(wdata);
} }
@ -377,19 +488,6 @@ static int wiimote_hid_probe(struct hid_device *hdev,
return -ENOMEM; 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); ret = hid_parse(hdev);
if (ret) { if (ret) {
hid_err(hdev, "HID parse failed\n"); hid_err(hdev, "HID parse failed\n");
@ -408,9 +506,10 @@ static int wiimote_hid_probe(struct hid_device *hdev,
goto err_stop; goto err_stop;
} }
/* smp_wmb: Write wdata->xy first before wdata->ready is set to 1 */ ret = wiimote_leds_create(wdata);
smp_wmb(); if (ret)
atomic_set(&wdata->ready, 1); goto err_free;
hid_info(hdev, "New device registered\n"); hid_info(hdev, "New device registered\n");
/* by default set led1 after device initialization */ /* by default set led1 after device initialization */
@ -420,15 +519,15 @@ static int wiimote_hid_probe(struct hid_device *hdev,
return 0; return 0;
err_free:
wiimote_destroy(wdata);
return ret;
err_stop: err_stop:
hid_hw_stop(hdev); hid_hw_stop(hdev);
err: err:
input_free_device(wdata->input); input_free_device(wdata->input);
device_remove_file(&hdev->dev, &dev_attr_led1); kfree(wdata);
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);
return ret; return ret;
} }
@ -437,16 +536,6 @@ static void wiimote_hid_remove(struct hid_device *hdev)
struct wiimote_data *wdata = hid_get_drvdata(hdev); struct wiimote_data *wdata = hid_get_drvdata(hdev);
hid_info(hdev, "Device removed\n"); 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); wiimote_destroy(wdata);
} }

View File

@ -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_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, 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 } { 0, 0 }
}; };

View File

@ -114,7 +114,6 @@ struct i5k_amb_data {
void __iomem *amb_mmio; void __iomem *amb_mmio;
struct i5k_device_attribute *attrs; struct i5k_device_attribute *attrs;
unsigned int num_attrs; unsigned int num_attrs;
unsigned long chipset_id;
}; };
static ssize_t show_name(struct device *dev, struct device_attribute *devattr, 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; goto out;
} }
data->chipset_id = devid;
res = 0; res = 0;
out: out:
pci_dev_put(pcidev); pci_dev_put(pcidev);
@ -478,23 +475,13 @@ out:
return res; return res;
} }
static unsigned long i5k_channel_pci_id(struct i5k_amb_data *data, static struct {
unsigned long channel) unsigned long err;
{ unsigned long fbd0;
switch (data->chipset_id) { } chipset_ids[] __devinitdata = {
case PCI_DEVICE_ID_INTEL_5000_ERR: { PCI_DEVICE_ID_INTEL_5000_ERR, PCI_DEVICE_ID_INTEL_5000_FBD0 },
return PCI_DEVICE_ID_INTEL_5000_FBD0 + channel; { PCI_DEVICE_ID_INTEL_5400_ERR, PCI_DEVICE_ID_INTEL_5400_FBD0 },
case PCI_DEVICE_ID_INTEL_5400_ERR: { 0, 0 }
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
}; };
#ifdef MODULE #ifdef MODULE
@ -510,8 +497,7 @@ static int __devinit i5k_amb_probe(struct platform_device *pdev)
{ {
struct i5k_amb_data *data; struct i5k_amb_data *data;
struct resource *reso; struct resource *reso;
int i; int i, res;
int res = -ENODEV;
data = kzalloc(sizeof(*data), GFP_KERNEL); data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) if (!data)
@ -520,22 +506,22 @@ static int __devinit i5k_amb_probe(struct platform_device *pdev)
/* Figure out where the AMB registers live */ /* Figure out where the AMB registers live */
i = 0; i = 0;
do { 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++; i++;
} while (res && chipset_ids[i]); } while (chipset_ids[i].err);
if (res) if (res)
goto err; goto err;
/* Copy the DIMM presence map for the first two channels */ /* Copy the DIMM presence map for the first two channels */
res = i5k_channel_probe(&data->amb_present[0], res = i5k_channel_probe(&data->amb_present[0], chipset_ids[i].fbd0);
i5k_channel_pci_id(data, 0));
if (res) if (res)
goto err; goto err;
/* Copy the DIMM presence map for the optional second two channels */ /* Copy the DIMM presence map for the optional second two channels */
i5k_channel_probe(&data->amb_present[2], i5k_channel_probe(&data->amb_present[2], chipset_ids[i].fbd0 + 1);
i5k_channel_pci_id(data, 1));
/* Set up resource regions */ /* Set up resource regions */
reso = request_mem_region(data->amb_base, data->amb_len, DRVNAME); reso = request_mem_region(data->amb_base, data->amb_len, DRVNAME);

View File

@ -211,8 +211,7 @@ static int lookup_comp(struct ntc_data *data,
if (data->comp[mid].ohm <= ohm) { if (data->comp[mid].ohm <= ohm) {
*i_low = mid; *i_low = mid;
*i_high = mid - 1; *i_high = mid - 1;
} } else {
if (data->comp[mid].ohm > ohm) {
*i_low = mid + 1; *i_low = mid + 1;
*i_high = mid; *i_high = mid;
} }

View File

@ -146,6 +146,7 @@ struct i2c_nmk_client {
* @stop: stop condition * @stop: stop condition
* @xfer_complete: acknowledge completion for a I2C message * @xfer_complete: acknowledge completion for a I2C message
* @result: controller propogated result * @result: controller propogated result
* @regulator: pointer to i2c regulator
* @busy: Busy doing transfer * @busy: Busy doing transfer
*/ */
struct nmk_i2c_dev { 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, writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
dev->virtbase + I2C_IMSCR); dev->virtbase + I2C_IMSCR);
timeout = wait_for_completion_interruptible_timeout( timeout = wait_for_completion_timeout(
&dev->xfer_complete, dev->adap.timeout); &dev->xfer_complete, dev->adap.timeout);
if (timeout < 0) { if (timeout < 0) {
dev_err(&dev->pdev->dev, dev_err(&dev->pdev->dev,
"wait_for_completion_interruptible_timeout" "wait_for_completion_timeout"
"returned %d waiting for event\n", timeout); "returned %d waiting for event\n", timeout);
status = timeout; status = timeout;
} }
@ -504,12 +505,12 @@ static int write_i2c(struct nmk_i2c_dev *dev)
writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask, writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
dev->virtbase + I2C_IMSCR); dev->virtbase + I2C_IMSCR);
timeout = wait_for_completion_interruptible_timeout( timeout = wait_for_completion_timeout(
&dev->xfer_complete, dev->adap.timeout); &dev->xfer_complete, dev->adap.timeout);
if (timeout < 0) { if (timeout < 0) {
dev_err(&dev->pdev->dev, dev_err(&dev->pdev->dev,
"wait_for_completion_interruptible_timeout" "wait_for_completion_timeout "
"returned %d waiting for event\n", timeout); "returned %d waiting for event\n", timeout);
status = timeout; status = timeout;
} }

View File

@ -1139,41 +1139,12 @@ omap_i2c_remove(struct platform_device *pdev)
return 0; 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 = { static struct platform_driver omap_i2c_driver = {
.probe = omap_i2c_probe, .probe = omap_i2c_probe,
.remove = omap_i2c_remove, .remove = omap_i2c_remove,
.driver = { .driver = {
.name = "omap_i2c", .name = "omap_i2c",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pm = OMAP_I2C_PM_OPS,
}, },
}; };

View File

@ -139,7 +139,7 @@ struct analog_port {
#include <linux/i8253.h> #include <linux/i8253.h>
#define GET_TIME(x) do { if (cpu_has_tsc) rdtscl(x); else x = get_time_pit(); } while (0) #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") #define TIME_NAME (cpu_has_tsc?"TSC":"PIT")
static unsigned int get_time_pit(void) static unsigned int get_time_pit(void)
{ {

View File

@ -20,6 +20,7 @@
* flag. * flag.
*/ */
#include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/clk.h> #include <linux/clk.h>

View File

@ -702,7 +702,7 @@ err_iounmap:
err_free_mem_region: err_free_mem_region:
release_mem_region(res->start, resource_size(res)); release_mem_region(res->start, resource_size(res));
err_free_mem: err_free_mem:
input_free_device(kbc->idev); input_free_device(input_dev);
kfree(kbc); kfree(kbc);
return err; return err;

View File

@ -1,7 +1,7 @@
/* /*
* AD714X CapTouch Programmable Controller driver (I2C bus) * AD714X CapTouch Programmable Controller driver (I2C bus)
* *
* Copyright 2009 Analog Devices Inc. * Copyright 2009-2011 Analog Devices Inc.
* *
* Licensed under the GPL-2 or later. * Licensed under the GPL-2 or later.
*/ */
@ -27,54 +27,49 @@ static int ad714x_i2c_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume); static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume);
static int ad714x_i2c_write(struct device *dev, unsigned short reg, static int ad714x_i2c_write(struct ad714x_chip *chip,
unsigned short data) unsigned short reg, unsigned short data)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(chip->dev);
int ret = 0; int error;
u8 *_reg = (u8 *)&reg;
u8 *_data = (u8 *)&data;
u8 tx[4] = { chip->xfer_buf[0] = cpu_to_be16(reg);
_reg[1], chip->xfer_buf[1] = cpu_to_be16(data);
_reg[0],
_data[1],
_data[0]
};
ret = i2c_master_send(client, tx, 4); error = i2c_master_send(client, (u8 *)chip->xfer_buf,
if (ret < 0) 2 * sizeof(*chip->xfer_buf));
dev_err(&client->dev, "I2C write error\n"); if (unlikely(error < 0)) {
dev_err(&client->dev, "I2C write error: %d\n", error);
return ret; return error;
}
static int ad714x_i2c_read(struct device *dev, unsigned short reg,
unsigned short *data)
{
struct i2c_client *client = to_i2c_client(dev);
int ret = 0;
u8 *_reg = (u8 *)&reg;
u8 *_data = (u8 *)data;
u8 tx[2] = {
_reg[1],
_reg[0]
};
u8 rx[2];
ret = i2c_master_send(client, tx, 2);
if (ret >= 0)
ret = i2c_master_recv(client, rx, 2);
if (unlikely(ret < 0)) {
dev_err(&client->dev, "I2C read error\n");
} else {
_data[0] = rx[1];
_data[1] = rx[0];
} }
return ret; return 0;
}
static int ad714x_i2c_read(struct ad714x_chip *chip,
unsigned short reg, unsigned short *data, size_t len)
{
struct i2c_client *client = to_i2c_client(chip->dev);
int i;
int error;
chip->xfer_buf[0] = cpu_to_be16(reg);
error = i2c_master_send(client, (u8 *)chip->xfer_buf,
sizeof(*chip->xfer_buf));
if (error >= 0)
error = i2c_master_recv(client, (u8 *)chip->xfer_buf,
len * sizeof(*chip->xfer_buf));
if (unlikely(error < 0)) {
dev_err(&client->dev, "I2C read error: %d\n", error);
return error;
}
for (i = 0; i < len; i++)
data[i] = be16_to_cpu(chip->xfer_buf[i]);
return 0;
} }
static int __devinit ad714x_i2c_probe(struct i2c_client *client, static int __devinit ad714x_i2c_probe(struct i2c_client *client,

View File

@ -1,12 +1,12 @@
/* /*
* AD714X CapTouch Programmable Controller driver (SPI bus) * AD714X CapTouch Programmable Controller driver (SPI bus)
* *
* Copyright 2009 Analog Devices Inc. * Copyright 2009-2011 Analog Devices Inc.
* *
* Licensed under the GPL-2 or later. * Licensed under the GPL-2 or later.
*/ */
#include <linux/input.h> /* BUS_I2C */ #include <linux/input.h> /* BUS_SPI */
#include <linux/module.h> #include <linux/module.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/pm.h> #include <linux/pm.h>
@ -30,30 +30,68 @@ static int ad714x_spi_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume);
static int ad714x_spi_read(struct device *dev, unsigned short reg, static int ad714x_spi_read(struct ad714x_chip *chip,
unsigned short *data) unsigned short reg, unsigned short *data, size_t len)
{ {
struct spi_device *spi = to_spi_device(dev); struct spi_device *spi = to_spi_device(chip->dev);
unsigned short tx = AD714x_SPI_CMD_PREFIX | AD714x_SPI_READ | reg; struct spi_message message;
struct spi_transfer xfer[2];
int i;
int error;
return spi_write_then_read(spi, (u8 *)&tx, 2, (u8 *)data, 2); spi_message_init(&message);
memset(xfer, 0, sizeof(xfer));
chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX |
AD714x_SPI_READ | reg);
xfer[0].tx_buf = &chip->xfer_buf[0];
xfer[0].len = sizeof(chip->xfer_buf[0]);
spi_message_add_tail(&xfer[0], &message);
xfer[1].rx_buf = &chip->xfer_buf[1];
xfer[1].len = sizeof(chip->xfer_buf[1]) * len;
spi_message_add_tail(&xfer[1], &message);
error = spi_sync(spi, &message);
if (unlikely(error)) {
dev_err(chip->dev, "SPI read error: %d\n", error);
return error;
}
for (i = 0; i < len; i++)
data[i] = be16_to_cpu(chip->xfer_buf[i + 1]);
return 0;
} }
static int ad714x_spi_write(struct device *dev, unsigned short reg, static int ad714x_spi_write(struct ad714x_chip *chip,
unsigned short data) unsigned short reg, unsigned short data)
{ {
struct spi_device *spi = to_spi_device(dev); struct spi_device *spi = to_spi_device(chip->dev);
unsigned short tx[2] = { int error;
AD714x_SPI_CMD_PREFIX | reg,
data
};
return spi_write(spi, (u8 *)tx, 4); chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg);
chip->xfer_buf[1] = cpu_to_be16(data);
error = spi_write(spi, (u8 *)chip->xfer_buf,
2 * sizeof(*chip->xfer_buf));
if (unlikely(error)) {
dev_err(chip->dev, "SPI write error: %d\n", error);
return error;
}
return 0;
} }
static int __devinit ad714x_spi_probe(struct spi_device *spi) static int __devinit ad714x_spi_probe(struct spi_device *spi)
{ {
struct ad714x_chip *chip; struct ad714x_chip *chip;
int err;
spi->bits_per_word = 8;
err = spi_setup(spi);
if (err < 0)
return err;
chip = ad714x_probe(&spi->dev, BUS_SPI, spi->irq, chip = ad714x_probe(&spi->dev, BUS_SPI, spi->irq,
ad714x_spi_read, ad714x_spi_write); ad714x_spi_read, ad714x_spi_write);

View File

@ -1,7 +1,7 @@
/* /*
* AD714X CapTouch Programmable Controller driver supporting AD7142/3/7/8/7A * AD714X CapTouch Programmable Controller driver supporting AD7142/3/7/8/7A
* *
* Copyright 2009 Analog Devices Inc. * Copyright 2009-2011 Analog Devices Inc.
* *
* Licensed under the GPL-2 or later. * Licensed under the GPL-2 or later.
*/ */
@ -59,7 +59,6 @@
#define STAGE11_AMBIENT 0x27D #define STAGE11_AMBIENT 0x27D
#define PER_STAGE_REG_NUM 36 #define PER_STAGE_REG_NUM 36
#define STAGE_NUM 12
#define STAGE_CFGREG_NUM 8 #define STAGE_CFGREG_NUM 8
#define SYS_CFGREG_NUM 8 #define SYS_CFGREG_NUM 8
@ -124,27 +123,6 @@ struct ad714x_driver_data {
* information to integrate all things which will be private data * information to integrate all things which will be private data
* of spi/i2c device * of spi/i2c device
*/ */
struct ad714x_chip {
unsigned short h_state;
unsigned short l_state;
unsigned short c_state;
unsigned short adc_reg[STAGE_NUM];
unsigned short amb_reg[STAGE_NUM];
unsigned short sensor_val[STAGE_NUM];
struct ad714x_platform_data *hw;
struct ad714x_driver_data *sw;
int irq;
struct device *dev;
ad714x_read_t read;
ad714x_write_t write;
struct mutex mutex;
unsigned product;
unsigned version;
};
static void ad714x_use_com_int(struct ad714x_chip *ad714x, static void ad714x_use_com_int(struct ad714x_chip *ad714x,
int start_stage, int end_stage) int start_stage, int end_stage)
@ -154,13 +132,13 @@ static void ad714x_use_com_int(struct ad714x_chip *ad714x,
mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1); mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
data |= 1 << end_stage; data |= 1 << end_stage;
ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
data &= ~mask; data &= ~mask;
ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data); ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
} }
static void ad714x_use_thr_int(struct ad714x_chip *ad714x, static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
@ -171,13 +149,13 @@ static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1); mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
data &= ~(1 << end_stage); data &= ~(1 << end_stage);
ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
data |= mask; data |= mask;
ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data); ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
} }
static int ad714x_cal_highest_stage(struct ad714x_chip *ad714x, static int ad714x_cal_highest_stage(struct ad714x_chip *ad714x,
@ -273,15 +251,16 @@ static void ad714x_slider_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx]; struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
int i; int i;
for (i = hw->start_stage; i <= hw->end_stage; i++) { ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
ad714x->read(ad714x->dev, CDC_RESULT_S0 + i, &ad714x->adc_reg[hw->start_stage],
&ad714x->adc_reg[i]); hw->end_stage - hw->start_stage + 1);
ad714x->read(ad714x->dev,
STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
&ad714x->amb_reg[i]);
ad714x->sensor_val[i] = abs(ad714x->adc_reg[i] - for (i = hw->start_stage; i <= hw->end_stage; i++) {
ad714x->amb_reg[i]); ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
&ad714x->amb_reg[i], 1);
ad714x->sensor_val[i] =
abs(ad714x->adc_reg[i] - ad714x->amb_reg[i]);
} }
} }
@ -444,15 +423,16 @@ static void ad714x_wheel_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
int i; int i;
ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
&ad714x->adc_reg[hw->start_stage],
hw->end_stage - hw->start_stage + 1);
for (i = hw->start_stage; i <= hw->end_stage; i++) { for (i = hw->start_stage; i <= hw->end_stage; i++) {
ad714x->read(ad714x->dev, CDC_RESULT_S0 + i, ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
&ad714x->adc_reg[i]); &ad714x->amb_reg[i], 1);
ad714x->read(ad714x->dev,
STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
&ad714x->amb_reg[i]);
if (ad714x->adc_reg[i] > ad714x->amb_reg[i]) if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
ad714x->sensor_val[i] = ad714x->adc_reg[i] - ad714x->sensor_val[i] =
ad714x->amb_reg[i]; ad714x->adc_reg[i] - ad714x->amb_reg[i];
else else
ad714x->sensor_val[i] = 0; ad714x->sensor_val[i] = 0;
} }
@ -597,15 +577,16 @@ static void touchpad_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx]; struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
int i; int i;
ad714x->read(ad714x, CDC_RESULT_S0 + hw->x_start_stage,
&ad714x->adc_reg[hw->x_start_stage],
hw->x_end_stage - hw->x_start_stage + 1);
for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) { for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) {
ad714x->read(ad714x->dev, CDC_RESULT_S0 + i, ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
&ad714x->adc_reg[i]); &ad714x->amb_reg[i], 1);
ad714x->read(ad714x->dev,
STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
&ad714x->amb_reg[i]);
if (ad714x->adc_reg[i] > ad714x->amb_reg[i]) if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
ad714x->sensor_val[i] = ad714x->adc_reg[i] - ad714x->sensor_val[i] =
ad714x->amb_reg[i]; ad714x->adc_reg[i] - ad714x->amb_reg[i];
else else
ad714x->sensor_val[i] = 0; ad714x->sensor_val[i] = 0;
} }
@ -891,7 +872,7 @@ static int ad714x_hw_detect(struct ad714x_chip *ad714x)
{ {
unsigned short data; unsigned short data;
ad714x->read(ad714x->dev, AD714X_PARTID_REG, &data); ad714x->read(ad714x, AD714X_PARTID_REG, &data, 1);
switch (data & 0xFFF0) { switch (data & 0xFFF0) {
case AD7142_PARTID: case AD7142_PARTID:
ad714x->product = 0x7142; ad714x->product = 0x7142;
@ -940,23 +921,20 @@ static void ad714x_hw_init(struct ad714x_chip *ad714x)
for (i = 0; i < STAGE_NUM; i++) { for (i = 0; i < STAGE_NUM; i++) {
reg_base = AD714X_STAGECFG_REG + i * STAGE_CFGREG_NUM; reg_base = AD714X_STAGECFG_REG + i * STAGE_CFGREG_NUM;
for (j = 0; j < STAGE_CFGREG_NUM; j++) for (j = 0; j < STAGE_CFGREG_NUM; j++)
ad714x->write(ad714x->dev, reg_base + j, ad714x->write(ad714x, reg_base + j,
ad714x->hw->stage_cfg_reg[i][j]); ad714x->hw->stage_cfg_reg[i][j]);
} }
for (i = 0; i < SYS_CFGREG_NUM; i++) for (i = 0; i < SYS_CFGREG_NUM; i++)
ad714x->write(ad714x->dev, AD714X_SYSCFG_REG + i, ad714x->write(ad714x, AD714X_SYSCFG_REG + i,
ad714x->hw->sys_cfg_reg[i]); ad714x->hw->sys_cfg_reg[i]);
for (i = 0; i < SYS_CFGREG_NUM; i++) for (i = 0; i < SYS_CFGREG_NUM; i++)
ad714x->read(ad714x->dev, AD714X_SYSCFG_REG + i, ad714x->read(ad714x, AD714X_SYSCFG_REG + i, &data, 1);
&data);
ad714x->write(ad714x->dev, AD714X_STG_CAL_EN_REG, 0xFFF); ad714x->write(ad714x, AD714X_STG_CAL_EN_REG, 0xFFF);
/* clear all interrupts */ /* clear all interrupts */
ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data); ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data);
ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data);
} }
static irqreturn_t ad714x_interrupt_thread(int irq, void *data) static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
@ -966,9 +944,7 @@ static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
mutex_lock(&ad714x->mutex); mutex_lock(&ad714x->mutex);
ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &ad714x->l_state); ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &ad714x->h_state);
ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &ad714x->c_state);
for (i = 0; i < ad714x->hw->button_num; i++) for (i = 0; i < ad714x->hw->button_num; i++)
ad714x_button_state_machine(ad714x, i); ad714x_button_state_machine(ad714x, i);
@ -1245,7 +1221,7 @@ int ad714x_disable(struct ad714x_chip *ad714x)
mutex_lock(&ad714x->mutex); mutex_lock(&ad714x->mutex);
data = ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL] | 0x3; data = ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL] | 0x3;
ad714x->write(ad714x->dev, AD714X_PWR_CTRL, data); ad714x->write(ad714x, AD714X_PWR_CTRL, data);
mutex_unlock(&ad714x->mutex); mutex_unlock(&ad714x->mutex);
@ -1255,24 +1231,20 @@ EXPORT_SYMBOL(ad714x_disable);
int ad714x_enable(struct ad714x_chip *ad714x) int ad714x_enable(struct ad714x_chip *ad714x)
{ {
unsigned short data;
dev_dbg(ad714x->dev, "%s enter\n", __func__); dev_dbg(ad714x->dev, "%s enter\n", __func__);
mutex_lock(&ad714x->mutex); mutex_lock(&ad714x->mutex);
/* resume to non-shutdown mode */ /* resume to non-shutdown mode */
ad714x->write(ad714x->dev, AD714X_PWR_CTRL, ad714x->write(ad714x, AD714X_PWR_CTRL,
ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL]); ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL]);
/* make sure the interrupt output line is not low level after resume, /* make sure the interrupt output line is not low level after resume,
* otherwise we will get no chance to enter falling-edge irq again * otherwise we will get no chance to enter falling-edge irq again
*/ */
ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data); ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data);
ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data);
mutex_unlock(&ad714x->mutex); mutex_unlock(&ad714x->mutex);

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