Merge branch 'sa11x0-mcp-fixes' into fixes
This commit is contained in:
Коммит
9a95b9e741
4
Makefile
4
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 2
|
||||
PATCHLEVEL = 3
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION =
|
||||
EXTRAVERSION = -rc1
|
||||
NAME = Saber-toothed Squirrel
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -202,7 +202,6 @@ static struct irda_platform_data assabet_irda_data = {
|
|||
static struct mcp_plat_data assabet_mcp_data = {
|
||||
.mccr0 = MCCR0_ADM,
|
||||
.sclk_rate = 11981000,
|
||||
.codec = "ucb1x00",
|
||||
};
|
||||
|
||||
static void __init assabet_init(void)
|
||||
|
@ -253,17 +252,6 @@ static void __init assabet_init(void)
|
|||
sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
|
||||
ARRAY_SIZE(assabet_flash_resources));
|
||||
sa11x0_register_irda(&assabet_irda_data);
|
||||
|
||||
/*
|
||||
* Setup the PPC unit correctly.
|
||||
*/
|
||||
PPDR &= ~PPC_RXD4;
|
||||
PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
|
||||
PSDR |= PPC_RXD4;
|
||||
PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
|
||||
ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
|
||||
sa11x0_register_mcp(&assabet_mcp_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -124,23 +124,12 @@ static void __init cerf_map_io(void)
|
|||
static struct mcp_plat_data cerf_mcp_data = {
|
||||
.mccr0 = MCCR0_ADM,
|
||||
.sclk_rate = 11981000,
|
||||
.codec = "ucb1x00",
|
||||
};
|
||||
|
||||
static void __init cerf_init(void)
|
||||
{
|
||||
platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
|
||||
sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
|
||||
|
||||
/*
|
||||
* Setup the PPC unit correctly.
|
||||
*/
|
||||
PPDR &= ~PPC_RXD4;
|
||||
PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
|
||||
PSDR |= PPC_RXD4;
|
||||
PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
|
||||
sa11x0_register_mcp(&cerf_mcp_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <linux/timer.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/pda_power.h>
|
||||
#include <linux/mfd/ucb1x00.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
@ -86,15 +85,10 @@ static struct scoop_pcmcia_config collie_pcmcia_config = {
|
|||
.num_devs = 1,
|
||||
};
|
||||
|
||||
static struct ucb1x00_plat_data collie_ucb1x00_data = {
|
||||
.gpio_base = COLLIE_TC35143_GPIO_BASE,
|
||||
};
|
||||
|
||||
static struct mcp_plat_data collie_mcp_data = {
|
||||
.mccr0 = MCCR0_ADM | MCCR0_ExtClk,
|
||||
.sclk_rate = 9216000,
|
||||
.codec = "ucb1x00",
|
||||
.codec_pdata = &collie_ucb1x00_data,
|
||||
.gpio_base = COLLIE_TC35143_GPIO_BASE,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -356,16 +350,6 @@ static void __init collie_init(void)
|
|||
|
||||
sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
|
||||
ARRAY_SIZE(collie_flash_resources));
|
||||
|
||||
/*
|
||||
* Setup the PPC unit correctly.
|
||||
*/
|
||||
PPDR &= ~PPC_RXD4;
|
||||
PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
|
||||
PSDR |= PPC_RXD4;
|
||||
PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
|
||||
sa11x0_register_mcp(&collie_mcp_data);
|
||||
|
||||
sharpsl_save_param();
|
||||
|
|
|
@ -217,15 +217,10 @@ static struct platform_device sa11x0uart3_device = {
|
|||
static struct resource sa11x0mcp_resources[] = {
|
||||
[0] = {
|
||||
.start = __PREG(Ser4MCCR0),
|
||||
.end = __PREG(Ser4MCCR0) + 0x1C - 1,
|
||||
.end = __PREG(Ser4MCCR0) + 0xffff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = __PREG(Ser4MCCR1),
|
||||
.end = __PREG(Ser4MCCR1) + 0x4 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_Ser4MCP,
|
||||
.end = IRQ_Ser4MCP,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
|
|
|
@ -17,8 +17,6 @@ struct mcp_plat_data {
|
|||
u32 mccr1;
|
||||
unsigned int sclk_rate;
|
||||
int gpio_base;
|
||||
const char *codec;
|
||||
void *codec_pdata;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,20 +24,10 @@
|
|||
static struct mcp_plat_data lart_mcp_data = {
|
||||
.mccr0 = MCCR0_ADM,
|
||||
.sclk_rate = 11981000,
|
||||
.codec = "ucb1x00",
|
||||
};
|
||||
|
||||
static void __init lart_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup the PPC unit correctly.
|
||||
*/
|
||||
PPDR &= ~PPC_RXD4;
|
||||
PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
|
||||
PSDR |= PPC_RXD4;
|
||||
PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
|
||||
sa11x0_register_mcp(&lart_mcp_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,22 +55,11 @@ static struct resource shannon_flash_resource = {
|
|||
static struct mcp_plat_data shannon_mcp_data = {
|
||||
.mccr0 = MCCR0_ADM,
|
||||
.sclk_rate = 11981000,
|
||||
.codec = "ucb1x00",
|
||||
};
|
||||
|
||||
static void __init shannon_init(void)
|
||||
{
|
||||
sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
|
||||
|
||||
/*
|
||||
* Setup the PPC unit correctly.
|
||||
*/
|
||||
PPDR &= ~PPC_RXD4;
|
||||
PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
|
||||
PSDR |= PPC_RXD4;
|
||||
PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
|
||||
sa11x0_register_mcp(&shannon_mcp_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/mfd/ucb1x00.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <mach/hardware.h>
|
||||
|
@ -188,15 +187,10 @@ static struct resource simpad_flash_resources [] = {
|
|||
}
|
||||
};
|
||||
|
||||
static struct ucb1x00_plat_data simpad_ucb1x00_data = {
|
||||
.gpio_base = SIMPAD_UCB1X00_GPIO_BASE,
|
||||
};
|
||||
|
||||
static struct mcp_plat_data simpad_mcp_data = {
|
||||
.mccr0 = MCCR0_ADM,
|
||||
.sclk_rate = 11981000,
|
||||
.codec = "ucb1300",
|
||||
.codec_pdata = &simpad_ucb1x00_data,
|
||||
.gpio_base = SIMPAD_UCB1X00_GPIO_BASE,
|
||||
};
|
||||
|
||||
|
||||
|
@ -384,16 +378,6 @@ static int __init simpad_init(void)
|
|||
|
||||
sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
|
||||
ARRAY_SIZE(simpad_flash_resources));
|
||||
|
||||
/*
|
||||
* Setup the PPC unit correctly.
|
||||
*/
|
||||
PPDR &= ~PPC_RXD4;
|
||||
PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
|
||||
PSDR |= PPC_RXD4;
|
||||
PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
|
||||
sa11x0_register_mcp(&simpad_mcp_data);
|
||||
|
||||
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
boot/compressed/vmlinux
|
||||
tools/test_get_len
|
||||
tools/insn_sanity
|
||||
|
||||
|
|
|
@ -125,16 +125,6 @@ config HAVE_LATENCYTOP_SUPPORT
|
|||
config MMU
|
||||
def_bool y
|
||||
|
||||
config ZONE_DMA
|
||||
bool "DMA memory allocation support" if EXPERT
|
||||
default y
|
||||
help
|
||||
DMA memory allocation support allows devices with less than 32-bit
|
||||
addressing to allocate within the first 16MB of address space.
|
||||
Disable if no such devices will be used.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config SBUS
|
||||
bool
|
||||
|
||||
|
@ -255,6 +245,16 @@ source "kernel/Kconfig.freezer"
|
|||
|
||||
menu "Processor type and features"
|
||||
|
||||
config ZONE_DMA
|
||||
bool "DMA memory allocation support" if EXPERT
|
||||
default y
|
||||
help
|
||||
DMA memory allocation support allows devices with less than 32-bit
|
||||
addressing to allocate within the first 16MB of address space.
|
||||
Disable if no such devices will be used.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
source "kernel/time/Kconfig"
|
||||
|
||||
config SMP
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
# include <asm/unistd_32.h>
|
||||
# define __ARCH_WANT_IPC_PARSE_VERSION
|
||||
# define __ARCH_WANT_STAT64
|
||||
# define __ARCH_WANT_SYS_IPC
|
||||
# define __ARCH_WANT_SYS_OLD_MMAP
|
||||
# define __ARCH_WANT_SYS_OLD_SELECT
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
* UV2: Bit 19 selects between
|
||||
* (0): 10 microsecond timebase and
|
||||
* (1): 80 microseconds
|
||||
* we're using 655us, similar to UV1: 65 units of 10us
|
||||
* we're using 560us, similar to UV1: 65 units of 10us
|
||||
*/
|
||||
#define UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD (9UL)
|
||||
#define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (15UL)
|
||||
|
@ -167,6 +167,7 @@
|
|||
#define FLUSH_RETRY_TIMEOUT 2
|
||||
#define FLUSH_GIVEUP 3
|
||||
#define FLUSH_COMPLETE 4
|
||||
#define FLUSH_RETRY_BUSYBUG 5
|
||||
|
||||
/*
|
||||
* tuning the action when the numalink network is extremely delayed
|
||||
|
@ -235,10 +236,10 @@ struct bau_msg_payload {
|
|||
|
||||
|
||||
/*
|
||||
* Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor)
|
||||
* UV1 Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor)
|
||||
* see table 4.2.3.0.1 in broacast_assist spec.
|
||||
*/
|
||||
struct bau_msg_header {
|
||||
struct uv1_bau_msg_header {
|
||||
unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */
|
||||
/* bits 5:0 */
|
||||
unsigned int base_dest_nasid:15; /* nasid of the first bit */
|
||||
|
@ -317,20 +318,88 @@ struct bau_msg_header {
|
|||
/* bits 127:107 */
|
||||
};
|
||||
|
||||
/*
|
||||
* UV2 Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor)
|
||||
* see figure 9-2 of harp_sys.pdf
|
||||
*/
|
||||
struct uv2_bau_msg_header {
|
||||
unsigned int base_dest_nasid:15; /* nasid of the first bit */
|
||||
/* bits 14:0 */ /* in uvhub map */
|
||||
unsigned int dest_subnodeid:5; /* must be 0x10, for the LB */
|
||||
/* bits 19:15 */
|
||||
unsigned int rsvd_1:1; /* must be zero */
|
||||
/* bit 20 */
|
||||
/* Address bits 59:21 */
|
||||
/* bits 25:2 of address (44:21) are payload */
|
||||
/* these next 24 bits become bytes 12-14 of msg */
|
||||
/* bits 28:21 land in byte 12 */
|
||||
unsigned int replied_to:1; /* sent as 0 by the source to
|
||||
byte 12 */
|
||||
/* bit 21 */
|
||||
unsigned int msg_type:3; /* software type of the
|
||||
message */
|
||||
/* bits 24:22 */
|
||||
unsigned int canceled:1; /* message canceled, resource
|
||||
is to be freed*/
|
||||
/* bit 25 */
|
||||
unsigned int payload_1:3; /* not currently used */
|
||||
/* bits 28:26 */
|
||||
|
||||
/* bits 36:29 land in byte 13 */
|
||||
unsigned int payload_2a:3; /* not currently used */
|
||||
unsigned int payload_2b:5; /* not currently used */
|
||||
/* bits 36:29 */
|
||||
|
||||
/* bits 44:37 land in byte 14 */
|
||||
unsigned int payload_3:8; /* not currently used */
|
||||
/* bits 44:37 */
|
||||
|
||||
unsigned int rsvd_2:7; /* reserved */
|
||||
/* bits 51:45 */
|
||||
unsigned int swack_flag:1; /* software acknowledge flag */
|
||||
/* bit 52 */
|
||||
unsigned int rsvd_3a:3; /* must be zero */
|
||||
unsigned int rsvd_3b:8; /* must be zero */
|
||||
unsigned int rsvd_3c:8; /* must be zero */
|
||||
unsigned int rsvd_3d:3; /* must be zero */
|
||||
/* bits 74:53 */
|
||||
unsigned int fairness:3; /* usually zero */
|
||||
/* bits 77:75 */
|
||||
|
||||
unsigned int sequence:16; /* message sequence number */
|
||||
/* bits 93:78 Suppl_A */
|
||||
unsigned int chaining:1; /* next descriptor is part of
|
||||
this activation*/
|
||||
/* bit 94 */
|
||||
unsigned int multilevel:1; /* multi-level multicast
|
||||
format */
|
||||
/* bit 95 */
|
||||
unsigned int rsvd_4:24; /* ordered / source node /
|
||||
source subnode / aging
|
||||
must be zero */
|
||||
/* bits 119:96 */
|
||||
unsigned int command:8; /* message type */
|
||||
/* bits 127:120 */
|
||||
};
|
||||
|
||||
/*
|
||||
* The activation descriptor:
|
||||
* The format of the message to send, plus all accompanying control
|
||||
* Should be 64 bytes
|
||||
*/
|
||||
struct bau_desc {
|
||||
struct pnmask distribution;
|
||||
struct pnmask distribution;
|
||||
/*
|
||||
* message template, consisting of header and payload:
|
||||
*/
|
||||
struct bau_msg_header header;
|
||||
struct bau_msg_payload payload;
|
||||
union bau_msg_header {
|
||||
struct uv1_bau_msg_header uv1_hdr;
|
||||
struct uv2_bau_msg_header uv2_hdr;
|
||||
} header;
|
||||
|
||||
struct bau_msg_payload payload;
|
||||
};
|
||||
/*
|
||||
/* UV1:
|
||||
* -payload-- ---------header------
|
||||
* bytes 0-11 bits 41-56 bits 58-81
|
||||
* A B (2) C (3)
|
||||
|
@ -340,6 +409,16 @@ struct bau_desc {
|
|||
* bytes 0-11 bytes 12-14 bytes 16-17 (byte 15 filled in by hw as vector)
|
||||
* ------------payload queue-----------
|
||||
*/
|
||||
/* UV2:
|
||||
* -payload-- ---------header------
|
||||
* bytes 0-11 bits 70-78 bits 21-44
|
||||
* A B (2) C (3)
|
||||
*
|
||||
* A/B/C are moved to:
|
||||
* A C B
|
||||
* bytes 0-11 bytes 12-14 bytes 16-17 (byte 15 filled in by hw as vector)
|
||||
* ------------payload queue-----------
|
||||
*/
|
||||
|
||||
/*
|
||||
* The payload queue on the destination side is an array of these.
|
||||
|
@ -385,7 +464,6 @@ struct bau_pq_entry {
|
|||
struct msg_desc {
|
||||
struct bau_pq_entry *msg;
|
||||
int msg_slot;
|
||||
int swack_slot;
|
||||
struct bau_pq_entry *queue_first;
|
||||
struct bau_pq_entry *queue_last;
|
||||
};
|
||||
|
@ -405,6 +483,7 @@ struct ptc_stats {
|
|||
requests */
|
||||
unsigned long s_stimeout; /* source side timeouts */
|
||||
unsigned long s_dtimeout; /* destination side timeouts */
|
||||
unsigned long s_strongnacks; /* number of strong nack's */
|
||||
unsigned long s_time; /* time spent in sending side */
|
||||
unsigned long s_retriesok; /* successful retries */
|
||||
unsigned long s_ntargcpu; /* total number of cpu's
|
||||
|
@ -439,6 +518,9 @@ struct ptc_stats {
|
|||
unsigned long s_retry_messages; /* retry broadcasts */
|
||||
unsigned long s_bau_reenabled; /* for bau enable/disable */
|
||||
unsigned long s_bau_disabled; /* for bau enable/disable */
|
||||
unsigned long s_uv2_wars; /* uv2 workaround, perm. busy */
|
||||
unsigned long s_uv2_wars_hw; /* uv2 workaround, hiwater */
|
||||
unsigned long s_uv2_war_waits; /* uv2 workaround, long waits */
|
||||
/* destination statistics */
|
||||
unsigned long d_alltlb; /* times all tlb's on this
|
||||
cpu were flushed */
|
||||
|
@ -511,9 +593,12 @@ struct bau_control {
|
|||
short osnode;
|
||||
short uvhub_cpu;
|
||||
short uvhub;
|
||||
short uvhub_version;
|
||||
short cpus_in_socket;
|
||||
short cpus_in_uvhub;
|
||||
short partition_base_pnode;
|
||||
short using_desc; /* an index, like uvhub_cpu */
|
||||
unsigned int inuse_map;
|
||||
unsigned short message_number;
|
||||
unsigned short uvhub_quiesce;
|
||||
short socket_acknowledge_count[DEST_Q_SIZE];
|
||||
|
@ -531,6 +616,7 @@ struct bau_control {
|
|||
int cong_response_us;
|
||||
int cong_reps;
|
||||
int cong_period;
|
||||
unsigned long clocks_per_100_usec;
|
||||
cycles_t period_time;
|
||||
long period_requests;
|
||||
struct hub_and_pnode *thp;
|
||||
|
@ -591,6 +677,11 @@ static inline void write_mmr_sw_ack(unsigned long mr)
|
|||
uv_write_local_mmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, mr);
|
||||
}
|
||||
|
||||
static inline void write_gmmr_sw_ack(int pnode, unsigned long mr)
|
||||
{
|
||||
write_gmmr(pnode, UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, mr);
|
||||
}
|
||||
|
||||
static inline unsigned long read_mmr_sw_ack(void)
|
||||
{
|
||||
return read_lmmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE);
|
||||
|
|
|
@ -290,14 +290,15 @@ static inline int pit_verify_msb(unsigned char val)
|
|||
static inline int pit_expect_msb(unsigned char val, u64 *tscp, unsigned long *deltap)
|
||||
{
|
||||
int count;
|
||||
u64 tsc = 0;
|
||||
u64 tsc = 0, prev_tsc = 0;
|
||||
|
||||
for (count = 0; count < 50000; count++) {
|
||||
if (!pit_verify_msb(val))
|
||||
break;
|
||||
prev_tsc = tsc;
|
||||
tsc = get_cycles();
|
||||
}
|
||||
*deltap = get_cycles() - tsc;
|
||||
*deltap = get_cycles() - prev_tsc;
|
||||
*tscp = tsc;
|
||||
|
||||
/*
|
||||
|
@ -311,9 +312,9 @@ static inline int pit_expect_msb(unsigned char val, u64 *tscp, unsigned long *de
|
|||
* How many MSB values do we want to see? We aim for
|
||||
* a maximum error rate of 500ppm (in practice the
|
||||
* real error is much smaller), but refuse to spend
|
||||
* more than 25ms on it.
|
||||
* more than 50ms on it.
|
||||
*/
|
||||
#define MAX_QUICK_PIT_MS 25
|
||||
#define MAX_QUICK_PIT_MS 50
|
||||
#define MAX_QUICK_PIT_ITERATIONS (MAX_QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256)
|
||||
|
||||
static unsigned long quick_pit_calibrate(void)
|
||||
|
@ -383,15 +384,12 @@ success:
|
|||
*
|
||||
* As a result, we can depend on there not being
|
||||
* any odd delays anywhere, and the TSC reads are
|
||||
* reliable (within the error). We also adjust the
|
||||
* delta to the middle of the error bars, just
|
||||
* because it looks nicer.
|
||||
* reliable (within the error).
|
||||
*
|
||||
* kHz = ticks / time-in-seconds / 1000;
|
||||
* kHz = (t2 - t1) / (I * 256 / PIT_TICK_RATE) / 1000
|
||||
* kHz = ((t2 - t1) * PIT_TICK_RATE) / (I * 256 * 1000)
|
||||
*/
|
||||
delta += (long)(d2 - d1)/2;
|
||||
delta *= PIT_TICK_RATE;
|
||||
do_div(delta, i*256*1000);
|
||||
printk("Fast TSC calibration using PIT\n");
|
||||
|
|
|
@ -219,7 +219,9 @@ ab: STOS/W/D/Q Yv,rAX
|
|||
ac: LODS/B AL,Xb
|
||||
ad: LODS/W/D/Q rAX,Xv
|
||||
ae: SCAS/B AL,Yb
|
||||
af: SCAS/W/D/Q rAX,Xv
|
||||
# Note: The May 2011 Intel manual shows Xv for the second parameter of the
|
||||
# next instruction but Yv is correct
|
||||
af: SCAS/W/D/Q rAX,Yv
|
||||
# 0xb0 - 0xbf
|
||||
b0: MOV AL/R8L,Ib
|
||||
b1: MOV CL/R9L,Ib
|
||||
|
@ -729,8 +731,8 @@ de: VAESDEC Vdq,Hdq,Wdq (66),(v1)
|
|||
df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1)
|
||||
f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2)
|
||||
f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2)
|
||||
f3: ANDN Gy,By,Ey (v)
|
||||
f4: Grp17 (1A)
|
||||
f2: ANDN Gy,By,Ey (v)
|
||||
f3: Grp17 (1A)
|
||||
f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v)
|
||||
f6: MULX By,Gy,rDX,Ey (F2),(v)
|
||||
f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v)
|
||||
|
|
|
@ -157,13 +157,14 @@ static int __init uvhub_to_first_apicid(int uvhub)
|
|||
* clear of the Timeout bit (as well) will free the resource. No reply will
|
||||
* be sent (the hardware will only do one reply per message).
|
||||
*/
|
||||
static void reply_to_message(struct msg_desc *mdp, struct bau_control *bcp)
|
||||
static void reply_to_message(struct msg_desc *mdp, struct bau_control *bcp,
|
||||
int do_acknowledge)
|
||||
{
|
||||
unsigned long dw;
|
||||
struct bau_pq_entry *msg;
|
||||
|
||||
msg = mdp->msg;
|
||||
if (!msg->canceled) {
|
||||
if (!msg->canceled && do_acknowledge) {
|
||||
dw = (msg->swack_vec << UV_SW_ACK_NPENDING) | msg->swack_vec;
|
||||
write_mmr_sw_ack(dw);
|
||||
}
|
||||
|
@ -212,8 +213,8 @@ static void bau_process_retry_msg(struct msg_desc *mdp,
|
|||
if (mmr & (msg_res << UV_SW_ACK_NPENDING)) {
|
||||
unsigned long mr;
|
||||
/*
|
||||
* is the resource timed out?
|
||||
* make everyone ignore the cancelled message.
|
||||
* Is the resource timed out?
|
||||
* Make everyone ignore the cancelled message.
|
||||
*/
|
||||
msg2->canceled = 1;
|
||||
stat->d_canceled++;
|
||||
|
@ -231,8 +232,8 @@ static void bau_process_retry_msg(struct msg_desc *mdp,
|
|||
* Do all the things a cpu should do for a TLB shootdown message.
|
||||
* Other cpu's may come here at the same time for this message.
|
||||
*/
|
||||
static void bau_process_message(struct msg_desc *mdp,
|
||||
struct bau_control *bcp)
|
||||
static void bau_process_message(struct msg_desc *mdp, struct bau_control *bcp,
|
||||
int do_acknowledge)
|
||||
{
|
||||
short socket_ack_count = 0;
|
||||
short *sp;
|
||||
|
@ -284,8 +285,9 @@ static void bau_process_message(struct msg_desc *mdp,
|
|||
if (msg_ack_count == bcp->cpus_in_uvhub) {
|
||||
/*
|
||||
* All cpus in uvhub saw it; reply
|
||||
* (unless we are in the UV2 workaround)
|
||||
*/
|
||||
reply_to_message(mdp, bcp);
|
||||
reply_to_message(mdp, bcp, do_acknowledge);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -491,27 +493,138 @@ static int uv1_wait_completion(struct bau_desc *bau_desc,
|
|||
/*
|
||||
* UV2 has an extra bit of status in the ACTIVATION_STATUS_2 register.
|
||||
*/
|
||||
static unsigned long uv2_read_status(unsigned long offset, int rshft, int cpu)
|
||||
static unsigned long uv2_read_status(unsigned long offset, int rshft, int desc)
|
||||
{
|
||||
unsigned long descriptor_status;
|
||||
unsigned long descriptor_status2;
|
||||
|
||||
descriptor_status = ((read_lmmr(offset) >> rshft) & UV_ACT_STATUS_MASK);
|
||||
descriptor_status2 = (read_mmr_uv2_status() >> cpu) & 0x1UL;
|
||||
descriptor_status2 = (read_mmr_uv2_status() >> desc) & 0x1UL;
|
||||
descriptor_status = (descriptor_status << 1) | descriptor_status2;
|
||||
return descriptor_status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return whether the status of the descriptor that is normally used for this
|
||||
* cpu (the one indexed by its hub-relative cpu number) is busy.
|
||||
* The status of the original 32 descriptors is always reflected in the 64
|
||||
* bits of UVH_LB_BAU_SB_ACTIVATION_STATUS_0.
|
||||
* The bit provided by the activation_status_2 register is irrelevant to
|
||||
* the status if it is only being tested for busy or not busy.
|
||||
*/
|
||||
int normal_busy(struct bau_control *bcp)
|
||||
{
|
||||
int cpu = bcp->uvhub_cpu;
|
||||
int mmr_offset;
|
||||
int right_shift;
|
||||
|
||||
mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0;
|
||||
right_shift = cpu * UV_ACT_STATUS_SIZE;
|
||||
return (((((read_lmmr(mmr_offset) >> right_shift) &
|
||||
UV_ACT_STATUS_MASK)) << 1) == UV2H_DESC_BUSY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Entered when a bau descriptor has gone into a permanent busy wait because
|
||||
* of a hardware bug.
|
||||
* Workaround the bug.
|
||||
*/
|
||||
int handle_uv2_busy(struct bau_control *bcp)
|
||||
{
|
||||
int busy_one = bcp->using_desc;
|
||||
int normal = bcp->uvhub_cpu;
|
||||
int selected = -1;
|
||||
int i;
|
||||
unsigned long descriptor_status;
|
||||
unsigned long status;
|
||||
int mmr_offset;
|
||||
struct bau_desc *bau_desc_old;
|
||||
struct bau_desc *bau_desc_new;
|
||||
struct bau_control *hmaster = bcp->uvhub_master;
|
||||
struct ptc_stats *stat = bcp->statp;
|
||||
cycles_t ttm;
|
||||
|
||||
stat->s_uv2_wars++;
|
||||
spin_lock(&hmaster->uvhub_lock);
|
||||
/* try for the original first */
|
||||
if (busy_one != normal) {
|
||||
if (!normal_busy(bcp))
|
||||
selected = normal;
|
||||
}
|
||||
if (selected < 0) {
|
||||
/* can't use the normal, select an alternate */
|
||||
mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1;
|
||||
descriptor_status = read_lmmr(mmr_offset);
|
||||
|
||||
/* scan available descriptors 32-63 */
|
||||
for (i = 0; i < UV_CPUS_PER_AS; i++) {
|
||||
if ((hmaster->inuse_map & (1 << i)) == 0) {
|
||||
status = ((descriptor_status >>
|
||||
(i * UV_ACT_STATUS_SIZE)) &
|
||||
UV_ACT_STATUS_MASK) << 1;
|
||||
if (status != UV2H_DESC_BUSY) {
|
||||
selected = i + UV_CPUS_PER_AS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (busy_one != normal)
|
||||
/* mark the busy alternate as not in-use */
|
||||
hmaster->inuse_map &= ~(1 << (busy_one - UV_CPUS_PER_AS));
|
||||
|
||||
if (selected >= 0) {
|
||||
/* switch to the selected descriptor */
|
||||
if (selected != normal) {
|
||||
/* set the selected alternate as in-use */
|
||||
hmaster->inuse_map |=
|
||||
(1 << (selected - UV_CPUS_PER_AS));
|
||||
if (selected > stat->s_uv2_wars_hw)
|
||||
stat->s_uv2_wars_hw = selected;
|
||||
}
|
||||
bau_desc_old = bcp->descriptor_base;
|
||||
bau_desc_old += (ITEMS_PER_DESC * busy_one);
|
||||
bcp->using_desc = selected;
|
||||
bau_desc_new = bcp->descriptor_base;
|
||||
bau_desc_new += (ITEMS_PER_DESC * selected);
|
||||
*bau_desc_new = *bau_desc_old;
|
||||
} else {
|
||||
/*
|
||||
* All are busy. Wait for the normal one for this cpu to
|
||||
* free up.
|
||||
*/
|
||||
stat->s_uv2_war_waits++;
|
||||
spin_unlock(&hmaster->uvhub_lock);
|
||||
ttm = get_cycles();
|
||||
do {
|
||||
cpu_relax();
|
||||
} while (normal_busy(bcp));
|
||||
spin_lock(&hmaster->uvhub_lock);
|
||||
/* switch to the original descriptor */
|
||||
bcp->using_desc = normal;
|
||||
bau_desc_old = bcp->descriptor_base;
|
||||
bau_desc_old += (ITEMS_PER_DESC * bcp->using_desc);
|
||||
bcp->using_desc = (ITEMS_PER_DESC * normal);
|
||||
bau_desc_new = bcp->descriptor_base;
|
||||
bau_desc_new += (ITEMS_PER_DESC * normal);
|
||||
*bau_desc_new = *bau_desc_old; /* copy the entire descriptor */
|
||||
}
|
||||
spin_unlock(&hmaster->uvhub_lock);
|
||||
return FLUSH_RETRY_BUSYBUG;
|
||||
}
|
||||
|
||||
static int uv2_wait_completion(struct bau_desc *bau_desc,
|
||||
unsigned long mmr_offset, int right_shift,
|
||||
struct bau_control *bcp, long try)
|
||||
{
|
||||
unsigned long descriptor_stat;
|
||||
cycles_t ttm;
|
||||
int cpu = bcp->uvhub_cpu;
|
||||
int desc = bcp->using_desc;
|
||||
long busy_reps = 0;
|
||||
struct ptc_stats *stat = bcp->statp;
|
||||
|
||||
descriptor_stat = uv2_read_status(mmr_offset, right_shift, cpu);
|
||||
descriptor_stat = uv2_read_status(mmr_offset, right_shift, desc);
|
||||
|
||||
/* spin on the status MMR, waiting for it to go idle */
|
||||
while (descriptor_stat != UV2H_DESC_IDLE) {
|
||||
|
@ -522,32 +635,35 @@ static int uv2_wait_completion(struct bau_desc *bau_desc,
|
|||
* our message and its state will stay IDLE.
|
||||
*/
|
||||
if ((descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT) ||
|
||||
(descriptor_stat == UV2H_DESC_DEST_STRONG_NACK) ||
|
||||
(descriptor_stat == UV2H_DESC_DEST_PUT_ERR)) {
|
||||
stat->s_stimeout++;
|
||||
return FLUSH_GIVEUP;
|
||||
} else if (descriptor_stat == UV2H_DESC_DEST_STRONG_NACK) {
|
||||
stat->s_strongnacks++;
|
||||
bcp->conseccompletes = 0;
|
||||
return FLUSH_GIVEUP;
|
||||
} else if (descriptor_stat == UV2H_DESC_DEST_TIMEOUT) {
|
||||
stat->s_dtimeout++;
|
||||
ttm = get_cycles();
|
||||
/*
|
||||
* Our retries may be blocked by all destination
|
||||
* swack resources being consumed, and a timeout
|
||||
* pending. In that case hardware returns the
|
||||
* ERROR that looks like a destination timeout.
|
||||
*/
|
||||
if (cycles_2_us(ttm - bcp->send_message) < timeout_us) {
|
||||
bcp->conseccompletes = 0;
|
||||
return FLUSH_RETRY_PLUGGED;
|
||||
}
|
||||
bcp->conseccompletes = 0;
|
||||
return FLUSH_RETRY_TIMEOUT;
|
||||
} else {
|
||||
busy_reps++;
|
||||
if (busy_reps > 1000000) {
|
||||
/* not to hammer on the clock */
|
||||
busy_reps = 0;
|
||||
ttm = get_cycles();
|
||||
if ((ttm - bcp->send_message) >
|
||||
(bcp->clocks_per_100_usec)) {
|
||||
return handle_uv2_busy(bcp);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* descriptor_stat is still BUSY
|
||||
*/
|
||||
cpu_relax();
|
||||
}
|
||||
descriptor_stat = uv2_read_status(mmr_offset, right_shift, cpu);
|
||||
descriptor_stat = uv2_read_status(mmr_offset, right_shift,
|
||||
desc);
|
||||
}
|
||||
bcp->conseccompletes++;
|
||||
return FLUSH_COMPLETE;
|
||||
|
@ -563,17 +679,17 @@ static int wait_completion(struct bau_desc *bau_desc,
|
|||
{
|
||||
int right_shift;
|
||||
unsigned long mmr_offset;
|
||||
int cpu = bcp->uvhub_cpu;
|
||||
int desc = bcp->using_desc;
|
||||
|
||||
if (cpu < UV_CPUS_PER_AS) {
|
||||
if (desc < UV_CPUS_PER_AS) {
|
||||
mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0;
|
||||
right_shift = cpu * UV_ACT_STATUS_SIZE;
|
||||
right_shift = desc * UV_ACT_STATUS_SIZE;
|
||||
} else {
|
||||
mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1;
|
||||
right_shift = ((cpu - UV_CPUS_PER_AS) * UV_ACT_STATUS_SIZE);
|
||||
right_shift = ((desc - UV_CPUS_PER_AS) * UV_ACT_STATUS_SIZE);
|
||||
}
|
||||
|
||||
if (is_uv1_hub())
|
||||
if (bcp->uvhub_version == 1)
|
||||
return uv1_wait_completion(bau_desc, mmr_offset, right_shift,
|
||||
bcp, try);
|
||||
else
|
||||
|
@ -752,19 +868,22 @@ static void handle_cmplt(int completion_status, struct bau_desc *bau_desc,
|
|||
* Returns 1 if it gives up entirely and the original cpu mask is to be
|
||||
* returned to the kernel.
|
||||
*/
|
||||
int uv_flush_send_and_wait(struct bau_desc *bau_desc,
|
||||
struct cpumask *flush_mask, struct bau_control *bcp)
|
||||
int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp)
|
||||
{
|
||||
int seq_number = 0;
|
||||
int completion_stat = 0;
|
||||
int uv1 = 0;
|
||||
long try = 0;
|
||||
unsigned long index;
|
||||
cycles_t time1;
|
||||
cycles_t time2;
|
||||
struct ptc_stats *stat = bcp->statp;
|
||||
struct bau_control *hmaster = bcp->uvhub_master;
|
||||
struct uv1_bau_msg_header *uv1_hdr = NULL;
|
||||
struct uv2_bau_msg_header *uv2_hdr = NULL;
|
||||
struct bau_desc *bau_desc;
|
||||
|
||||
if (is_uv1_hub())
|
||||
if (bcp->uvhub_version == 1)
|
||||
uv1_throttle(hmaster, stat);
|
||||
|
||||
while (hmaster->uvhub_quiesce)
|
||||
|
@ -772,22 +891,39 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc,
|
|||
|
||||
time1 = get_cycles();
|
||||
do {
|
||||
if (try == 0) {
|
||||
bau_desc->header.msg_type = MSG_REGULAR;
|
||||
bau_desc = bcp->descriptor_base;
|
||||
bau_desc += (ITEMS_PER_DESC * bcp->using_desc);
|
||||
if (bcp->uvhub_version == 1) {
|
||||
uv1 = 1;
|
||||
uv1_hdr = &bau_desc->header.uv1_hdr;
|
||||
} else
|
||||
uv2_hdr = &bau_desc->header.uv2_hdr;
|
||||
if ((try == 0) || (completion_stat == FLUSH_RETRY_BUSYBUG)) {
|
||||
if (uv1)
|
||||
uv1_hdr->msg_type = MSG_REGULAR;
|
||||
else
|
||||
uv2_hdr->msg_type = MSG_REGULAR;
|
||||
seq_number = bcp->message_number++;
|
||||
} else {
|
||||
bau_desc->header.msg_type = MSG_RETRY;
|
||||
if (uv1)
|
||||
uv1_hdr->msg_type = MSG_RETRY;
|
||||
else
|
||||
uv2_hdr->msg_type = MSG_RETRY;
|
||||
stat->s_retry_messages++;
|
||||
}
|
||||
|
||||
bau_desc->header.sequence = seq_number;
|
||||
index = (1UL << AS_PUSH_SHIFT) | bcp->uvhub_cpu;
|
||||
if (uv1)
|
||||
uv1_hdr->sequence = seq_number;
|
||||
else
|
||||
uv2_hdr->sequence = seq_number;
|
||||
index = (1UL << AS_PUSH_SHIFT) | bcp->using_desc;
|
||||
bcp->send_message = get_cycles();
|
||||
|
||||
write_mmr_activation(index);
|
||||
|
||||
try++;
|
||||
completion_stat = wait_completion(bau_desc, bcp, try);
|
||||
/* UV2: wait_completion() may change the bcp->using_desc */
|
||||
|
||||
handle_cmplt(completion_stat, bau_desc, bcp, hmaster, stat);
|
||||
|
||||
|
@ -798,6 +934,7 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc,
|
|||
}
|
||||
cpu_relax();
|
||||
} while ((completion_stat == FLUSH_RETRY_PLUGGED) ||
|
||||
(completion_stat == FLUSH_RETRY_BUSYBUG) ||
|
||||
(completion_stat == FLUSH_RETRY_TIMEOUT));
|
||||
|
||||
time2 = get_cycles();
|
||||
|
@ -812,6 +949,7 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc,
|
|||
record_send_stats(time1, time2, bcp, stat, completion_stat, try);
|
||||
|
||||
if (completion_stat == FLUSH_GIVEUP)
|
||||
/* FLUSH_GIVEUP will fall back to using IPI's for tlb flush */
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -967,7 +1105,7 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
|
|||
stat->s_ntargself++;
|
||||
|
||||
bau_desc = bcp->descriptor_base;
|
||||
bau_desc += ITEMS_PER_DESC * bcp->uvhub_cpu;
|
||||
bau_desc += (ITEMS_PER_DESC * bcp->using_desc);
|
||||
bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE);
|
||||
if (set_distrib_bits(flush_mask, bcp, bau_desc, &locals, &remotes))
|
||||
return NULL;
|
||||
|
@ -980,12 +1118,85 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
|
|||
* uv_flush_send_and_wait returns 0 if all cpu's were messaged,
|
||||
* or 1 if it gave up and the original cpumask should be returned.
|
||||
*/
|
||||
if (!uv_flush_send_and_wait(bau_desc, flush_mask, bcp))
|
||||
if (!uv_flush_send_and_wait(flush_mask, bcp))
|
||||
return NULL;
|
||||
else
|
||||
return cpumask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search the message queue for any 'other' message with the same software
|
||||
* acknowledge resource bit vector.
|
||||
*/
|
||||
struct bau_pq_entry *find_another_by_swack(struct bau_pq_entry *msg,
|
||||
struct bau_control *bcp, unsigned char swack_vec)
|
||||
{
|
||||
struct bau_pq_entry *msg_next = msg + 1;
|
||||
|
||||
if (msg_next > bcp->queue_last)
|
||||
msg_next = bcp->queue_first;
|
||||
while ((msg_next->swack_vec != 0) && (msg_next != msg)) {
|
||||
if (msg_next->swack_vec == swack_vec)
|
||||
return msg_next;
|
||||
msg_next++;
|
||||
if (msg_next > bcp->queue_last)
|
||||
msg_next = bcp->queue_first;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* UV2 needs to work around a bug in which an arriving message has not
|
||||
* set a bit in the UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE register.
|
||||
* Such a message must be ignored.
|
||||
*/
|
||||
void process_uv2_message(struct msg_desc *mdp, struct bau_control *bcp)
|
||||
{
|
||||
unsigned long mmr_image;
|
||||
unsigned char swack_vec;
|
||||
struct bau_pq_entry *msg = mdp->msg;
|
||||
struct bau_pq_entry *other_msg;
|
||||
|
||||
mmr_image = read_mmr_sw_ack();
|
||||
swack_vec = msg->swack_vec;
|
||||
|
||||
if ((swack_vec & mmr_image) == 0) {
|
||||
/*
|
||||
* This message was assigned a swack resource, but no
|
||||
* reserved acknowlegment is pending.
|
||||
* The bug has prevented this message from setting the MMR.
|
||||
* And no other message has used the same sw_ack resource.
|
||||
* Do the requested shootdown but do not reply to the msg.
|
||||
* (the 0 means make no acknowledge)
|
||||
*/
|
||||
bau_process_message(mdp, bcp, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some message has set the MMR 'pending' bit; it might have been
|
||||
* another message. Look for that message.
|
||||
*/
|
||||
other_msg = find_another_by_swack(msg, bcp, msg->swack_vec);
|
||||
if (other_msg) {
|
||||
/* There is another. Do not ack the current one. */
|
||||
bau_process_message(mdp, bcp, 0);
|
||||
/*
|
||||
* Let the natural processing of that message acknowledge
|
||||
* it. Don't get the processing of sw_ack's out of order.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* There is no other message using this sw_ack, so it is safe to
|
||||
* acknowledge it.
|
||||
*/
|
||||
bau_process_message(mdp, bcp, 1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The BAU message interrupt comes here. (registered by set_intr_gate)
|
||||
* See entry_64.S
|
||||
|
@ -1009,6 +1220,7 @@ void uv_bau_message_interrupt(struct pt_regs *regs)
|
|||
struct ptc_stats *stat;
|
||||
struct msg_desc msgdesc;
|
||||
|
||||
ack_APIC_irq();
|
||||
time_start = get_cycles();
|
||||
|
||||
bcp = &per_cpu(bau_control, smp_processor_id());
|
||||
|
@ -1022,9 +1234,11 @@ void uv_bau_message_interrupt(struct pt_regs *regs)
|
|||
count++;
|
||||
|
||||
msgdesc.msg_slot = msg - msgdesc.queue_first;
|
||||
msgdesc.swack_slot = ffs(msg->swack_vec) - 1;
|
||||
msgdesc.msg = msg;
|
||||
bau_process_message(&msgdesc, bcp);
|
||||
if (bcp->uvhub_version == 2)
|
||||
process_uv2_message(&msgdesc, bcp);
|
||||
else
|
||||
bau_process_message(&msgdesc, bcp, 1);
|
||||
|
||||
msg++;
|
||||
if (msg > msgdesc.queue_last)
|
||||
|
@ -1036,8 +1250,6 @@ void uv_bau_message_interrupt(struct pt_regs *regs)
|
|||
stat->d_nomsg++;
|
||||
else if (count > 1)
|
||||
stat->d_multmsg++;
|
||||
|
||||
ack_APIC_irq();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1083,7 +1295,7 @@ static void __init enable_timeouts(void)
|
|||
*/
|
||||
mmr_image |= (1L << SOFTACK_MSHIFT);
|
||||
if (is_uv2_hub()) {
|
||||
mmr_image |= (1L << UV2_LEG_SHFT);
|
||||
mmr_image &= ~(1L << UV2_LEG_SHFT);
|
||||
mmr_image |= (1L << UV2_EXT_SHFT);
|
||||
}
|
||||
write_mmr_misc_control(pnode, mmr_image);
|
||||
|
@ -1136,13 +1348,13 @@ static int ptc_seq_show(struct seq_file *file, void *data)
|
|||
seq_printf(file,
|
||||
"remotehub numuvhubs numuvhubs16 numuvhubs8 ");
|
||||
seq_printf(file,
|
||||
"numuvhubs4 numuvhubs2 numuvhubs1 dto retries rok ");
|
||||
"numuvhubs4 numuvhubs2 numuvhubs1 dto snacks retries rok ");
|
||||
seq_printf(file,
|
||||
"resetp resett giveup sto bz throt swack recv rtime ");
|
||||
seq_printf(file,
|
||||
"all one mult none retry canc nocan reset rcan ");
|
||||
seq_printf(file,
|
||||
"disable enable\n");
|
||||
"disable enable wars warshw warwaits\n");
|
||||
}
|
||||
if (cpu < num_possible_cpus() && cpu_online(cpu)) {
|
||||
stat = &per_cpu(ptcstats, cpu);
|
||||
|
@ -1154,10 +1366,10 @@ static int ptc_seq_show(struct seq_file *file, void *data)
|
|||
stat->s_ntargremotes, stat->s_ntargcpu,
|
||||
stat->s_ntarglocaluvhub, stat->s_ntargremoteuvhub,
|
||||
stat->s_ntarguvhub, stat->s_ntarguvhub16);
|
||||
seq_printf(file, "%ld %ld %ld %ld %ld ",
|
||||
seq_printf(file, "%ld %ld %ld %ld %ld %ld ",
|
||||
stat->s_ntarguvhub8, stat->s_ntarguvhub4,
|
||||
stat->s_ntarguvhub2, stat->s_ntarguvhub1,
|
||||
stat->s_dtimeout);
|
||||
stat->s_dtimeout, stat->s_strongnacks);
|
||||
seq_printf(file, "%ld %ld %ld %ld %ld %ld %ld %ld ",
|
||||
stat->s_retry_messages, stat->s_retriesok,
|
||||
stat->s_resets_plug, stat->s_resets_timeout,
|
||||
|
@ -1173,8 +1385,10 @@ static int ptc_seq_show(struct seq_file *file, void *data)
|
|||
stat->d_nomsg, stat->d_retries, stat->d_canceled,
|
||||
stat->d_nocanceled, stat->d_resets,
|
||||
stat->d_rcanceled);
|
||||
seq_printf(file, "%ld %ld\n",
|
||||
stat->s_bau_disabled, stat->s_bau_reenabled);
|
||||
seq_printf(file, "%ld %ld %ld %ld %ld\n",
|
||||
stat->s_bau_disabled, stat->s_bau_reenabled,
|
||||
stat->s_uv2_wars, stat->s_uv2_wars_hw,
|
||||
stat->s_uv2_war_waits);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1432,12 +1646,15 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode)
|
|||
{
|
||||
int i;
|
||||
int cpu;
|
||||
int uv1 = 0;
|
||||
unsigned long gpa;
|
||||
unsigned long m;
|
||||
unsigned long n;
|
||||
size_t dsize;
|
||||
struct bau_desc *bau_desc;
|
||||
struct bau_desc *bd2;
|
||||
struct uv1_bau_msg_header *uv1_hdr;
|
||||
struct uv2_bau_msg_header *uv2_hdr;
|
||||
struct bau_control *bcp;
|
||||
|
||||
/*
|
||||
|
@ -1451,6 +1668,8 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode)
|
|||
gpa = uv_gpa(bau_desc);
|
||||
n = uv_gpa_to_gnode(gpa);
|
||||
m = uv_gpa_to_offset(gpa);
|
||||
if (is_uv1_hub())
|
||||
uv1 = 1;
|
||||
|
||||
/* the 14-bit pnode */
|
||||
write_mmr_descriptor_base(pnode, (n << UV_DESC_PSHIFT | m));
|
||||
|
@ -1461,21 +1680,33 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode)
|
|||
*/
|
||||
for (i = 0, bd2 = bau_desc; i < (ADP_SZ * ITEMS_PER_DESC); i++, bd2++) {
|
||||
memset(bd2, 0, sizeof(struct bau_desc));
|
||||
bd2->header.swack_flag = 1;
|
||||
/*
|
||||
* The base_dest_nasid set in the message header is the nasid
|
||||
* of the first uvhub in the partition. The bit map will
|
||||
* indicate destination pnode numbers relative to that base.
|
||||
* They may not be consecutive if nasid striding is being used.
|
||||
*/
|
||||
bd2->header.base_dest_nasid = UV_PNODE_TO_NASID(base_pnode);
|
||||
bd2->header.dest_subnodeid = UV_LB_SUBNODEID;
|
||||
bd2->header.command = UV_NET_ENDPOINT_INTD;
|
||||
bd2->header.int_both = 1;
|
||||
/*
|
||||
* all others need to be set to zero:
|
||||
* fairness chaining multilevel count replied_to
|
||||
*/
|
||||
if (uv1) {
|
||||
uv1_hdr = &bd2->header.uv1_hdr;
|
||||
uv1_hdr->swack_flag = 1;
|
||||
/*
|
||||
* The base_dest_nasid set in the message header
|
||||
* is the nasid of the first uvhub in the partition.
|
||||
* The bit map will indicate destination pnode numbers
|
||||
* relative to that base. They may not be consecutive
|
||||
* if nasid striding is being used.
|
||||
*/
|
||||
uv1_hdr->base_dest_nasid =
|
||||
UV_PNODE_TO_NASID(base_pnode);
|
||||
uv1_hdr->dest_subnodeid = UV_LB_SUBNODEID;
|
||||
uv1_hdr->command = UV_NET_ENDPOINT_INTD;
|
||||
uv1_hdr->int_both = 1;
|
||||
/*
|
||||
* all others need to be set to zero:
|
||||
* fairness chaining multilevel count replied_to
|
||||
*/
|
||||
} else {
|
||||
uv2_hdr = &bd2->header.uv2_hdr;
|
||||
uv2_hdr->swack_flag = 1;
|
||||
uv2_hdr->base_dest_nasid =
|
||||
UV_PNODE_TO_NASID(base_pnode);
|
||||
uv2_hdr->dest_subnodeid = UV_LB_SUBNODEID;
|
||||
uv2_hdr->command = UV_NET_ENDPOINT_INTD;
|
||||
}
|
||||
}
|
||||
for_each_present_cpu(cpu) {
|
||||
if (pnode != uv_blade_to_pnode(uv_cpu_to_blade_id(cpu)))
|
||||
|
@ -1531,6 +1762,7 @@ static void pq_init(int node, int pnode)
|
|||
write_mmr_payload_first(pnode, pn_first);
|
||||
write_mmr_payload_tail(pnode, first);
|
||||
write_mmr_payload_last(pnode, last);
|
||||
write_gmmr_sw_ack(pnode, 0xffffUL);
|
||||
|
||||
/* in effect, all msg_type's are set to MSG_NOOP */
|
||||
memset(pqp, 0, sizeof(struct bau_pq_entry) * DEST_Q_SIZE);
|
||||
|
@ -1584,14 +1816,14 @@ static int calculate_destination_timeout(void)
|
|||
ts_ns = base * mult1 * mult2;
|
||||
ret = ts_ns / 1000;
|
||||
} else {
|
||||
/* 4 bits 0/1 for 10/80us, 3 bits of multiplier */
|
||||
mmr_image = uv_read_local_mmr(UVH_AGING_PRESCALE_SEL);
|
||||
/* 4 bits 0/1 for 10/80us base, 3 bits of multiplier */
|
||||
mmr_image = uv_read_local_mmr(UVH_LB_BAU_MISC_CONTROL);
|
||||
mmr_image = (mmr_image & UV_SA_MASK) >> UV_SA_SHFT;
|
||||
if (mmr_image & (1L << UV2_ACK_UNITS_SHFT))
|
||||
mult1 = 80;
|
||||
base = 80;
|
||||
else
|
||||
mult1 = 10;
|
||||
base = mmr_image & UV2_ACK_MASK;
|
||||
base = 10;
|
||||
mult1 = mmr_image & UV2_ACK_MASK;
|
||||
ret = mult1 * base;
|
||||
}
|
||||
return ret;
|
||||
|
@ -1618,6 +1850,7 @@ static void __init init_per_cpu_tunables(void)
|
|||
bcp->cong_response_us = congested_respns_us;
|
||||
bcp->cong_reps = congested_reps;
|
||||
bcp->cong_period = congested_period;
|
||||
bcp->clocks_per_100_usec = usec_2_cycles(100);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1728,8 +1961,17 @@ static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp,
|
|||
bcp->cpus_in_socket = sdp->num_cpus;
|
||||
bcp->socket_master = *smasterp;
|
||||
bcp->uvhub = bdp->uvhub;
|
||||
if (is_uv1_hub())
|
||||
bcp->uvhub_version = 1;
|
||||
else if (is_uv2_hub())
|
||||
bcp->uvhub_version = 2;
|
||||
else {
|
||||
printk(KERN_EMERG "uvhub version not 1 or 2\n");
|
||||
return 1;
|
||||
}
|
||||
bcp->uvhub_master = *hmasterp;
|
||||
bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->blade_processor_id;
|
||||
bcp->using_desc = bcp->uvhub_cpu;
|
||||
if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) {
|
||||
printk(KERN_EMERG "%d cpus per uvhub invalid\n",
|
||||
bcp->uvhub_cpu);
|
||||
|
@ -1845,6 +2087,8 @@ static int __init uv_bau_init(void)
|
|||
uv_base_pnode = uv_blade_to_pnode(uvhub);
|
||||
}
|
||||
|
||||
enable_timeouts();
|
||||
|
||||
if (init_per_cpu(nuvhubs, uv_base_pnode)) {
|
||||
nobau = 1;
|
||||
return 0;
|
||||
|
@ -1855,7 +2099,6 @@ static int __init uv_bau_init(void)
|
|||
if (uv_blade_nr_possible_cpus(uvhub))
|
||||
init_uvhub(uvhub, vector, uv_base_pnode);
|
||||
|
||||
enable_timeouts();
|
||||
alloc_intr_gate(vector, uv_bau_message_intr1);
|
||||
|
||||
for_each_possible_blade(uvhub) {
|
||||
|
@ -1867,7 +2110,8 @@ static int __init uv_bau_init(void)
|
|||
val = 1L << 63;
|
||||
write_gmmr_activation(pnode, val);
|
||||
mmr = 1; /* should be 1 to broadcast to both sockets */
|
||||
write_mmr_data_broadcast(pnode, mmr);
|
||||
if (!is_uv1_hub())
|
||||
write_mmr_data_broadcast(pnode, mmr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ config GPIO_GENERIC_PLATFORM
|
|||
|
||||
config GPIO_IT8761E
|
||||
tristate "IT8761E GPIO support"
|
||||
depends on X86 # unconditional access to IO space.
|
||||
help
|
||||
Say yes here to support GPIO functionality of IT8761E super I/O chip.
|
||||
|
||||
|
|
|
@ -248,7 +248,7 @@ static void ioh_gpio_setup(struct ioh_gpio *chip, int num_port)
|
|||
static int ioh_irq_type(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
u32 im;
|
||||
u32 *im_reg;
|
||||
void __iomem *im_reg;
|
||||
u32 ien;
|
||||
u32 im_pos;
|
||||
int ch;
|
||||
|
@ -412,7 +412,7 @@ static int __devinit ioh_gpio_probe(struct pci_dev *pdev,
|
|||
int i, j;
|
||||
struct ioh_gpio *chip;
|
||||
void __iomem *base;
|
||||
void __iomem *chip_save;
|
||||
void *chip_save;
|
||||
int irq_base;
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
|
@ -428,7 +428,7 @@ static int __devinit ioh_gpio_probe(struct pci_dev *pdev,
|
|||
}
|
||||
|
||||
base = pci_iomap(pdev, 1, 0);
|
||||
if (base == 0) {
|
||||
if (!base) {
|
||||
dev_err(&pdev->dev, "%s : pci_iomap failed", __func__);
|
||||
ret = -ENOMEM;
|
||||
goto err_iomap;
|
||||
|
@ -521,7 +521,7 @@ static void __devexit ioh_gpio_remove(struct pci_dev *pdev)
|
|||
int err;
|
||||
int i;
|
||||
struct ioh_gpio *chip = pci_get_drvdata(pdev);
|
||||
void __iomem *chip_save;
|
||||
void *chip_save;
|
||||
|
||||
chip_save = chip;
|
||||
|
||||
|
|
|
@ -231,7 +231,7 @@ static void pch_gpio_setup(struct pch_gpio *chip)
|
|||
static int pch_irq_type(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
u32 im;
|
||||
u32 *im_reg;
|
||||
u32 __iomem *im_reg;
|
||||
u32 ien;
|
||||
u32 im_pos;
|
||||
int ch;
|
||||
|
@ -376,7 +376,7 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev,
|
|||
}
|
||||
|
||||
chip->base = pci_iomap(pdev, 1, 0);
|
||||
if (chip->base == 0) {
|
||||
if (!chip->base) {
|
||||
dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__);
|
||||
ret = -ENOMEM;
|
||||
goto err_iomap;
|
||||
|
|
|
@ -52,7 +52,7 @@ static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset,
|
|||
struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio);
|
||||
|
||||
/* Set the initial value */
|
||||
tps65910_gpio_set(gc, 0, value);
|
||||
tps65910_gpio_set(gc, offset, value);
|
||||
|
||||
return tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset,
|
||||
GPIO_CFG_MASK);
|
||||
|
|
|
@ -26,35 +26,9 @@
|
|||
#define to_mcp(d) container_of(d, struct mcp, attached_device)
|
||||
#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv)
|
||||
|
||||
static const struct mcp_device_id *mcp_match_id(const struct mcp_device_id *id,
|
||||
const char *codec)
|
||||
{
|
||||
while (id->name[0]) {
|
||||
if (strcmp(codec, id->name) == 0)
|
||||
return id;
|
||||
id++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp)
|
||||
{
|
||||
const struct mcp_driver *driver =
|
||||
to_mcp_driver(mcp->attached_device.driver);
|
||||
|
||||
return mcp_match_id(driver->id_table, mcp->codec);
|
||||
}
|
||||
EXPORT_SYMBOL(mcp_get_device_id);
|
||||
|
||||
static int mcp_bus_match(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
const struct mcp *mcp = to_mcp(dev);
|
||||
const struct mcp_driver *driver = to_mcp_driver(drv);
|
||||
|
||||
if (driver->id_table)
|
||||
return !!mcp_match_id(driver->id_table, mcp->codec);
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int mcp_bus_probe(struct device *dev)
|
||||
|
@ -100,18 +74,9 @@ static int mcp_bus_resume(struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int mcp_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct mcp *mcp = to_mcp(dev);
|
||||
|
||||
add_uevent_var(env, "MODALIAS=%s%s", MCP_MODULE_PREFIX, mcp->codec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct bus_type mcp_bus_type = {
|
||||
.name = "mcp",
|
||||
.match = mcp_bus_match,
|
||||
.uevent = mcp_bus_uevent,
|
||||
.probe = mcp_bus_probe,
|
||||
.remove = mcp_bus_remove,
|
||||
.suspend = mcp_bus_suspend,
|
||||
|
@ -128,9 +93,11 @@ static struct bus_type mcp_bus_type = {
|
|||
*/
|
||||
void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div)
|
||||
{
|
||||
spin_lock_irq(&mcp->lock);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mcp->lock, flags);
|
||||
mcp->ops->set_telecom_divisor(mcp, div);
|
||||
spin_unlock_irq(&mcp->lock);
|
||||
spin_unlock_irqrestore(&mcp->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(mcp_set_telecom_divisor);
|
||||
|
||||
|
@ -143,9 +110,11 @@ EXPORT_SYMBOL(mcp_set_telecom_divisor);
|
|||
*/
|
||||
void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div)
|
||||
{
|
||||
spin_lock_irq(&mcp->lock);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mcp->lock, flags);
|
||||
mcp->ops->set_audio_divisor(mcp, div);
|
||||
spin_unlock_irq(&mcp->lock);
|
||||
spin_unlock_irqrestore(&mcp->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(mcp_set_audio_divisor);
|
||||
|
||||
|
@ -198,10 +167,11 @@ EXPORT_SYMBOL(mcp_reg_read);
|
|||
*/
|
||||
void mcp_enable(struct mcp *mcp)
|
||||
{
|
||||
spin_lock_irq(&mcp->lock);
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&mcp->lock, flags);
|
||||
if (mcp->use_count++ == 0)
|
||||
mcp->ops->enable(mcp);
|
||||
spin_unlock_irq(&mcp->lock);
|
||||
spin_unlock_irqrestore(&mcp->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(mcp_enable);
|
||||
|
||||
|
@ -247,14 +217,9 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
|
|||
}
|
||||
EXPORT_SYMBOL(mcp_host_alloc);
|
||||
|
||||
int mcp_host_register(struct mcp *mcp, void *pdata)
|
||||
int mcp_host_register(struct mcp *mcp)
|
||||
{
|
||||
if (!mcp->codec)
|
||||
return -EINVAL;
|
||||
|
||||
mcp->attached_device.platform_data = pdata;
|
||||
dev_set_name(&mcp->attached_device, "mcp0");
|
||||
request_module("%s%s", MCP_MODULE_PREFIX, mcp->codec);
|
||||
return device_register(&mcp->attached_device);
|
||||
}
|
||||
EXPORT_SYMBOL(mcp_host_register);
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <linux/spinlock.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mfd/mcp.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <mach/dma.h>
|
||||
#include <mach/hardware.h>
|
||||
|
@ -27,19 +26,12 @@
|
|||
#include <asm/system.h>
|
||||
#include <mach/mcp.h>
|
||||
|
||||
/* Register offsets */
|
||||
#define MCCR0 0x00
|
||||
#define MCDR0 0x08
|
||||
#define MCDR1 0x0C
|
||||
#define MCDR2 0x10
|
||||
#define MCSR 0x18
|
||||
#define MCCR1 0x00
|
||||
#include <mach/assabet.h>
|
||||
|
||||
|
||||
struct mcp_sa11x0 {
|
||||
u32 mccr0;
|
||||
u32 mccr1;
|
||||
unsigned char *mccr0_base;
|
||||
unsigned char *mccr1_base;
|
||||
u32 mccr0;
|
||||
u32 mccr1;
|
||||
};
|
||||
|
||||
#define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp))
|
||||
|
@ -47,25 +39,25 @@ struct mcp_sa11x0 {
|
|||
static void
|
||||
mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
|
||||
{
|
||||
struct mcp_sa11x0 *priv = priv(mcp);
|
||||
unsigned int mccr0;
|
||||
|
||||
divisor /= 32;
|
||||
|
||||
priv->mccr0 &= ~0x00007f00;
|
||||
priv->mccr0 |= divisor << 8;
|
||||
__raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
|
||||
mccr0 = Ser4MCCR0 & ~0x00007f00;
|
||||
mccr0 |= divisor << 8;
|
||||
Ser4MCCR0 = mccr0;
|
||||
}
|
||||
|
||||
static void
|
||||
mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
|
||||
{
|
||||
struct mcp_sa11x0 *priv = priv(mcp);
|
||||
unsigned int mccr0;
|
||||
|
||||
divisor /= 32;
|
||||
|
||||
priv->mccr0 &= ~0x0000007f;
|
||||
priv->mccr0 |= divisor;
|
||||
__raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
|
||||
mccr0 = Ser4MCCR0 & ~0x0000007f;
|
||||
mccr0 |= divisor;
|
||||
Ser4MCCR0 = mccr0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -79,16 +71,12 @@ mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
|
|||
{
|
||||
int ret = -ETIME;
|
||||
int i;
|
||||
u32 mcpreg;
|
||||
struct mcp_sa11x0 *priv = priv(mcp);
|
||||
|
||||
mcpreg = reg << 17 | MCDR2_Wr | (val & 0xffff);
|
||||
__raw_writel(mcpreg, priv->mccr0_base + MCDR2);
|
||||
Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
udelay(mcp->rw_timeout);
|
||||
mcpreg = __raw_readl(priv->mccr0_base + MCSR);
|
||||
if (mcpreg & MCSR_CWC) {
|
||||
if (Ser4MCSR & MCSR_CWC) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -109,18 +97,13 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
|
|||
{
|
||||
int ret = -ETIME;
|
||||
int i;
|
||||
u32 mcpreg;
|
||||
struct mcp_sa11x0 *priv = priv(mcp);
|
||||
|
||||
mcpreg = reg << 17 | MCDR2_Rd;
|
||||
__raw_writel(mcpreg, priv->mccr0_base + MCDR2);
|
||||
Ser4MCDR2 = reg << 17 | MCDR2_Rd;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
udelay(mcp->rw_timeout);
|
||||
mcpreg = __raw_readl(priv->mccr0_base + MCSR);
|
||||
if (mcpreg & MCSR_CRC) {
|
||||
ret = __raw_readl(priv->mccr0_base + MCDR2)
|
||||
& 0xffff;
|
||||
if (Ser4MCSR & MCSR_CRC) {
|
||||
ret = Ser4MCDR2 & 0xffff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -133,19 +116,13 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
|
|||
|
||||
static void mcp_sa11x0_enable(struct mcp *mcp)
|
||||
{
|
||||
struct mcp_sa11x0 *priv = priv(mcp);
|
||||
|
||||
__raw_writel(-1, priv->mccr0_base + MCSR);
|
||||
priv->mccr0 |= MCCR0_MCE;
|
||||
__raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
|
||||
Ser4MCSR = -1;
|
||||
Ser4MCCR0 |= MCCR0_MCE;
|
||||
}
|
||||
|
||||
static void mcp_sa11x0_disable(struct mcp *mcp)
|
||||
{
|
||||
struct mcp_sa11x0 *priv = priv(mcp);
|
||||
|
||||
priv->mccr0 &= ~MCCR0_MCE;
|
||||
__raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
|
||||
Ser4MCCR0 &= ~MCCR0_MCE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -165,69 +142,50 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
|
|||
struct mcp_plat_data *data = pdev->dev.platform_data;
|
||||
struct mcp *mcp;
|
||||
int ret;
|
||||
struct mcp_sa11x0 *priv;
|
||||
struct resource *res_mem0, *res_mem1;
|
||||
u32 size0, size1;
|
||||
|
||||
if (!data)
|
||||
return -ENODEV;
|
||||
|
||||
if (!data->codec)
|
||||
return -ENODEV;
|
||||
|
||||
res_mem0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res_mem0)
|
||||
return -ENODEV;
|
||||
size0 = res_mem0->end - res_mem0->start + 1;
|
||||
|
||||
res_mem1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
if (!res_mem1)
|
||||
return -ENODEV;
|
||||
size1 = res_mem1->end - res_mem1->start + 1;
|
||||
|
||||
if (!request_mem_region(res_mem0->start, size0, "sa11x0-mcp"))
|
||||
if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp"))
|
||||
return -EBUSY;
|
||||
|
||||
if (!request_mem_region(res_mem1->start, size1, "sa11x0-mcp")) {
|
||||
ret = -EBUSY;
|
||||
goto release;
|
||||
}
|
||||
|
||||
mcp = mcp_host_alloc(&pdev->dev, sizeof(struct mcp_sa11x0));
|
||||
if (!mcp) {
|
||||
ret = -ENOMEM;
|
||||
goto release2;
|
||||
goto release;
|
||||
}
|
||||
|
||||
priv = priv(mcp);
|
||||
|
||||
mcp->owner = THIS_MODULE;
|
||||
mcp->ops = &mcp_sa11x0;
|
||||
mcp->sclk_rate = data->sclk_rate;
|
||||
mcp->dma_audio_rd = DDAR_DevAdd(res_mem0->start + MCDR0)
|
||||
+ DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev;
|
||||
mcp->dma_audio_wr = DDAR_DevAdd(res_mem0->start + MCDR0)
|
||||
+ DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev;
|
||||
mcp->dma_telco_rd = DDAR_DevAdd(res_mem0->start + MCDR1)
|
||||
+ DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev;
|
||||
mcp->dma_telco_wr = DDAR_DevAdd(res_mem0->start + MCDR1)
|
||||
+ DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev;
|
||||
mcp->codec = data->codec;
|
||||
mcp->dma_audio_rd = DMA_Ser4MCP0Rd;
|
||||
mcp->dma_audio_wr = DMA_Ser4MCP0Wr;
|
||||
mcp->dma_telco_rd = DMA_Ser4MCP1Rd;
|
||||
mcp->dma_telco_wr = DMA_Ser4MCP1Wr;
|
||||
mcp->gpio_base = data->gpio_base;
|
||||
|
||||
platform_set_drvdata(pdev, mcp);
|
||||
|
||||
if (machine_is_assabet()) {
|
||||
ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the PPC unit correctly.
|
||||
*/
|
||||
PPDR &= ~PPC_RXD4;
|
||||
PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
|
||||
PSDR |= PPC_RXD4;
|
||||
PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
|
||||
/*
|
||||
* Initialise device. Note that we initially
|
||||
* set the sampling rate to minimum.
|
||||
*/
|
||||
priv->mccr0_base = ioremap(res_mem0->start, size0);
|
||||
priv->mccr1_base = ioremap(res_mem1->start, size1);
|
||||
|
||||
__raw_writel(-1, priv->mccr0_base + MCSR);
|
||||
priv->mccr1 = data->mccr1;
|
||||
priv->mccr0 = data->mccr0 | 0x7f7f;
|
||||
__raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
|
||||
__raw_writel(priv->mccr1, priv->mccr1_base + MCCR1);
|
||||
Ser4MCSR = -1;
|
||||
Ser4MCCR1 = data->mccr1;
|
||||
Ser4MCCR0 = data->mccr0 | 0x7f7f;
|
||||
|
||||
/*
|
||||
* Calculate the read/write timeout (us) from the bit clock
|
||||
|
@ -237,53 +195,36 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
|
|||
mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) /
|
||||
mcp->sclk_rate;
|
||||
|
||||
ret = mcp_host_register(mcp, data->codec_pdata);
|
||||
ret = mcp_host_register(mcp);
|
||||
if (ret == 0)
|
||||
goto out;
|
||||
|
||||
release2:
|
||||
release_mem_region(res_mem1->start, size1);
|
||||
release:
|
||||
release_mem_region(res_mem0->start, size0);
|
||||
release_mem_region(0x80060000, 0x60);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mcp_sa11x0_remove(struct platform_device *pdev)
|
||||
static int mcp_sa11x0_remove(struct platform_device *dev)
|
||||
{
|
||||
struct mcp *mcp = platform_get_drvdata(pdev);
|
||||
struct mcp_sa11x0 *priv = priv(mcp);
|
||||
struct resource *res_mem;
|
||||
u32 size;
|
||||
struct mcp *mcp = platform_get_drvdata(dev);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
platform_set_drvdata(dev, NULL);
|
||||
mcp_host_unregister(mcp);
|
||||
release_mem_region(0x80060000, 0x60);
|
||||
|
||||
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res_mem) {
|
||||
size = res_mem->end - res_mem->start + 1;
|
||||
release_mem_region(res_mem->start, size);
|
||||
}
|
||||
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
if (res_mem) {
|
||||
size = res_mem->end - res_mem->start + 1;
|
||||
release_mem_region(res_mem->start, size);
|
||||
}
|
||||
iounmap(priv->mccr0_base);
|
||||
iounmap(priv->mccr1_base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state)
|
||||
{
|
||||
struct mcp *mcp = platform_get_drvdata(dev);
|
||||
struct mcp_sa11x0 *priv = priv(mcp);
|
||||
u32 mccr0;
|
||||
|
||||
mccr0 = priv->mccr0 & ~MCCR0_MCE;
|
||||
__raw_writel(mccr0, priv->mccr0_base + MCCR0);
|
||||
priv(mcp)->mccr0 = Ser4MCCR0;
|
||||
priv(mcp)->mccr1 = Ser4MCCR1;
|
||||
Ser4MCCR0 &= ~MCCR0_MCE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -291,10 +232,9 @@ static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state)
|
|||
static int mcp_sa11x0_resume(struct platform_device *dev)
|
||||
{
|
||||
struct mcp *mcp = platform_get_drvdata(dev);
|
||||
struct mcp_sa11x0 *priv = priv(mcp);
|
||||
|
||||
__raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
|
||||
__raw_writel(priv->mccr1, priv->mccr1_base + MCCR1);
|
||||
Ser4MCCR1 = priv(mcp)->mccr1;
|
||||
Ser4MCCR0 = priv(mcp)->mccr0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -311,7 +251,6 @@ static struct platform_driver mcp_sa11x0_driver = {
|
|||
.resume = mcp_sa11x0_resume,
|
||||
.driver = {
|
||||
.name = "sa11x0-mcp",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -36,15 +36,6 @@ static DEFINE_MUTEX(ucb1x00_mutex);
|
|||
static LIST_HEAD(ucb1x00_drivers);
|
||||
static LIST_HEAD(ucb1x00_devices);
|
||||
|
||||
static struct mcp_device_id ucb1x00_id[] = {
|
||||
{ "ucb1x00", 0 }, /* auto-detection */
|
||||
{ "ucb1200", UCB_ID_1200 },
|
||||
{ "ucb1300", UCB_ID_1300 },
|
||||
{ "tc35143", UCB_ID_TC35143 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(mcp, ucb1x00_id);
|
||||
|
||||
/**
|
||||
* ucb1x00_io_set_dir - set IO direction
|
||||
* @ucb: UCB1x00 structure describing chip
|
||||
|
@ -157,16 +148,22 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
|
|||
{
|
||||
struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
|
||||
unsigned long flags;
|
||||
unsigned old, mask = 1 << offset;
|
||||
|
||||
spin_lock_irqsave(&ucb->io_lock, flags);
|
||||
ucb->io_dir |= (1 << offset);
|
||||
ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
|
||||
|
||||
old = ucb->io_out;
|
||||
if (value)
|
||||
ucb->io_out |= 1 << offset;
|
||||
ucb->io_out |= mask;
|
||||
else
|
||||
ucb->io_out &= ~(1 << offset);
|
||||
ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
|
||||
ucb->io_out &= ~mask;
|
||||
|
||||
if (old != ucb->io_out)
|
||||
ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
|
||||
|
||||
if (!(ucb->io_dir & mask)) {
|
||||
ucb->io_dir |= mask;
|
||||
ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
|
||||
}
|
||||
spin_unlock_irqrestore(&ucb->io_lock, flags);
|
||||
|
||||
return 0;
|
||||
|
@ -536,33 +533,17 @@ static struct class ucb1x00_class = {
|
|||
|
||||
static int ucb1x00_probe(struct mcp *mcp)
|
||||
{
|
||||
const struct mcp_device_id *mid;
|
||||
struct ucb1x00 *ucb;
|
||||
struct ucb1x00_driver *drv;
|
||||
struct ucb1x00_plat_data *pdata;
|
||||
unsigned int id;
|
||||
int ret = -ENODEV;
|
||||
int temp;
|
||||
|
||||
mcp_enable(mcp);
|
||||
id = mcp_reg_read(mcp, UCB_ID);
|
||||
mid = mcp_get_device_id(mcp);
|
||||
|
||||
if (mid && mid->driver_data) {
|
||||
if (id != mid->driver_data) {
|
||||
printk(KERN_WARNING "%s wrong ID %04x found: %04x\n",
|
||||
mid->name, (unsigned int) mid->driver_data, id);
|
||||
goto err_disable;
|
||||
}
|
||||
} else {
|
||||
mid = &ucb1x00_id[1];
|
||||
while (mid->driver_data) {
|
||||
if (id == mid->driver_data)
|
||||
break;
|
||||
mid++;
|
||||
}
|
||||
printk(KERN_WARNING "%s ID not found: %04x\n",
|
||||
ucb1x00_id[0].name, id);
|
||||
if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) {
|
||||
printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
|
||||
goto err_disable;
|
||||
}
|
||||
|
||||
|
@ -571,28 +552,28 @@ static int ucb1x00_probe(struct mcp *mcp)
|
|||
if (!ucb)
|
||||
goto err_disable;
|
||||
|
||||
pdata = mcp->attached_device.platform_data;
|
||||
|
||||
ucb->dev.class = &ucb1x00_class;
|
||||
ucb->dev.parent = &mcp->attached_device;
|
||||
dev_set_name(&ucb->dev, mid->name);
|
||||
dev_set_name(&ucb->dev, "ucb1x00");
|
||||
|
||||
spin_lock_init(&ucb->lock);
|
||||
spin_lock_init(&ucb->io_lock);
|
||||
sema_init(&ucb->adc_sem, 1);
|
||||
|
||||
ucb->id = mid;
|
||||
ucb->id = id;
|
||||
ucb->mcp = mcp;
|
||||
ucb->irq = ucb1x00_detect_irq(ucb);
|
||||
if (ucb->irq == NO_IRQ) {
|
||||
printk(KERN_ERR "%s: IRQ probe failed\n", mid->name);
|
||||
printk(KERN_ERR "UCB1x00: IRQ probe failed\n");
|
||||
ret = -ENODEV;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
ucb->gpio.base = -1;
|
||||
if (pdata && (pdata->gpio_base >= 0)) {
|
||||
if (mcp->gpio_base != 0) {
|
||||
ucb->gpio.label = dev_name(&ucb->dev);
|
||||
ucb->gpio.base = pdata->gpio_base;
|
||||
ucb->gpio.base = mcp->gpio_base;
|
||||
ucb->gpio.ngpio = 10;
|
||||
ucb->gpio.set = ucb1x00_gpio_set;
|
||||
ucb->gpio.get = ucb1x00_gpio_get;
|
||||
|
@ -605,10 +586,10 @@ static int ucb1x00_probe(struct mcp *mcp)
|
|||
dev_info(&ucb->dev, "gpio_base not set so no gpiolib support");
|
||||
|
||||
ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING,
|
||||
mid->name, ucb);
|
||||
"UCB1x00", ucb);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s: unable to grab irq%d: %d\n",
|
||||
mid->name, ucb->irq, ret);
|
||||
printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
|
||||
ucb->irq, ret);
|
||||
goto err_gpio;
|
||||
}
|
||||
|
||||
|
@ -712,6 +693,7 @@ static int ucb1x00_resume(struct mcp *mcp)
|
|||
struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
|
||||
struct ucb1x00_dev *dev;
|
||||
|
||||
ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
|
||||
ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
|
||||
mutex_lock(&ucb1x00_mutex);
|
||||
list_for_each_entry(dev, &ucb->devs, dev_node) {
|
||||
|
@ -730,7 +712,6 @@ static struct mcp_driver ucb1x00_driver = {
|
|||
.remove = ucb1x00_remove,
|
||||
.suspend = ucb1x00_suspend,
|
||||
.resume = ucb1x00_resume,
|
||||
.id_table = ucb1x00_id,
|
||||
};
|
||||
|
||||
static int __init ucb1x00_init(void)
|
||||
|
|
|
@ -47,7 +47,6 @@ struct ucb1x00_ts {
|
|||
u16 x_res;
|
||||
u16 y_res;
|
||||
|
||||
unsigned int restart:1;
|
||||
unsigned int adcsync:1;
|
||||
};
|
||||
|
||||
|
@ -207,15 +206,17 @@ static int ucb1x00_thread(void *_ts)
|
|||
{
|
||||
struct ucb1x00_ts *ts = _ts;
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
bool frozen, ignore = false;
|
||||
int valid = 0;
|
||||
|
||||
set_freezable();
|
||||
add_wait_queue(&ts->irq_wait, &wait);
|
||||
while (!kthread_should_stop()) {
|
||||
while (!kthread_freezable_should_stop(&frozen)) {
|
||||
unsigned int x, y, p;
|
||||
signed long timeout;
|
||||
|
||||
ts->restart = 0;
|
||||
if (frozen)
|
||||
ignore = true;
|
||||
|
||||
ucb1x00_adc_enable(ts->ucb);
|
||||
|
||||
|
@ -258,7 +259,7 @@ static int ucb1x00_thread(void *_ts)
|
|||
* space. We therefore leave it to user space
|
||||
* to do any filtering they please.
|
||||
*/
|
||||
if (!ts->restart) {
|
||||
if (!ignore) {
|
||||
ucb1x00_ts_evt_add(ts, p, x, y);
|
||||
valid = 1;
|
||||
}
|
||||
|
@ -267,8 +268,6 @@ static int ucb1x00_thread(void *_ts)
|
|||
timeout = HZ / 100;
|
||||
}
|
||||
|
||||
try_to_freeze();
|
||||
|
||||
schedule_timeout(timeout);
|
||||
}
|
||||
|
||||
|
@ -340,26 +339,6 @@ static void ucb1x00_ts_close(struct input_dev *idev)
|
|||
ucb1x00_disable(ts->ucb);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int ucb1x00_ts_resume(struct ucb1x00_dev *dev)
|
||||
{
|
||||
struct ucb1x00_ts *ts = dev->priv;
|
||||
|
||||
if (ts->rtask != NULL) {
|
||||
/*
|
||||
* Restart the TS thread to ensure the
|
||||
* TS interrupt mode is set up again
|
||||
* after sleep.
|
||||
*/
|
||||
ts->restart = 1;
|
||||
wake_up(&ts->irq_wait);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define ucb1x00_ts_resume NULL
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Initialisation.
|
||||
|
@ -382,7 +361,7 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
|
|||
ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
|
||||
|
||||
idev->name = "Touchscreen panel";
|
||||
idev->id.product = ts->ucb->id->driver_data;
|
||||
idev->id.product = ts->ucb->id;
|
||||
idev->open = ucb1x00_ts_open;
|
||||
idev->close = ucb1x00_ts_close;
|
||||
|
||||
|
@ -425,7 +404,6 @@ static void ucb1x00_ts_remove(struct ucb1x00_dev *dev)
|
|||
static struct ucb1x00_driver ucb1x00_ts_driver = {
|
||||
.add = ucb1x00_ts_add,
|
||||
.remove = ucb1x00_ts_remove,
|
||||
.resume = ucb1x00_ts_resume,
|
||||
};
|
||||
|
||||
static int __init ucb1x00_ts_init(void)
|
||||
|
|
|
@ -322,9 +322,6 @@ EXPORT_SYMBOL(clear_nlink);
|
|||
void set_nlink(struct inode *inode, unsigned int nlink)
|
||||
{
|
||||
if (!nlink) {
|
||||
printk_ratelimited(KERN_INFO
|
||||
"set_nlink() clearing i_nlink on %s inode %li\n",
|
||||
inode->i_sb->s_type->name, inode->i_ino);
|
||||
clear_nlink(inode);
|
||||
} else {
|
||||
/* Yes, some filesystems do change nlink from zero to one */
|
||||
|
|
|
@ -77,6 +77,8 @@ static int show_stat(struct seq_file *p, void *v)
|
|||
steal += kcpustat_cpu(i).cpustat[CPUTIME_STEAL];
|
||||
guest += kcpustat_cpu(i).cpustat[CPUTIME_GUEST];
|
||||
guest_nice += kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE];
|
||||
sum += kstat_cpu_irqs_sum(i);
|
||||
sum += arch_irq_stat_cpu(i);
|
||||
|
||||
for (j = 0; j < NR_SOFTIRQS; j++) {
|
||||
unsigned int softirq_stat = kstat_softirqs_cpu(j, i);
|
||||
|
|
|
@ -179,47 +179,33 @@ static const char *qnx4_checkroot(struct super_block *sb)
|
|||
struct qnx4_inode_entry *rootdir;
|
||||
int rd, rl;
|
||||
int i, j;
|
||||
int found = 0;
|
||||
|
||||
if (*(qnx4_sb(sb)->sb->RootDir.di_fname) != '/') {
|
||||
if (*(qnx4_sb(sb)->sb->RootDir.di_fname) != '/')
|
||||
return "no qnx4 filesystem (no root dir).";
|
||||
} else {
|
||||
QNX4DEBUG((KERN_NOTICE "QNX4 filesystem found on dev %s.\n", sb->s_id));
|
||||
rd = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_blk) - 1;
|
||||
rl = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_size);
|
||||
for (j = 0; j < rl; j++) {
|
||||
bh = sb_bread(sb, rd + j); /* root dir, first block */
|
||||
if (bh == NULL) {
|
||||
return "unable to read root entry.";
|
||||
}
|
||||
for (i = 0; i < QNX4_INODES_PER_BLOCK; i++) {
|
||||
rootdir = (struct qnx4_inode_entry *) (bh->b_data + i * QNX4_DIR_ENTRY_SIZE);
|
||||
if (rootdir->di_fname != NULL) {
|
||||
QNX4DEBUG((KERN_INFO "rootdir entry found : [%s]\n", rootdir->di_fname));
|
||||
if (!strcmp(rootdir->di_fname,
|
||||
QNX4_BMNAME)) {
|
||||
found = 1;
|
||||
qnx4_sb(sb)->BitMap = kmemdup(rootdir,
|
||||
sizeof(struct qnx4_inode_entry),
|
||||
GFP_KERNEL);
|
||||
if (!qnx4_sb(sb)->BitMap) {
|
||||
brelse (bh);
|
||||
return "not enough memory for bitmap inode";
|
||||
}/* keep bitmap inode known */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
QNX4DEBUG((KERN_NOTICE "QNX4 filesystem found on dev %s.\n", sb->s_id));
|
||||
rd = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_blk) - 1;
|
||||
rl = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_size);
|
||||
for (j = 0; j < rl; j++) {
|
||||
bh = sb_bread(sb, rd + j); /* root dir, first block */
|
||||
if (bh == NULL)
|
||||
return "unable to read root entry.";
|
||||
rootdir = (struct qnx4_inode_entry *) bh->b_data;
|
||||
for (i = 0; i < QNX4_INODES_PER_BLOCK; i++, rootdir++) {
|
||||
QNX4DEBUG((KERN_INFO "rootdir entry found : [%s]\n", rootdir->di_fname));
|
||||
if (strcmp(rootdir->di_fname, QNX4_BMNAME) != 0)
|
||||
continue;
|
||||
qnx4_sb(sb)->BitMap = kmemdup(rootdir,
|
||||
sizeof(struct qnx4_inode_entry),
|
||||
GFP_KERNEL);
|
||||
brelse(bh);
|
||||
if (found != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == 0) {
|
||||
return "bitmap file not found.";
|
||||
if (!qnx4_sb(sb)->BitMap)
|
||||
return "not enough memory for bitmap inode";
|
||||
/* keep bitmap inode known */
|
||||
return NULL;
|
||||
}
|
||||
brelse(bh);
|
||||
}
|
||||
return NULL;
|
||||
return "bitmap file not found.";
|
||||
}
|
||||
|
||||
static int qnx4_fill_super(struct super_block *s, void *data, int silent)
|
||||
|
@ -270,7 +256,7 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent)
|
|||
if (IS_ERR(root)) {
|
||||
printk(KERN_ERR "qnx4: get inode failed\n");
|
||||
ret = PTR_ERR(root);
|
||||
goto out;
|
||||
goto outb;
|
||||
}
|
||||
|
||||
ret = -ENOMEM;
|
||||
|
@ -283,6 +269,8 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent)
|
|||
|
||||
outi:
|
||||
iput(root);
|
||||
outb:
|
||||
kfree(qs->BitMap);
|
||||
out:
|
||||
brelse(bh);
|
||||
outnobh:
|
||||
|
|
|
@ -1186,6 +1186,8 @@ int freeze_super(struct super_block *sb)
|
|||
printk(KERN_ERR
|
||||
"VFS:Filesystem freeze failed\n");
|
||||
sb->s_frozen = SB_UNFROZEN;
|
||||
smp_wmb();
|
||||
wake_up(&sb->s_wait_unfrozen);
|
||||
deactivate_locked_super(sb);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ extern int keyring_add_key(struct key *keyring,
|
|||
|
||||
extern struct key *key_lookup(key_serial_t id);
|
||||
|
||||
static inline key_serial_t key_serial(struct key *key)
|
||||
static inline key_serial_t key_serial(const struct key *key)
|
||||
{
|
||||
return key ? key->serial : 0;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#ifndef MCP_H
|
||||
#define MCP_H
|
||||
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <mach/dma.h>
|
||||
|
||||
struct mcp_ops;
|
||||
|
@ -27,7 +26,7 @@ struct mcp {
|
|||
dma_device_t dma_telco_rd;
|
||||
dma_device_t dma_telco_wr;
|
||||
struct device attached_device;
|
||||
const char *codec;
|
||||
int gpio_base;
|
||||
};
|
||||
|
||||
struct mcp_ops {
|
||||
|
@ -45,11 +44,10 @@ void mcp_reg_write(struct mcp *, unsigned int, unsigned int);
|
|||
unsigned int mcp_reg_read(struct mcp *, unsigned int);
|
||||
void mcp_enable(struct mcp *);
|
||||
void mcp_disable(struct mcp *);
|
||||
const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp);
|
||||
#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
|
||||
|
||||
struct mcp *mcp_host_alloc(struct device *, size_t);
|
||||
int mcp_host_register(struct mcp *, void *);
|
||||
int mcp_host_register(struct mcp *);
|
||||
void mcp_host_unregister(struct mcp *);
|
||||
|
||||
struct mcp_driver {
|
||||
|
@ -58,7 +56,6 @@ struct mcp_driver {
|
|||
void (*remove)(struct mcp *);
|
||||
int (*suspend)(struct mcp *, pm_message_t);
|
||||
int (*resume)(struct mcp *);
|
||||
const struct mcp_device_id *id_table;
|
||||
};
|
||||
|
||||
int mcp_driver_register(struct mcp_driver *);
|
||||
|
@ -67,6 +64,9 @@ void mcp_driver_unregister(struct mcp_driver *);
|
|||
#define mcp_get_drvdata(mcp) dev_get_drvdata(&(mcp)->attached_device)
|
||||
#define mcp_set_drvdata(mcp,d) dev_set_drvdata(&(mcp)->attached_device, d)
|
||||
|
||||
#define mcp_priv(mcp) ((void *)((mcp)+1))
|
||||
static inline void *mcp_priv(struct mcp *mcp)
|
||||
{
|
||||
return mcp + 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -104,9 +104,6 @@
|
|||
#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
|
||||
#define UCB_MODE_AUD_OFF_CAN (1 << 13)
|
||||
|
||||
struct ucb1x00_plat_data {
|
||||
int gpio_base;
|
||||
};
|
||||
|
||||
struct ucb1x00_irq {
|
||||
void *devid;
|
||||
|
@ -119,7 +116,7 @@ struct ucb1x00 {
|
|||
unsigned int irq;
|
||||
struct semaphore adc_sem;
|
||||
spinlock_t io_lock;
|
||||
const struct mcp_device_id *id;
|
||||
u16 id;
|
||||
u16 io_dir;
|
||||
u16 io_out;
|
||||
u16 adc_cr;
|
||||
|
|
|
@ -436,17 +436,6 @@ struct spi_device_id {
|
|||
__attribute__((aligned(sizeof(kernel_ulong_t))));
|
||||
};
|
||||
|
||||
/* mcp */
|
||||
|
||||
#define MCP_NAME_SIZE 20
|
||||
#define MCP_MODULE_PREFIX "mcp:"
|
||||
|
||||
struct mcp_device_id {
|
||||
char name[MCP_NAME_SIZE];
|
||||
kernel_ulong_t driver_data /* Data private to the driver */
|
||||
__attribute__((aligned(sizeof(kernel_ulong_t))));
|
||||
};
|
||||
|
||||
/* dmi */
|
||||
enum dmi_field {
|
||||
DMI_NONE,
|
||||
|
|
|
@ -634,10 +634,11 @@ static int tracepoint_module_coming(struct module *mod)
|
|||
int ret = 0;
|
||||
|
||||
/*
|
||||
* We skip modules that tain the kernel, especially those with different
|
||||
* module header (for forced load), to make sure we don't cause a crash.
|
||||
* We skip modules that taint the kernel, especially those with different
|
||||
* module headers (for forced load), to make sure we don't cause a crash.
|
||||
* Staging and out-of-tree GPL modules are fine.
|
||||
*/
|
||||
if (mod->taints)
|
||||
if (mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP)))
|
||||
return 0;
|
||||
mutex_lock(&tracepoints_mutex);
|
||||
tp_mod = kmalloc(sizeof(struct tp_module), GFP_KERNEL);
|
||||
|
|
|
@ -255,6 +255,8 @@ void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign)
|
|||
if (!n)
|
||||
n++; /* avoid zero length allocation */
|
||||
p = buffer = kmalloc(n, GFP_KERNEL);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
for (i = a->nlimbs - 1; i >= 0; i--) {
|
||||
alimb = a->d[i];
|
||||
|
|
|
@ -823,16 +823,6 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id,
|
|||
}
|
||||
ADD_TO_DEVTABLE("spi", struct spi_device_id, do_spi_entry);
|
||||
|
||||
/* Looks like: mcp:S */
|
||||
static int do_mcp_entry(const char *filename, struct mcp_device_id *id,
|
||||
char *alias)
|
||||
{
|
||||
sprintf(alias, MCP_MODULE_PREFIX "%s", id->name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
ADD_TO_DEVTABLE("mcp", struct mcp_device_id, do_mcp_entry);
|
||||
|
||||
static const struct dmifield {
|
||||
const char *prefix;
|
||||
int field;
|
||||
|
|
|
@ -99,6 +99,7 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
|
|||
struct inode *inode, enum ima_hooks func, int mask)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
const struct cred *cred = current_cred();
|
||||
int i;
|
||||
|
||||
if ((rule->flags & IMA_FUNC) && rule->func != func)
|
||||
|
@ -108,7 +109,7 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
|
|||
if ((rule->flags & IMA_FSMAGIC)
|
||||
&& rule->fsmagic != inode->i_sb->s_magic)
|
||||
return false;
|
||||
if ((rule->flags & IMA_UID) && rule->uid != tsk->cred->uid)
|
||||
if ((rule->flags & IMA_UID) && rule->uid != cred->uid)
|
||||
return false;
|
||||
for (i = 0; i < MAX_LSM_RULES; i++) {
|
||||
int rc = 0;
|
||||
|
|
|
@ -59,7 +59,7 @@ int user_instantiate(struct key *key, const void *data, size_t datalen)
|
|||
/* attach the data */
|
||||
upayload->datalen = datalen;
|
||||
memcpy(upayload->data, data, datalen);
|
||||
rcu_assign_pointer(key->payload.data, upayload);
|
||||
rcu_assign_keypointer(key, upayload);
|
||||
ret = 0;
|
||||
|
||||
error:
|
||||
|
@ -98,7 +98,7 @@ int user_update(struct key *key, const void *data, size_t datalen)
|
|||
if (ret == 0) {
|
||||
/* attach the new data, displacing the old */
|
||||
zap = key->payload.data;
|
||||
rcu_assign_pointer(key->payload.data, upayload);
|
||||
rcu_assign_keypointer(key, upayload);
|
||||
key->expiry = 0;
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ void user_revoke(struct key *key)
|
|||
key_payload_reserve(key, 0);
|
||||
|
||||
if (upayload) {
|
||||
rcu_assign_pointer(key->payload.data, NULL);
|
||||
rcu_assign_keypointer(key, NULL);
|
||||
kfree_rcu(upayload, rcu);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче