You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'linus' into cpus4096
Conflicts: kernel/stop_machine.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
@@ -528,7 +528,33 @@ See more details on the proper patch format in the following
|
||||
references.
|
||||
|
||||
|
||||
16) Sending "git pull" requests (from Linus emails)
|
||||
|
||||
Please write the git repo address and branch name alone on the same line
|
||||
so that I can't even by mistake pull from the wrong branch, and so
|
||||
that a triple-click just selects the whole thing.
|
||||
|
||||
So the proper format is something along the lines of:
|
||||
|
||||
"Please pull from
|
||||
|
||||
git://jdelvare.pck.nerim.net/jdelvare-2.6 i2c-for-linus
|
||||
|
||||
to get these changes:"
|
||||
|
||||
so that I don't have to hunt-and-peck for the address and inevitably
|
||||
get it wrong (actually, I've only gotten it wrong a few times, and
|
||||
checking against the diffstat tells me when I get it wrong, but I'm
|
||||
just a lot more comfortable when I don't have to "look for" the right
|
||||
thing to pull, and double-check that I have the right branch-name).
|
||||
|
||||
|
||||
Please use "git diff -M --stat --summary" to generate the diffstat:
|
||||
the -M enables rename detection, and the summary enables a summary of
|
||||
new/deleted or renamed files.
|
||||
|
||||
With rename detection, the statistics are rather different [...]
|
||||
because git will notice that a fair number of the changes are renames.
|
||||
|
||||
-----------------------------------
|
||||
SECTION 2 - HINTS, TIPS, AND TRICKS
|
||||
|
||||
@@ -47,6 +47,30 @@ Who: Mauro Carvalho Chehab <mchehab@infradead.org>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: old tuner-3036 i2c driver
|
||||
When: 2.6.28
|
||||
Why: This driver is for VERY old i2c-over-parallel port teletext receiver
|
||||
boxes. Rather then spending effort on converting this driver to V4L2,
|
||||
and since it is extremely unlikely that anyone still uses one of these
|
||||
devices, it was decided to drop it.
|
||||
Who: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
Mauro Carvalho Chehab <mchehab@infradead.org>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: V4L2 dpc7146 driver
|
||||
When: 2.6.28
|
||||
Why: Old driver for the dpc7146 demonstration board that is no longer
|
||||
relevant. The last time this was tested on actual hardware was
|
||||
probably around 2002. Since this is a driver for a demonstration
|
||||
board the decision was made to remove it rather than spending a
|
||||
lot of effort continually updating this driver to stay in sync
|
||||
with the latest internal V4L2 or I2C API.
|
||||
Who: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
Mauro Carvalho Chehab <mchehab@infradead.org>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
|
||||
When: November 2005
|
||||
Files: drivers/pcmcia/: pcmcia_ioctl.c
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
Upgrading I2C Drivers to the new 2.6 Driver Model
|
||||
=================================================
|
||||
|
||||
Ben Dooks <ben-linux@fluff.org>
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This guide outlines how to alter existing Linux 2.6 client drivers from
|
||||
the old to the new new binding methods.
|
||||
|
||||
|
||||
Example old-style driver
|
||||
------------------------
|
||||
|
||||
|
||||
struct example_state {
|
||||
struct i2c_client client;
|
||||
....
|
||||
};
|
||||
|
||||
static struct i2c_driver example_driver;
|
||||
|
||||
static unsigned short ignore[] = { I2C_CLIENT_END };
|
||||
static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
|
||||
|
||||
I2C_CLIENT_INSMOD;
|
||||
|
||||
static int example_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||
{
|
||||
struct example_state *state;
|
||||
struct device *dev = &adap->dev; /* to use for dev_ reports */
|
||||
int ret;
|
||||
|
||||
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
|
||||
if (state == NULL) {
|
||||
dev_err(dev, "failed to create our state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
example->client.addr = addr;
|
||||
example->client.flags = 0;
|
||||
example->client.adapter = adap;
|
||||
|
||||
i2c_set_clientdata(&state->i2c_client, state);
|
||||
strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE);
|
||||
|
||||
ret = i2c_attach_client(&state->i2c_client);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to attach client\n");
|
||||
kfree(state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev = &state->i2c_client.dev;
|
||||
|
||||
/* rest of the initialisation goes here. */
|
||||
|
||||
dev_info(dev, "example client created\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit example_detach(struct i2c_client *client)
|
||||
{
|
||||
struct example_state *state = i2c_get_clientdata(client);
|
||||
|
||||
i2c_detach_client(client);
|
||||
kfree(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int example_attach_adapter(struct i2c_adapter *adap)
|
||||
{
|
||||
return i2c_probe(adap, &addr_data, example_attach);
|
||||
}
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "example",
|
||||
},
|
||||
.attach_adapter = example_attach_adapter,
|
||||
.detach_client = __devexit_p(example_detach),
|
||||
.suspend = example_suspend,
|
||||
.resume = example_resume,
|
||||
};
|
||||
|
||||
|
||||
Updating the client
|
||||
-------------------
|
||||
|
||||
The new style binding model will check against a list of supported
|
||||
devices and their associated address supplied by the code registering
|
||||
the busses. This means that the driver .attach_adapter and
|
||||
.detach_adapter methods can be removed, along with the addr_data,
|
||||
as follows:
|
||||
|
||||
- static struct i2c_driver example_driver;
|
||||
|
||||
- static unsigned short ignore[] = { I2C_CLIENT_END };
|
||||
- static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
|
||||
|
||||
- I2C_CLIENT_INSMOD;
|
||||
|
||||
- static int example_attach_adapter(struct i2c_adapter *adap)
|
||||
- {
|
||||
- return i2c_probe(adap, &addr_data, example_attach);
|
||||
- }
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
- .attach_adapter = example_attach_adapter,
|
||||
- .detach_client = __devexit_p(example_detach),
|
||||
}
|
||||
|
||||
Add the probe and remove methods to the i2c_driver, as so:
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
+ .probe = example_probe,
|
||||
+ .remove = __devexit_p(example_remove),
|
||||
}
|
||||
|
||||
Change the example_attach method to accept the new parameters
|
||||
which include the i2c_client that it will be working with:
|
||||
|
||||
- static int example_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||
+ static int example_probe(struct i2c_client *client,
|
||||
+ const struct i2c_device_id *id)
|
||||
|
||||
Change the name of example_attach to example_probe to align it with the
|
||||
i2c_driver entry names. The rest of the probe routine will now need to be
|
||||
changed as the i2c_client has already been setup for use.
|
||||
|
||||
The necessary client fields have already been setup before
|
||||
the probe function is called, so the following client setup
|
||||
can be removed:
|
||||
|
||||
- example->client.addr = addr;
|
||||
- example->client.flags = 0;
|
||||
- example->client.adapter = adap;
|
||||
-
|
||||
- strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE);
|
||||
|
||||
The i2c_set_clientdata is now:
|
||||
|
||||
- i2c_set_clientdata(&state->client, state);
|
||||
+ i2c_set_clientdata(client, state);
|
||||
|
||||
The call to i2c_attach_client is no longer needed, if the probe
|
||||
routine exits successfully, then the driver will be automatically
|
||||
attached by the core. Change the probe routine as so:
|
||||
|
||||
- ret = i2c_attach_client(&state->i2c_client);
|
||||
- if (ret < 0) {
|
||||
- dev_err(dev, "failed to attach client\n");
|
||||
- kfree(state);
|
||||
- return ret;
|
||||
- }
|
||||
|
||||
|
||||
Remove the storage of 'struct i2c_client' from the 'struct example_state'
|
||||
as we are provided with the i2c_client in our example_probe. Instead we
|
||||
store a pointer to it for when it is needed.
|
||||
|
||||
struct example_state {
|
||||
- struct i2c_client client;
|
||||
+ struct i2c_client *client;
|
||||
|
||||
the new i2c client as so:
|
||||
|
||||
- struct device *dev = &adap->dev; /* to use for dev_ reports */
|
||||
+ struct device *dev = &i2c_client->dev; /* to use for dev_ reports */
|
||||
|
||||
And remove the change after our client is attached, as the driver no
|
||||
longer needs to register a new client structure with the core:
|
||||
|
||||
- dev = &state->i2c_client.dev;
|
||||
|
||||
In the probe routine, ensure that the new state has the client stored
|
||||
in it:
|
||||
|
||||
static int example_probe(struct i2c_client *i2c_client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct example_state *state;
|
||||
struct device *dev = &i2c_client->dev;
|
||||
int ret;
|
||||
|
||||
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
|
||||
if (state == NULL) {
|
||||
dev_err(dev, "failed to create our state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
+ state->client = i2c_client;
|
||||
|
||||
Update the detach method, by changing the name to _remove and
|
||||
to delete the i2c_detach_client call. It is possible that you
|
||||
can also remove the ret variable as it is not not needed for
|
||||
any of the core functions.
|
||||
|
||||
- static int __devexit example_detach(struct i2c_client *client)
|
||||
+ static int __devexit example_remove(struct i2c_client *client)
|
||||
{
|
||||
struct example_state *state = i2c_get_clientdata(client);
|
||||
|
||||
- i2c_detach_client(client);
|
||||
|
||||
And finally ensure that we have the correct ID table for the i2c-core
|
||||
and other utilities:
|
||||
|
||||
+ struct i2c_device_id example_idtable[] = {
|
||||
+ { "example", 0 },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(i2c, example_idtable);
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "example",
|
||||
},
|
||||
+ .id_table = example_ids,
|
||||
|
||||
|
||||
Our driver should now look like this:
|
||||
|
||||
struct example_state {
|
||||
struct i2c_client *client;
|
||||
....
|
||||
};
|
||||
|
||||
static int example_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct example_state *state;
|
||||
struct device *dev = &client->dev;
|
||||
|
||||
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
|
||||
if (state == NULL) {
|
||||
dev_err(dev, "failed to create our state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
state->client = client;
|
||||
i2c_set_clientdata(client, state);
|
||||
|
||||
/* rest of the initialisation goes here. */
|
||||
|
||||
dev_info(dev, "example client created\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit example_remove(struct i2c_client *client)
|
||||
{
|
||||
struct example_state *state = i2c_get_clientdata(client);
|
||||
|
||||
kfree(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_device_id example_idtable[] = {
|
||||
{ "example", 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, example_idtable);
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "example",
|
||||
},
|
||||
.id_table = example_idtable,
|
||||
.probe = example_probe,
|
||||
.remove = __devexit_p(example_remove),
|
||||
.suspend = example_suspend,
|
||||
.resume = example_resume,
|
||||
};
|
||||
@@ -2,3 +2,4 @@
|
||||
1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008]
|
||||
2 -> Hauppauge HVR850 (au0828) [2040:7240]
|
||||
3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620]
|
||||
4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281]
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800]
|
||||
1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2750,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
|
||||
1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
|
||||
2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036]
|
||||
3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
|
||||
4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201]
|
||||
5 -> MSI VOX USB 2.0 (em2820/em2840)
|
||||
6 -> Terratec Cinergy 200 USB (em2800)
|
||||
7 -> Leadtek Winfast USB II (em2800)
|
||||
7 -> Leadtek Winfast USB II (em2800) [0413:6023]
|
||||
8 -> Kworld USB2800 (em2800)
|
||||
9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a]
|
||||
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
|
||||
@@ -14,7 +14,46 @@
|
||||
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
|
||||
14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
|
||||
15 -> V-Gear PocketTV (em2800)
|
||||
16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f]
|
||||
16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b,2040:651f]
|
||||
17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227]
|
||||
18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502]
|
||||
19 -> PointNix Intra-Oral Camera (em2860)
|
||||
20 -> AMD ATI TV Wonder HD 600 (em2880) [0438:b002]
|
||||
21 -> eMPIA Technology, Inc. GrabBeeX+ Video Encoder (em2800) [eb1a:2801]
|
||||
22 -> Unknown EM2750/EM2751 webcam grabber (em2750) [eb1a:2750,eb1a:2751]
|
||||
23 -> Huaqi DLCW-130 (em2750)
|
||||
24 -> D-Link DUB-T210 TV Tuner (em2820/em2840) [2001:f112]
|
||||
25 -> Gadmei UTV310 (em2820/em2840)
|
||||
26 -> Hercules Smart TV USB 2.0 (em2820/em2840)
|
||||
27 -> Pinnacle PCTV USB 2 (Philips FM1216ME) (em2820/em2840)
|
||||
28 -> Leadtek Winfast USB II Deluxe (em2820/em2840)
|
||||
29 -> Pinnacle Dazzle DVC 100 (em2820/em2840)
|
||||
30 -> Videology 20K14XUSB USB2.0 (em2820/em2840)
|
||||
31 -> Usbgear VD204v9 (em2821)
|
||||
32 -> Supercomp USB 2.0 TV (em2821)
|
||||
33 -> SIIG AVTuner-PVR/Prolink PlayTV USB 2.0 (em2821)
|
||||
34 -> Terratec Cinergy A Hybrid XS (em2860) [0ccd:004f]
|
||||
35 -> Typhoon DVD Maker (em2860)
|
||||
36 -> NetGMBH Cam (em2860)
|
||||
37 -> Gadmei UTV330 (em2860)
|
||||
38 -> Yakumo MovieMixer (em2861)
|
||||
39 -> KWorld PVRTV 300U (em2861) [eb1a:e300]
|
||||
40 -> Plextor ConvertX PX-TV100U (em2861) [093b:a005]
|
||||
41 -> Kworld 350 U DVB-T (em2870) [eb1a:e350]
|
||||
42 -> Kworld 355 U DVB-T (em2870) [eb1a:e355,eb1a:e357]
|
||||
43 -> Terratec Cinergy T XS (em2870) [0ccd:0043]
|
||||
44 -> Terratec Cinergy T XS (MT2060) (em2870)
|
||||
45 -> Pinnacle PCTV DVB-T (em2870)
|
||||
46 -> Compro, VideoMate U3 (em2870) [185b:2870]
|
||||
47 -> KWorld DVB-T 305U (em2880) [eb1a:e305]
|
||||
48 -> KWorld DVB-T 310U (em2880)
|
||||
49 -> MSI DigiVox A/D (em2880) [eb1a:e310]
|
||||
50 -> MSI DigiVox A/D II (em2880) [eb1a:e320]
|
||||
51 -> Terratec Hybrid XS Secam (em2880) [0ccd:004c]
|
||||
52 -> DNT DA2 Hybrid (em2881)
|
||||
53 -> Pinnacle Hybrid Pro (em2881)
|
||||
54 -> Kworld VS-DVB-T 323UR (em2882) [eb1a:e323]
|
||||
55 -> Terratec Hybrid XS (em2882) (em2882) [0ccd:005e]
|
||||
56 -> Pinnacle Hybrid Pro (2) (em2882) [2304:0226]
|
||||
57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316]
|
||||
58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
List of the webcams know by gspca.
|
||||
List of the webcams known by gspca.
|
||||
|
||||
The modules are:
|
||||
gspca_main main driver
|
||||
|
||||
@@ -3796,6 +3796,12 @@ P: Ben Nizette
|
||||
M: bn@niasdigital.com
|
||||
S: Maintained
|
||||
|
||||
SOC-CAMERA V4L2 SUBSYSTEM
|
||||
P: Guennadi Liakhovetski
|
||||
M: g.liakhovetski@gmx.de
|
||||
L: video4linux-list@redhat.com
|
||||
S: Maintained
|
||||
|
||||
SOFTWARE RAID (Multiple Disks) SUPPORT
|
||||
P: Ingo Molnar
|
||||
M: mingo@redhat.com
|
||||
|
||||
@@ -206,7 +206,11 @@ ifeq ($(ARCH),x86_64)
|
||||
endif
|
||||
|
||||
# Where to locate arch specific headers
|
||||
hdr-arch := $(SRCARCH)
|
||||
ifeq ($(ARCH),sparc64)
|
||||
hdr-arch := sparc
|
||||
else
|
||||
hdr-arch := $(SRCARCH)
|
||||
endif
|
||||
|
||||
KCONFIG_CONFIG ?= .config
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@ config PPC
|
||||
select HAVE_KPROBES
|
||||
select HAVE_ARCH_KGDB
|
||||
select HAVE_KRETPROBES
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_LMB
|
||||
select HAVE_DMA_ATTRS if PPC64
|
||||
select USE_GENERIC_SMP_HELPERS if SMP
|
||||
|
||||
@@ -148,7 +148,7 @@ transfer_to_handler:
|
||||
/* Check to see if the dbcr0 register is set up to debug. Use the
|
||||
internal debug mode bit to do this. */
|
||||
lwz r12,THREAD_DBCR0(r12)
|
||||
andis. r12,r12,(DBCR0_IDM | DBSR_DAC1R | DBSR_DAC1W)@h
|
||||
andis. r12,r12,DBCR0_IDM@h
|
||||
beq+ 3f
|
||||
/* From user and task is ptraced - load up global dbcr0 */
|
||||
li r12,-1 /* clear all pending debug events */
|
||||
@@ -292,7 +292,7 @@ syscall_exit_cont:
|
||||
/* If the process has its own DBCR0 value, load it up. The internal
|
||||
debug mode bit tells us that dbcr0 should be loaded. */
|
||||
lwz r0,THREAD+THREAD_DBCR0(r2)
|
||||
andis. r10,r0,(DBCR0_IDM | DBSR_DAC1R | DBSR_DAC1W)@h
|
||||
andis. r10,r0,DBCR0_IDM@h
|
||||
bnel- load_dbcr0
|
||||
#endif
|
||||
#ifdef CONFIG_44x
|
||||
@@ -343,7 +343,12 @@ syscall_dotrace:
|
||||
stw r0,_TRAP(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl do_syscall_trace_enter
|
||||
lwz r0,GPR0(r1) /* Restore original registers */
|
||||
/*
|
||||
* Restore argument registers possibly just changed.
|
||||
* We use the return value of do_syscall_trace_enter
|
||||
* for call number to look up in the table (r0).
|
||||
*/
|
||||
mr r0,r3
|
||||
lwz r3,GPR3(r1)
|
||||
lwz r4,GPR4(r1)
|
||||
lwz r5,GPR5(r1)
|
||||
@@ -720,7 +725,7 @@ restore_user:
|
||||
/* Check whether this process has its own DBCR0 value. The internal
|
||||
debug mode bit tells us that dbcr0 should be loaded. */
|
||||
lwz r0,THREAD+THREAD_DBCR0(r2)
|
||||
andis. r10,r0,(DBCR0_IDM | DBSR_DAC1R | DBSR_DAC1W)@h
|
||||
andis. r10,r0,DBCR0_IDM@h
|
||||
bnel- load_dbcr0
|
||||
#endif
|
||||
|
||||
@@ -1055,8 +1060,8 @@ do_user_signal: /* r10 contains MSR_KERNEL here */
|
||||
SAVE_NVGPRS(r1)
|
||||
rlwinm r3,r3,0,0,30
|
||||
stw r3,_TRAP(r1)
|
||||
2: li r3,0
|
||||
addi r4,r1,STACK_FRAME_OVERHEAD
|
||||
2: addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
mr r4,r9
|
||||
bl do_signal
|
||||
REST_NVGPRS(r1)
|
||||
b recheck
|
||||
|
||||
@@ -214,7 +214,12 @@ syscall_dotrace:
|
||||
bl .save_nvgprs
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl .do_syscall_trace_enter
|
||||
ld r0,GPR0(r1) /* Restore original registers */
|
||||
/*
|
||||
* Restore argument registers possibly just changed.
|
||||
* We use the return value of do_syscall_trace_enter
|
||||
* for the call number to look up in the table (r0).
|
||||
*/
|
||||
mr r0,r3
|
||||
ld r3,GPR3(r1)
|
||||
ld r4,GPR4(r1)
|
||||
ld r5,GPR5(r1)
|
||||
@@ -638,8 +643,7 @@ user_work:
|
||||
b .ret_from_except_lite
|
||||
|
||||
1: bl .save_nvgprs
|
||||
li r3,0
|
||||
addi r4,r1,STACK_FRAME_OVERHEAD
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl .do_signal
|
||||
b .ret_from_except
|
||||
|
||||
|
||||
@@ -493,18 +493,18 @@ static int __init serial_dev_init(void)
|
||||
device_initcall(serial_dev_init);
|
||||
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
||||
/*
|
||||
* This is called very early, as part of console_init() (typically just after
|
||||
* time_init()). This function is respondible for trying to find a good
|
||||
* default console on serial ports. It tries to match the open firmware
|
||||
* default output with one of the available serial console drivers, either
|
||||
* one of the platform serial ports that have been probed earlier by
|
||||
* find_legacy_serial_ports() or some more platform specific ones.
|
||||
* default output with one of the available serial console drivers that have
|
||||
* been probed earlier by find_legacy_serial_ports()
|
||||
*/
|
||||
static int __init check_legacy_serial_console(void)
|
||||
{
|
||||
struct device_node *prom_stdout = NULL;
|
||||
int speed = 0, offset = 0;
|
||||
int i, speed = 0, offset = 0;
|
||||
const char *name;
|
||||
const u32 *spd;
|
||||
|
||||
@@ -548,31 +548,20 @@ static int __init check_legacy_serial_console(void)
|
||||
if (spd)
|
||||
speed = *spd;
|
||||
|
||||
if (0)
|
||||
;
|
||||
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
||||
else if (strcmp(name, "serial") == 0) {
|
||||
int i;
|
||||
/* Look for it in probed array */
|
||||
for (i = 0; i < legacy_serial_count; i++) {
|
||||
if (prom_stdout != legacy_serial_infos[i].np)
|
||||
continue;
|
||||
offset = i;
|
||||
speed = legacy_serial_infos[i].speed;
|
||||
break;
|
||||
}
|
||||
if (i >= legacy_serial_count)
|
||||
goto not_found;
|
||||
}
|
||||
#endif /* CONFIG_SERIAL_8250_CONSOLE */
|
||||
#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
|
||||
else if (strcmp(name, "ch-a") == 0)
|
||||
offset = 0;
|
||||
else if (strcmp(name, "ch-b") == 0)
|
||||
offset = 1;
|
||||
#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
|
||||
else
|
||||
if (strcmp(name, "serial") != 0)
|
||||
goto not_found;
|
||||
|
||||
/* Look for it in probed array */
|
||||
for (i = 0; i < legacy_serial_count; i++) {
|
||||
if (prom_stdout != legacy_serial_infos[i].np)
|
||||
continue;
|
||||
offset = i;
|
||||
speed = legacy_serial_infos[i].speed;
|
||||
break;
|
||||
}
|
||||
if (i >= legacy_serial_count)
|
||||
goto not_found;
|
||||
|
||||
of_node_put(prom_stdout);
|
||||
|
||||
DBG("Found serial console at ttyS%d\n", offset);
|
||||
@@ -591,3 +580,4 @@ static int __init check_legacy_serial_console(void)
|
||||
}
|
||||
console_initcall(check_legacy_serial_console);
|
||||
|
||||
#endif /* CONFIG_SERIAL_8250_CONSOLE */
|
||||
|
||||
@@ -254,7 +254,7 @@ void do_dabr(struct pt_regs *regs, unsigned long address,
|
||||
return;
|
||||
|
||||
/* Clear the DAC and struct entries. One shot trigger */
|
||||
#if (defined(CONFIG_44x) || defined(CONFIG_BOOKE))
|
||||
#if defined(CONFIG_BOOKE)
|
||||
mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBSR_DAC1R | DBSR_DAC1W
|
||||
| DBCR0_IDM));
|
||||
#endif
|
||||
@@ -286,7 +286,7 @@ int set_dabr(unsigned long dabr)
|
||||
mtspr(SPRN_DABR, dabr);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_44x) || defined(CONFIG_BOOKE)
|
||||
#if defined(CONFIG_BOOKE)
|
||||
mtspr(SPRN_DAC1, dabr);
|
||||
#endif
|
||||
|
||||
@@ -373,7 +373,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
|
||||
if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
|
||||
set_dabr(new->thread.dabr);
|
||||
|
||||
#if defined(CONFIG_44x) || defined(CONFIG_BOOKE)
|
||||
#if defined(CONFIG_BOOKE)
|
||||
/* If new thread DAC (HW breakpoint) is the same then leave it */
|
||||
if (new->thread.dabr)
|
||||
set_dabr(new->thread.dabr);
|
||||
@@ -568,7 +568,7 @@ void flush_thread(void)
|
||||
current->thread.dabr = 0;
|
||||
set_dabr(0);
|
||||
|
||||
#if defined(CONFIG_44x) || defined(CONFIG_BOOKE)
|
||||
#if defined(CONFIG_BOOKE)
|
||||
current->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -205,8 +205,6 @@ static int __initdata mem_reserve_cnt;
|
||||
static cell_t __initdata regbuf[1024];
|
||||
|
||||
|
||||
#define MAX_CPU_THREADS 2
|
||||
|
||||
/*
|
||||
* Error results ... some OF calls will return "-1" on error, some
|
||||
* will return 0, some will return either. To simplify, here are
|
||||
@@ -1339,10 +1337,6 @@ static void __init prom_hold_cpus(void)
|
||||
unsigned int reg;
|
||||
phandle node;
|
||||
char type[64];
|
||||
int cpuid = 0;
|
||||
unsigned int interrupt_server[MAX_CPU_THREADS];
|
||||
unsigned int cpu_threads, hw_cpu_num;
|
||||
int propsize;
|
||||
struct prom_t *_prom = &RELOC(prom);
|
||||
unsigned long *spinloop
|
||||
= (void *) LOW_ADDR(__secondary_hold_spinloop);
|
||||
@@ -1386,7 +1380,6 @@ static void __init prom_hold_cpus(void)
|
||||
reg = -1;
|
||||
prom_getprop(node, "reg", ®, sizeof(reg));
|
||||
|
||||
prom_debug("\ncpuid = 0x%x\n", cpuid);
|
||||
prom_debug("cpu hw idx = 0x%x\n", reg);
|
||||
|
||||
/* Init the acknowledge var which will be reset by
|
||||
@@ -1395,28 +1388,9 @@ static void __init prom_hold_cpus(void)
|
||||
*/
|
||||
*acknowledge = (unsigned long)-1;
|
||||
|
||||
propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
|
||||
&interrupt_server,
|
||||
sizeof(interrupt_server));
|
||||
if (propsize < 0) {
|
||||
/* no property. old hardware has no SMT */
|
||||
cpu_threads = 1;
|
||||
interrupt_server[0] = reg; /* fake it with phys id */
|
||||
} else {
|
||||
/* We have a threaded processor */
|
||||
cpu_threads = propsize / sizeof(u32);
|
||||
if (cpu_threads > MAX_CPU_THREADS) {
|
||||
prom_printf("SMT: too many threads!\n"
|
||||
"SMT: found %x, max is %x\n",
|
||||
cpu_threads, MAX_CPU_THREADS);
|
||||
cpu_threads = 1; /* ToDo: panic? */
|
||||
}
|
||||
}
|
||||
|
||||
hw_cpu_num = interrupt_server[0];
|
||||
if (hw_cpu_num != _prom->cpu) {
|
||||
if (reg != _prom->cpu) {
|
||||
/* Primary Thread of non-boot cpu */
|
||||
prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
|
||||
prom_printf("starting cpu hw idx %x... ", reg);
|
||||
call_prom("start-cpu", 3, 0, node,
|
||||
secondary_hold, reg);
|
||||
|
||||
@@ -1431,17 +1405,10 @@ static void __init prom_hold_cpus(void)
|
||||
}
|
||||
#ifdef CONFIG_SMP
|
||||
else
|
||||
prom_printf("%x : boot cpu %x\n", cpuid, reg);
|
||||
prom_printf("boot cpu hw idx %x\n", reg);
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
/* Reserve cpu #s for secondary threads. They start later. */
|
||||
cpuid += cpu_threads;
|
||||
}
|
||||
|
||||
if (cpuid > NR_CPUS)
|
||||
prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
|
||||
") exceeded: ignoring extras\n");
|
||||
|
||||
prom_debug("prom_hold_cpus: end...\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/regset.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/security.h>
|
||||
@@ -717,7 +718,7 @@ void user_disable_single_step(struct task_struct *task)
|
||||
struct pt_regs *regs = task->thread.regs;
|
||||
|
||||
|
||||
#if defined(CONFIG_44x) || defined(CONFIG_BOOKE)
|
||||
#if defined(CONFIG_BOOKE)
|
||||
/* If DAC then do not single step, skip */
|
||||
if (task->thread.dabr)
|
||||
return;
|
||||
@@ -744,10 +745,11 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
|
||||
if (addr > 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* The bottom 3 bits in dabr are flags */
|
||||
if ((data & ~0x7UL) >= TASK_SIZE)
|
||||
return -EIO;
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
#ifndef CONFIG_BOOKE
|
||||
|
||||
/* For processors using DABR (i.e. 970), the bottom 3 bits are flags.
|
||||
* It was assumed, on previous implementations, that 3 bits were
|
||||
@@ -769,7 +771,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
|
||||
task->thread.dabr = data;
|
||||
|
||||
#endif
|
||||
#if defined(CONFIG_44x) || defined(CONFIG_BOOKE)
|
||||
#if defined(CONFIG_BOOKE)
|
||||
|
||||
/* As described above, it was assumed 3 bits were passed with the data
|
||||
* address, but we will assume only the mode bits will be passed
|
||||
@@ -1013,31 +1015,24 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void do_syscall_trace(void)
|
||||
/*
|
||||
* We must return the syscall number to actually look up in the table.
|
||||
* This can be -1L to skip running any syscall at all.
|
||||
*/
|
||||
long do_syscall_trace_enter(struct pt_regs *regs)
|
||||
{
|
||||
/* the 0x80 provides a way for the tracing parent to distinguish
|
||||
between a syscall stop and SIGTRAP delivery */
|
||||
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
|
||||
? 0x80 : 0));
|
||||
long ret = 0;
|
||||
|
||||
/*
|
||||
* this isn't the same as continuing with a signal, but it will do
|
||||
* for normal use. strace only continues with a signal if the
|
||||
* stopping signal is not SIGTRAP. -brl
|
||||
*/
|
||||
if (current->exit_code) {
|
||||
send_sig(current->exit_code, current, 1);
|
||||
current->exit_code = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void do_syscall_trace_enter(struct pt_regs *regs)
|
||||
{
|
||||
secure_computing(regs->gpr[0]);
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE)
|
||||
&& (current->ptrace & PT_PTRACED))
|
||||
do_syscall_trace();
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||
tracehook_report_syscall_entry(regs))
|
||||
/*
|
||||
* Tracing decided this syscall should not happen.
|
||||
* We'll return a bogus call number to get an ENOSYS
|
||||
* error, but leave the original number in regs->gpr[0].
|
||||
*/
|
||||
ret = -1L;
|
||||
|
||||
if (unlikely(current->audit_context)) {
|
||||
#ifdef CONFIG_PPC64
|
||||
@@ -1055,16 +1050,19 @@ void do_syscall_trace_enter(struct pt_regs *regs)
|
||||
regs->gpr[5] & 0xffffffff,
|
||||
regs->gpr[6] & 0xffffffff);
|
||||
}
|
||||
|
||||
return ret ?: regs->gpr[0];
|
||||
}
|
||||
|
||||
void do_syscall_trace_leave(struct pt_regs *regs)
|
||||
{
|
||||
int step;
|
||||
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
|
||||
regs->result);
|
||||
|
||||
if ((test_thread_flag(TIF_SYSCALL_TRACE)
|
||||
|| test_thread_flag(TIF_SINGLESTEP))
|
||||
&& (current->ptrace & PT_PTRACED))
|
||||
do_syscall_trace();
|
||||
step = test_thread_flag(TIF_SINGLESTEP);
|
||||
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall_exit(regs, step);
|
||||
}
|
||||
|
||||
@@ -367,7 +367,6 @@ static void __init cpu_init_thread_core_maps(int tpc)
|
||||
* setup_cpu_maps - initialize the following cpu maps:
|
||||
* cpu_possible_map
|
||||
* cpu_present_map
|
||||
* cpu_sibling_map
|
||||
*
|
||||
* Having the possible map set up early allows us to restrict allocations
|
||||
* of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
|
||||
@@ -475,29 +474,6 @@ void __init smp_setup_cpu_maps(void)
|
||||
*/
|
||||
cpu_init_thread_core_maps(nthreads);
|
||||
}
|
||||
|
||||
/*
|
||||
* Being that cpu_sibling_map is now a per_cpu array, then it cannot
|
||||
* be initialized until the per_cpu areas have been created. This
|
||||
* function is now called from setup_per_cpu_areas().
|
||||
*/
|
||||
void __init smp_setup_cpu_sibling_map(void)
|
||||
{
|
||||
#ifdef CONFIG_PPC64
|
||||
int i, cpu, base;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
DBG("Sibling map for CPU %d:", cpu);
|
||||
base = cpu_first_thread_in_core(cpu);
|
||||
for (i = 0; i < threads_per_core; i++) {
|
||||
cpu_set(base + i, per_cpu(cpu_sibling_map, cpu));
|
||||
DBG(" %d", base + i);
|
||||
}
|
||||
DBG("\n");
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PPC64 */
|
||||
}
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#ifdef CONFIG_PCSPKR_PLATFORM
|
||||
|
||||
@@ -611,9 +611,6 @@ void __init setup_per_cpu_areas(void)
|
||||
paca[i].data_offset = ptr - __per_cpu_start;
|
||||
memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
|
||||
}
|
||||
|
||||
/* Now that per_cpu is setup, initialize cpu_sibling_map */
|
||||
smp_setup_cpu_sibling_map();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* this archive for more details.
|
||||
*/
|
||||
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/signal.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/unistd.h>
|
||||
@@ -112,7 +112,7 @@ static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
|
||||
}
|
||||
}
|
||||
|
||||
int do_signal(sigset_t *oldset, struct pt_regs *regs)
|
||||
static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
|
||||
{
|
||||
siginfo_t info;
|
||||
int signr;
|
||||
@@ -147,7 +147,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
|
||||
*/
|
||||
if (current->thread.dabr) {
|
||||
set_dabr(current->thread.dabr);
|
||||
#if defined(CONFIG_44x) || defined(CONFIG_BOOKE)
|
||||
#if defined(CONFIG_BOOKE)
|
||||
mtspr(SPRN_DBCR0, current->thread.dbcr0);
|
||||
#endif
|
||||
}
|
||||
@@ -177,11 +177,28 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
|
||||
* its frame, and we can clear the TLF_RESTORE_SIGMASK flag.
|
||||
*/
|
||||
current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK;
|
||||
|
||||
/*
|
||||
* Let tracing know that we've done the handler setup.
|
||||
*/
|
||||
tracehook_signal_handler(signr, &info, &ka, regs,
|
||||
test_thread_flag(TIF_SINGLESTEP));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void do_signal(struct pt_regs *regs, unsigned long thread_info_flags)
|
||||
{
|
||||
if (thread_info_flags & _TIF_SIGPENDING)
|
||||
do_signal_pending(NULL, regs);
|
||||
|
||||
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
|
||||
clear_thread_flag(TIF_NOTIFY_RESUME);
|
||||
tracehook_notify_resume(regs);
|
||||
}
|
||||
}
|
||||
|
||||
long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
|
||||
unsigned long r5, unsigned long r6, unsigned long r7,
|
||||
unsigned long r8, struct pt_regs *regs)
|
||||
|
||||
+116
-3
@@ -41,6 +41,7 @@
|
||||
#include <asm/smp.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/cputhreads.h>
|
||||
#include <asm/cputable.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/mpic.h>
|
||||
@@ -62,10 +63,12 @@ struct thread_info *secondary_ti;
|
||||
cpumask_t cpu_possible_map = CPU_MASK_NONE;
|
||||
cpumask_t cpu_online_map = CPU_MASK_NONE;
|
||||
DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
|
||||
DEFINE_PER_CPU(cpumask_t, cpu_core_map) = CPU_MASK_NONE;
|
||||
|
||||
EXPORT_SYMBOL(cpu_online_map);
|
||||
EXPORT_SYMBOL(cpu_possible_map);
|
||||
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
|
||||
EXPORT_PER_CPU_SYMBOL(cpu_core_map);
|
||||
|
||||
/* SMP operations for this machine */
|
||||
struct smp_ops_t *smp_ops;
|
||||
@@ -228,6 +231,8 @@ void __devinit smp_prepare_boot_cpu(void)
|
||||
BUG_ON(smp_processor_id() != boot_cpuid);
|
||||
|
||||
cpu_set(boot_cpuid, cpu_online_map);
|
||||
cpu_set(boot_cpuid, per_cpu(cpu_sibling_map, boot_cpuid));
|
||||
cpu_set(boot_cpuid, per_cpu(cpu_core_map, boot_cpuid));
|
||||
#ifdef CONFIG_PPC64
|
||||
paca[boot_cpuid].__current = current;
|
||||
#endif
|
||||
@@ -375,11 +380,60 @@ int __cpuinit __cpu_up(unsigned int cpu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the value of the reg property corresponding to the given
|
||||
* logical cpu.
|
||||
*/
|
||||
int cpu_to_core_id(int cpu)
|
||||
{
|
||||
struct device_node *np;
|
||||
const int *reg;
|
||||
int id = -1;
|
||||
|
||||
np = of_get_cpu_node(cpu, NULL);
|
||||
if (!np)
|
||||
goto out;
|
||||
|
||||
reg = of_get_property(np, "reg", NULL);
|
||||
if (!reg)
|
||||
goto out;
|
||||
|
||||
id = *reg;
|
||||
out:
|
||||
of_node_put(np);
|
||||
return id;
|
||||
}
|
||||
|
||||
/* Must be called when no change can occur to cpu_present_map,
|
||||
* i.e. during cpu online or offline.
|
||||
*/
|
||||
static struct device_node *cpu_to_l2cache(int cpu)
|
||||
{
|
||||
struct device_node *np;
|
||||
const phandle *php;
|
||||
phandle ph;
|
||||
|
||||
if (!cpu_present(cpu))
|
||||
return NULL;
|
||||
|
||||
np = of_get_cpu_node(cpu, NULL);
|
||||
if (np == NULL)
|
||||
return NULL;
|
||||
|
||||
php = of_get_property(np, "l2-cache", NULL);
|
||||
if (php == NULL)
|
||||
return NULL;
|
||||
ph = *php;
|
||||
of_node_put(np);
|
||||
|
||||
return of_find_node_by_phandle(ph);
|
||||
}
|
||||
|
||||
/* Activate a secondary processor. */
|
||||
int __devinit start_secondary(void *unused)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
struct device_node *l2_cache;
|
||||
int i, base;
|
||||
|
||||
atomic_inc(&init_mm.mm_count);
|
||||
current->active_mm = &init_mm;
|
||||
@@ -400,6 +454,33 @@ int __devinit start_secondary(void *unused)
|
||||
|
||||
ipi_call_lock();
|
||||
cpu_set(cpu, cpu_online_map);
|
||||
/* Update sibling maps */
|
||||
base = cpu_first_thread_in_core(cpu);
|
||||
for (i = 0; i < threads_per_core; i++) {
|
||||
if (cpu_is_offline(base + i))
|
||||
continue;
|
||||
cpu_set(cpu, per_cpu(cpu_sibling_map, base + i));
|
||||
cpu_set(base + i, per_cpu(cpu_sibling_map, cpu));
|
||||
|
||||
/* cpu_core_map should be a superset of
|
||||
* cpu_sibling_map even if we don't have cache
|
||||
* information, so update the former here, too.
|
||||
*/
|
||||
cpu_set(cpu, per_cpu(cpu_core_map, base +i));
|
||||
cpu_set(base + i, per_cpu(cpu_core_map, cpu));
|
||||
}
|
||||
l2_cache = cpu_to_l2cache(cpu);
|
||||
for_each_online_cpu(i) {
|
||||
struct device_node *np = cpu_to_l2cache(i);
|
||||
if (!np)
|
||||
continue;
|
||||
if (np == l2_cache) {
|
||||
cpu_set(cpu, per_cpu(cpu_core_map, i));
|
||||
cpu_set(i, per_cpu(cpu_core_map, cpu));
|
||||
}
|
||||
of_node_put(np);
|
||||
}
|
||||
of_node_put(l2_cache);
|
||||
ipi_call_unlock();
|
||||
|
||||
local_irq_enable();
|
||||
@@ -437,10 +518,42 @@ void __init smp_cpus_done(unsigned int max_cpus)
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
int __cpu_disable(void)
|
||||
{
|
||||
if (smp_ops->cpu_disable)
|
||||
return smp_ops->cpu_disable();
|
||||
struct device_node *l2_cache;
|
||||
int cpu = smp_processor_id();
|
||||
int base, i;
|
||||
int err;
|
||||
|
||||
return -ENOSYS;
|
||||
if (!smp_ops->cpu_disable)
|
||||
return -ENOSYS;
|
||||
|
||||
err = smp_ops->cpu_disable();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Update sibling maps */
|
||||
base = cpu_first_thread_in_core(cpu);
|
||||
for (i = 0; i < threads_per_core; i++) {
|
||||
cpu_clear(cpu, per_cpu(cpu_sibling_map, base + i));
|
||||
cpu_clear(base + i, per_cpu(cpu_sibling_map, cpu));
|
||||
cpu_clear(cpu, per_cpu(cpu_core_map, base +i));
|
||||
cpu_clear(base + i, per_cpu(cpu_core_map, cpu));
|
||||
}
|
||||
|
||||
l2_cache = cpu_to_l2cache(cpu);
|
||||
for_each_present_cpu(i) {
|
||||
struct device_node *np = cpu_to_l2cache(i);
|
||||
if (!np)
|
||||
continue;
|
||||
if (np == l2_cache) {
|
||||
cpu_clear(cpu, per_cpu(cpu_core_map, i));
|
||||
cpu_clear(i, per_cpu(cpu_core_map, cpu));
|
||||
}
|
||||
of_node_put(np);
|
||||
}
|
||||
of_node_put(l2_cache);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __cpu_die(unsigned int cpu)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/stacktrace.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user