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