Merge branch 'zImage_DTB_append' of git://git.linaro.org/people/nico/linux into devel-stable
This commit is contained in:
commit
1db3706b05
|
@ -1,13 +1,21 @@
|
||||||
00-INDEX
|
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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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/
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -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*
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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(¤t_thread_info()->flags,
|
if (cmpxchg(¤t_thread_info()->flags,
|
||||||
old, new) != old)
|
old, new) != old)
|
||||||
goto again;
|
goto again;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 ""
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
#include <asm/setup.h>
|
||||||
|
#include <libfdt.h>
|
||||||
|
|
||||||
|
static int node_offset(void *fdt, const char *node_path)
|
||||||
|
{
|
||||||
|
int offset = fdt_path_offset(fdt, node_path);
|
||||||
|
if (offset == -FDT_ERR_NOTFOUND)
|
||||||
|
offset = fdt_add_subnode(fdt, 0, node_path);
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int setprop(void *fdt, const char *node_path, const char *property,
|
||||||
|
uint32_t *val_array, int size)
|
||||||
|
{
|
||||||
|
int offset = node_offset(fdt, node_path);
|
||||||
|
if (offset < 0)
|
||||||
|
return offset;
|
||||||
|
return fdt_setprop(fdt, offset, property, val_array, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int setprop_string(void *fdt, const char *node_path,
|
||||||
|
const char *property, const char *string)
|
||||||
|
{
|
||||||
|
int offset = node_offset(fdt, node_path);
|
||||||
|
if (offset < 0)
|
||||||
|
return offset;
|
||||||
|
return fdt_setprop_string(fdt, offset, property, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int setprop_cell(void *fdt, const char *node_path,
|
||||||
|
const char *property, uint32_t val)
|
||||||
|
{
|
||||||
|
int offset = node_offset(fdt, node_path);
|
||||||
|
if (offset < 0)
|
||||||
|
return offset;
|
||||||
|
return fdt_setprop_cell(fdt, offset, property, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert and fold provided ATAGs into the provided FDT.
|
||||||
|
*
|
||||||
|
* REturn values:
|
||||||
|
* = 0 -> pretend success
|
||||||
|
* = 1 -> bad ATAG (may retry with another possible ATAG pointer)
|
||||||
|
* < 0 -> error from libfdt
|
||||||
|
*/
|
||||||
|
int atags_to_fdt(void *atag_list, void *fdt, int total_space)
|
||||||
|
{
|
||||||
|
struct tag *atag = atag_list;
|
||||||
|
uint32_t mem_reg_property[2 * NR_BANKS];
|
||||||
|
int memcount = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* make sure we've got an aligned pointer */
|
||||||
|
if ((u32)atag_list & 0x3)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* if we get a DTB here we're done already */
|
||||||
|
if (*(u32 *)atag_list == fdt32_to_cpu(FDT_MAGIC))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* validate the ATAG */
|
||||||
|
if (atag->hdr.tag != ATAG_CORE ||
|
||||||
|
(atag->hdr.size != tag_size(tag_core) &&
|
||||||
|
atag->hdr.size != 2))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* let's give it all the room it could need */
|
||||||
|
ret = fdt_open_into(fdt, fdt, total_space);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for_each_tag(atag, atag_list) {
|
||||||
|
if (atag->hdr.tag == ATAG_CMDLINE) {
|
||||||
|
setprop_string(fdt, "/chosen", "bootargs",
|
||||||
|
atag->u.cmdline.cmdline);
|
||||||
|
} else if (atag->hdr.tag == ATAG_MEM) {
|
||||||
|
if (memcount >= sizeof(mem_reg_property)/4)
|
||||||
|
continue;
|
||||||
|
mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start);
|
||||||
|
mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size);
|
||||||
|
} else if (atag->hdr.tag == ATAG_INITRD2) {
|
||||||
|
uint32_t initrd_start, initrd_size;
|
||||||
|
initrd_start = atag->u.initrd.start;
|
||||||
|
initrd_size = atag->u.initrd.size;
|
||||||
|
setprop_cell(fdt, "/chosen", "linux,initrd-start",
|
||||||
|
initrd_start);
|
||||||
|
setprop_cell(fdt, "/chosen", "linux,initrd-end",
|
||||||
|
initrd_start + initrd_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcount)
|
||||||
|
setprop(fdt, "/memory", "reg", mem_reg_property, 4*memcount);
|
||||||
|
|
||||||
|
return fdt_pack(fdt);
|
||||||
|
}
|
|
@ -216,6 +216,103 @@ restart: adr r0, LC0
|
||||||
mov r10, r6
|
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
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef _ARM_LIBFDT_ENV_H
|
||||||
|
#define _ARM_LIBFDT_ENV_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
|
#define fdt16_to_cpu(x) be16_to_cpu(x)
|
||||||
|
#define cpu_to_fdt16(x) cpu_to_be16(x)
|
||||||
|
#define fdt32_to_cpu(x) be32_to_cpu(x)
|
||||||
|
#define cpu_to_fdt32(x) cpu_to_be32(x)
|
||||||
|
#define fdt64_to_cpu(x) be64_to_cpu(x)
|
||||||
|
#define cpu_to_fdt64(x) cpu_to_be64(x)
|
||||||
|
|
||||||
|
#endif
|
|
@ -18,14 +18,9 @@
|
||||||
|
|
||||||
unsigned int __machine_arch_type;
|
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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* arch/arm/boot/compressed/string.c
|
||||||
|
*
|
||||||
|
* Small subset of simple string routines
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/string.h>
|
||||||
|
|
||||||
|
void *memcpy(void *__dest, __const void *__src, size_t __n)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
|
||||||
|
|
||||||
|
for (i = __n >> 3; i > 0; i--) {
|
||||||
|
*d++ = *s++;
|
||||||
|
*d++ = *s++;
|
||||||
|
*d++ = *s++;
|
||||||
|
*d++ = *s++;
|
||||||
|
*d++ = *s++;
|
||||||
|
*d++ = *s++;
|
||||||
|
*d++ = *s++;
|
||||||
|
*d++ = *s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__n & 1 << 2) {
|
||||||
|
*d++ = *s++;
|
||||||
|
*d++ = *s++;
|
||||||
|
*d++ = *s++;
|
||||||
|
*d++ = *s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__n & 1 << 1) {
|
||||||
|
*d++ = *s++;
|
||||||
|
*d++ = *s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__n & 1)
|
||||||
|
*d++ = *s++;
|
||||||
|
|
||||||
|
return __dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *memmove(void *__dest, __const void *__src, size_t count)
|
||||||
|
{
|
||||||
|
unsigned char *d = __dest;
|
||||||
|
const unsigned char *s = __src;
|
||||||
|
|
||||||
|
if (__dest == __src)
|
||||||
|
return __dest;
|
||||||
|
|
||||||
|
if (__dest < __src)
|
||||||
|
return memcpy(__dest, __src, count);
|
||||||
|
|
||||||
|
while (count--)
|
||||||
|
d[count] = s[count];
|
||||||
|
return __dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t strlen(const char *s)
|
||||||
|
{
|
||||||
|
const char *sc = s;
|
||||||
|
|
||||||
|
while (*sc != '\0')
|
||||||
|
sc++;
|
||||||
|
return sc - s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int memcmp(const void *cs, const void *ct, size_t count)
|
||||||
|
{
|
||||||
|
const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
while (su1 < end) {
|
||||||
|
res = *su1++ - *su2++;
|
||||||
|
if (res)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int strcmp(const char *cs, const char *ct)
|
||||||
|
{
|
||||||
|
unsigned char c1, c2;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
c1 = *cs++;
|
||||||
|
c2 = *ct++;
|
||||||
|
res = c1 - c2;
|
||||||
|
if (res)
|
||||||
|
break;
|
||||||
|
} while (c1);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *memchr(const void *s, int c, size_t count)
|
||||||
|
{
|
||||||
|
const unsigned char *p = s;
|
||||||
|
|
||||||
|
while (count--)
|
||||||
|
if ((unsigned char)c == *p++)
|
||||||
|
return (void *)(p - 1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *strchr(const char *s, int c)
|
||||||
|
{
|
||||||
|
while (*s != (char)c)
|
||||||
|
if (*s++ == '\0')
|
||||||
|
return NULL;
|
||||||
|
return (char *)s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef memset
|
||||||
|
|
||||||
|
void *memset(void *s, int c, size_t count)
|
||||||
|
{
|
||||||
|
char *xs = s;
|
||||||
|
while (count--)
|
||||||
|
*xs++ = c;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __memzero(void *s, size_t count)
|
||||||
|
{
|
||||||
|
memset(s, 0, count);
|
||||||
|
}
|
|
@ -51,6 +51,10 @@ SECTIONS
|
||||||
_got_start = .;
|
_got_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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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]),
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef _ASM_SERIAL_H
|
||||||
|
#define _ASM_SERIAL_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This assumes you have a 1.8432 MHz clock for your UART.
|
||||||
|
*/
|
||||||
|
#define BASE_BAUD (1843200 / 16)
|
||||||
|
|
||||||
|
#endif /* _ASM_SERIAL_H */
|
|
@ -1358,7 +1358,7 @@ sys_call_table:
|
||||||
.long sys_ni_syscall /* for vm86 */
|
.long sys_ni_syscall /* 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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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; \
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 = ¤t_thread_info()->reg_window[wsaved - 1];
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
|
||||||
|
err |= __put_user(rp->ins[6], &sf->ss.fp);
|
||||||
|
err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
|
||||||
|
}
|
||||||
if (err)
|
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 = ¤t_thread_info()->reg_window[wsaved - 1];
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
|
||||||
|
err |= __put_user(rp->ins[6], &sf->ss.fp);
|
||||||
|
err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
|
||||||
|
}
|
||||||
if (err)
|
if (err)
|
||||||
goto sigsegv;
|
goto sigsegv;
|
||||||
|
|
||||||
|
|
|
@ -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(¤t->thread.float_regs[0], &fpu->si_float_regs[0],
|
|
||||||
(sizeof(unsigned long) * 32));
|
|
||||||
err |= __get_user(current->thread.fsr, &fpu->si_fsr);
|
|
||||||
err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
|
|
||||||
if (current->thread.fpqdepth != 0)
|
|
||||||
err |= __copy_from_user(¤t->thread.fpqueue[0],
|
|
||||||
&fpu->si_fpqueue[0],
|
|
||||||
((sizeof(unsigned long) +
|
|
||||||
(sizeof(unsigned long *)))*16));
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage void do_sigreturn(struct pt_regs *regs)
|
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(¤t->sighand->siglock);
|
spin_lock_irq(¤t->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(¤t->thread.float_regs[0], ¤t->thread.fsr,
|
|
||||||
¤t->thread.fpqueue[0], ¤t->thread.fpqdepth);
|
|
||||||
regs->psr &= ~(PSR_EF);
|
|
||||||
clear_tsk_thread_flag(current, TIF_USEDFPU);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (current == last_task_used_math) {
|
|
||||||
put_psr(get_psr() | PSR_EF);
|
|
||||||
fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr,
|
|
||||||
¤t->thread.fpqueue[0], ¤t->thread.fpqdepth);
|
|
||||||
last_task_used_math = NULL;
|
|
||||||
regs->psr &= ~(PSR_EF);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
err |= __copy_to_user(&fpu->si_float_regs[0],
|
|
||||||
¤t->thread.float_regs[0],
|
|
||||||
(sizeof(unsigned long) * 32));
|
|
||||||
err |= __put_user(current->thread.fsr, &fpu->si_fsr);
|
|
||||||
err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
|
|
||||||
if (current->thread.fpqdepth != 0)
|
|
||||||
err |= __copy_to_user(&fpu->si_fpqueue[0],
|
|
||||||
¤t->thread.fpqueue[0],
|
|
||||||
((sizeof(unsigned long) +
|
|
||||||
(sizeof(unsigned long *)))*16));
|
|
||||||
clear_used_math();
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
|
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 = ¤t_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 = ¤t_thread_info()->reg_window[wsaved - 1];
|
||||||
|
err |= __copy_to_user(sf, rp, sizeof(struct reg_window32));
|
||||||
|
}
|
||||||
|
|
||||||
err |= copy_siginfo_to_user(&sf->info, info);
|
err |= copy_siginfo_to_user(&sf->info, info);
|
||||||
|
|
||||||
|
|
|
@ -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 = ¤t_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 {
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef _SIGUTIL_H
|
||||||
|
#define _SIGUTIL_H
|
||||||
|
|
||||||
|
int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu);
|
||||||
|
int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu);
|
||||||
|
int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin);
|
||||||
|
int restore_rwin_state(__siginfo_rwin_t __user *rp);
|
||||||
|
|
||||||
|
#endif /* _SIGUTIL_H */
|
|
@ -0,0 +1,120 @@
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/thread_info.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
|
#include <asm/sigcontext.h>
|
||||||
|
#include <asm/fpumacro.h>
|
||||||
|
#include <asm/ptrace.h>
|
||||||
|
|
||||||
|
#include "sigutil.h"
|
||||||
|
|
||||||
|
int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
if (test_tsk_thread_flag(current, TIF_USEDFPU)) {
|
||||||
|
put_psr(get_psr() | PSR_EF);
|
||||||
|
fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr,
|
||||||
|
¤t->thread.fpqueue[0], ¤t->thread.fpqdepth);
|
||||||
|
regs->psr &= ~(PSR_EF);
|
||||||
|
clear_tsk_thread_flag(current, TIF_USEDFPU);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (current == last_task_used_math) {
|
||||||
|
put_psr(get_psr() | PSR_EF);
|
||||||
|
fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr,
|
||||||
|
¤t->thread.fpqueue[0], ¤t->thread.fpqdepth);
|
||||||
|
last_task_used_math = NULL;
|
||||||
|
regs->psr &= ~(PSR_EF);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
err |= __copy_to_user(&fpu->si_float_regs[0],
|
||||||
|
¤t->thread.float_regs[0],
|
||||||
|
(sizeof(unsigned long) * 32));
|
||||||
|
err |= __put_user(current->thread.fsr, &fpu->si_fsr);
|
||||||
|
err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
|
||||||
|
if (current->thread.fpqdepth != 0)
|
||||||
|
err |= __copy_to_user(&fpu->si_fpqueue[0],
|
||||||
|
¤t->thread.fpqueue[0],
|
||||||
|
((sizeof(unsigned long) +
|
||||||
|
(sizeof(unsigned long *)))*16));
|
||||||
|
clear_used_math();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
if (test_tsk_thread_flag(current, TIF_USEDFPU))
|
||||||
|
regs->psr &= ~PSR_EF;
|
||||||
|
#else
|
||||||
|
if (current == last_task_used_math) {
|
||||||
|
last_task_used_math = NULL;
|
||||||
|
regs->psr &= ~PSR_EF;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
set_used_math();
|
||||||
|
clear_tsk_thread_flag(current, TIF_USEDFPU);
|
||||||
|
|
||||||
|
if (!access_ok(VERIFY_READ, fpu, sizeof(*fpu)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
err = __copy_from_user(¤t->thread.float_regs[0], &fpu->si_float_regs[0],
|
||||||
|
(sizeof(unsigned long) * 32));
|
||||||
|
err |= __get_user(current->thread.fsr, &fpu->si_fsr);
|
||||||
|
err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
|
||||||
|
if (current->thread.fpqdepth != 0)
|
||||||
|
err |= __copy_from_user(¤t->thread.fpqueue[0],
|
||||||
|
&fpu->si_fpqueue[0],
|
||||||
|
((sizeof(unsigned long) +
|
||||||
|
(sizeof(unsigned long *)))*16));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin)
|
||||||
|
{
|
||||||
|
int i, err = __put_user(wsaved, &rwin->wsaved);
|
||||||
|
|
||||||
|
for (i = 0; i < wsaved; i++) {
|
||||||
|
struct reg_window32 *rp;
|
||||||
|
unsigned long fp;
|
||||||
|
|
||||||
|
rp = ¤t_thread_info()->reg_window[i];
|
||||||
|
fp = current_thread_info()->rwbuf_stkptrs[i];
|
||||||
|
err |= copy_to_user(&rwin->reg_window[i], rp,
|
||||||
|
sizeof(struct reg_window32));
|
||||||
|
err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int restore_rwin_state(__siginfo_rwin_t __user *rp)
|
||||||
|
{
|
||||||
|
struct thread_info *t = current_thread_info();
|
||||||
|
int i, wsaved, err;
|
||||||
|
|
||||||
|
__get_user(wsaved, &rp->wsaved);
|
||||||
|
if (wsaved > NSWINS)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
for (i = 0; i < wsaved; i++) {
|
||||||
|
err |= copy_from_user(&t->reg_window[i],
|
||||||
|
&rp->reg_window[i],
|
||||||
|
sizeof(struct reg_window32));
|
||||||
|
err |= __get_user(t->rwbuf_stkptrs[i],
|
||||||
|
&rp->rwbuf_stkptrs[i]);
|
||||||
|
}
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
t->w_saved = wsaved;
|
||||||
|
synchronize_user_stack();
|
||||||
|
if (t->w_saved)
|
||||||
|
return -EFAULT;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/thread_info.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
|
#include <asm/sigcontext.h>
|
||||||
|
#include <asm/fpumacro.h>
|
||||||
|
#include <asm/ptrace.h>
|
||||||
|
|
||||||
|
#include "sigutil.h"
|
||||||
|
|
||||||
|
int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||||
|
{
|
||||||
|
unsigned long *fpregs = current_thread_info()->fpregs;
|
||||||
|
unsigned long fprs;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
fprs = current_thread_info()->fpsaved[0];
|
||||||
|
if (fprs & FPRS_DL)
|
||||||
|
err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
|
||||||
|
(sizeof(unsigned int) * 32));
|
||||||
|
if (fprs & FPRS_DU)
|
||||||
|
err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
|
||||||
|
(sizeof(unsigned int) * 32));
|
||||||
|
err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
|
||||||
|
err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
|
||||||
|
err |= __put_user(fprs, &fpu->si_fprs);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||||
|
{
|
||||||
|
unsigned long *fpregs = current_thread_info()->fpregs;
|
||||||
|
unsigned long fprs;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = __get_user(fprs, &fpu->si_fprs);
|
||||||
|
fprs_write(0);
|
||||||
|
regs->tstate &= ~TSTATE_PEF;
|
||||||
|
if (fprs & FPRS_DL)
|
||||||
|
err |= copy_from_user(fpregs, &fpu->si_float_regs[0],
|
||||||
|
(sizeof(unsigned int) * 32));
|
||||||
|
if (fprs & FPRS_DU)
|
||||||
|
err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32],
|
||||||
|
(sizeof(unsigned int) * 32));
|
||||||
|
err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
|
||||||
|
err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
|
||||||
|
current_thread_info()->fpsaved[0] |= fprs;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin)
|
||||||
|
{
|
||||||
|
int i, err = __put_user(wsaved, &rwin->wsaved);
|
||||||
|
|
||||||
|
for (i = 0; i < wsaved; i++) {
|
||||||
|
struct reg_window *rp = ¤t_thread_info()->reg_window[i];
|
||||||
|
unsigned long fp = current_thread_info()->rwbuf_stkptrs[i];
|
||||||
|
|
||||||
|
err |= copy_to_user(&rwin->reg_window[i], rp,
|
||||||
|
sizeof(struct reg_window));
|
||||||
|
err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int restore_rwin_state(__siginfo_rwin_t __user *rp)
|
||||||
|
{
|
||||||
|
struct thread_info *t = current_thread_info();
|
||||||
|
int i, wsaved, err;
|
||||||
|
|
||||||
|
__get_user(wsaved, &rp->wsaved);
|
||||||
|
if (wsaved > NSWINS)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
for (i = 0; i < wsaved; i++) {
|
||||||
|
err |= copy_from_user(&t->reg_window[i],
|
||||||
|
&rp->reg_window[i],
|
||||||
|
sizeof(struct reg_window));
|
||||||
|
err |= __get_user(t->rwbuf_stkptrs[i],
|
||||||
|
&rp->rwbuf_stkptrs[i]);
|
||||||
|
}
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
set_thread_wsaved(wsaved);
|
||||||
|
synchronize_user_stack();
|
||||||
|
if (get_thread_wsaved())
|
||||||
|
return -EFAULT;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -81,7 +81,6 @@ SIGN2(sys32_fadvise64, compat_sys_fadvise64, %o0, %o4)
|
||||||
SIGN2(sys32_fadvise64_64, compat_sys_fadvise64_64, %o0, %o5)
|
SIGN2(sys32_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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) |
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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) },
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 *)®
|
|
||||||
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 *)®
|
|
||||||
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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
Loading…
Reference in New Issue