mirror of https://gitee.com/openkylin/linux.git
Merge commit 'v2.6.27-rc1' into x86/urgent
This commit is contained in:
commit
35780c8ea7
|
@ -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
|
||||
|
|
|
@ -138,14 +138,8 @@ So, what's changed?
|
|||
|
||||
Set active the IRQ edge(s)/level. This replaces the
|
||||
SA1111 INTPOL manipulation, and the set_GPIO_IRQ_edge()
|
||||
function. Type should be one of the following:
|
||||
|
||||
#define IRQT_NOEDGE (0)
|
||||
#define IRQT_RISING (__IRQT_RISEDGE)
|
||||
#define IRQT_FALLING (__IRQT_FALEDGE)
|
||||
#define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE)
|
||||
#define IRQT_LOW (__IRQT_LOWLVL)
|
||||
#define IRQT_HIGH (__IRQT_HIGHLVL)
|
||||
function. Type should be one of IRQ_TYPE_xxx defined in
|
||||
<linux/irq.h>
|
||||
|
||||
3. set_GPIO_IRQ_edge() is obsolete, and should be replaced by set_irq_type.
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
|
@ -65,26 +65,26 @@ Install kexec-tools
|
|||
|
||||
2) Download the kexec-tools user-space package from the following URL:
|
||||
|
||||
http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/kexec-tools-testing.tar.gz
|
||||
http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/kexec-tools.tar.gz
|
||||
|
||||
This is a symlink to the latest version, which at the time of writing is
|
||||
20061214, the only release of kexec-tools-testing so far. As other versions
|
||||
are released, the older ones will remain available at
|
||||
http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/
|
||||
This is a symlink to the latest version.
|
||||
|
||||
Note: Latest kexec-tools-testing git tree is available at
|
||||
The latest kexec-tools git tree is available at:
|
||||
|
||||
git://git.kernel.org/pub/scm/linux/kernel/git/horms/kexec-tools-testing.git
|
||||
git://git.kernel.org/pub/scm/linux/kernel/git/horms/kexec-tools.git
|
||||
or
|
||||
http://www.kernel.org/git/?p=linux/kernel/git/horms/kexec-tools-testing.git;a=summary
|
||||
http://www.kernel.org/git/?p=linux/kernel/git/horms/kexec-tools.git
|
||||
|
||||
More information about kexec-tools can be found at
|
||||
http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/README.html
|
||||
|
||||
3) Unpack the tarball with the tar command, as follows:
|
||||
|
||||
tar xvpzf kexec-tools-testing.tar.gz
|
||||
tar xvpzf kexec-tools.tar.gz
|
||||
|
||||
4) Change to the kexec-tools directory, as follows:
|
||||
|
||||
cd kexec-tools-testing-VERSION
|
||||
cd kexec-tools-VERSION
|
||||
|
||||
5) Configure the package, as follows:
|
||||
|
||||
|
|
|
@ -36,11 +36,13 @@
|
|||
#include <sched.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <signal.h>
|
||||
#include "linux/lguest_launcher.h"
|
||||
#include "linux/virtio_config.h"
|
||||
#include "linux/virtio_net.h"
|
||||
#include "linux/virtio_blk.h"
|
||||
#include "linux/virtio_console.h"
|
||||
#include "linux/virtio_rng.h"
|
||||
#include "linux/virtio_ring.h"
|
||||
#include "asm-x86/bootparam.h"
|
||||
/*L:110 We can ignore the 39 include files we need for this program, but I do
|
||||
|
@ -64,8 +66,8 @@ typedef uint8_t u8;
|
|||
#endif
|
||||
/* We can have up to 256 pages for devices. */
|
||||
#define DEVICE_PAGES 256
|
||||
/* This will occupy 2 pages: it must be a power of 2. */
|
||||
#define VIRTQUEUE_NUM 128
|
||||
/* This will occupy 3 pages: it must be a power of 2. */
|
||||
#define VIRTQUEUE_NUM 256
|
||||
|
||||
/*L:120 verbose is both a global flag and a macro. The C preprocessor allows
|
||||
* this, and although I wouldn't recommend it, it works quite nicely here. */
|
||||
|
@ -74,12 +76,19 @@ static bool verbose;
|
|||
do { if (verbose) printf(args); } while(0)
|
||||
/*:*/
|
||||
|
||||
/* The pipe to send commands to the waker process */
|
||||
static int waker_fd;
|
||||
/* File descriptors for the Waker. */
|
||||
struct {
|
||||
int pipe[2];
|
||||
int lguest_fd;
|
||||
} waker_fds;
|
||||
|
||||
/* The pointer to the start of guest memory. */
|
||||
static void *guest_base;
|
||||
/* The maximum guest physical address allowed, and maximum possible. */
|
||||
static unsigned long guest_limit, guest_max;
|
||||
/* The pipe for signal hander to write to. */
|
||||
static int timeoutpipe[2];
|
||||
static unsigned int timeout_usec = 500;
|
||||
|
||||
/* a per-cpu variable indicating whose vcpu is currently running */
|
||||
static unsigned int __thread cpu_id;
|
||||
|
@ -155,11 +164,14 @@ struct virtqueue
|
|||
/* Last available index we saw. */
|
||||
u16 last_avail_idx;
|
||||
|
||||
/* The routine to call when the Guest pings us. */
|
||||
void (*handle_output)(int fd, struct virtqueue *me);
|
||||
/* The routine to call when the Guest pings us, or timeout. */
|
||||
void (*handle_output)(int fd, struct virtqueue *me, bool timeout);
|
||||
|
||||
/* Outstanding buffers */
|
||||
unsigned int inflight;
|
||||
|
||||
/* Is this blocked awaiting a timer? */
|
||||
bool blocked;
|
||||
};
|
||||
|
||||
/* Remember the arguments to the program so we can "reboot" */
|
||||
|
@ -190,6 +202,9 @@ static void *_convert(struct iovec *iov, size_t size, size_t align,
|
|||
return iov->iov_base;
|
||||
}
|
||||
|
||||
/* Wrapper for the last available index. Makes it easier to change. */
|
||||
#define lg_last_avail(vq) ((vq)->last_avail_idx)
|
||||
|
||||
/* The virtio configuration space is defined to be little-endian. x86 is
|
||||
* little-endian too, but it's nice to be explicit so we have these helpers. */
|
||||
#define cpu_to_le16(v16) (v16)
|
||||
|
@ -199,6 +214,33 @@ static void *_convert(struct iovec *iov, size_t size, size_t align,
|
|||
#define le32_to_cpu(v32) (v32)
|
||||
#define le64_to_cpu(v64) (v64)
|
||||
|
||||
/* Is this iovec empty? */
|
||||
static bool iov_empty(const struct iovec iov[], unsigned int num_iov)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < num_iov; i++)
|
||||
if (iov[i].iov_len)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Take len bytes from the front of this iovec. */
|
||||
static void iov_consume(struct iovec iov[], unsigned num_iov, unsigned len)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < num_iov; i++) {
|
||||
unsigned int used;
|
||||
|
||||
used = iov[i].iov_len < len ? iov[i].iov_len : len;
|
||||
iov[i].iov_base += used;
|
||||
iov[i].iov_len -= used;
|
||||
len -= used;
|
||||
}
|
||||
assert(len == 0);
|
||||
}
|
||||
|
||||
/* The device virtqueue descriptors are followed by feature bitmasks. */
|
||||
static u8 *get_feature_bits(struct device *dev)
|
||||
{
|
||||
|
@ -254,6 +296,7 @@ static void *map_zeroed_pages(unsigned int num)
|
|||
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0);
|
||||
if (addr == MAP_FAILED)
|
||||
err(1, "Mmaping %u pages of /dev/zero", num);
|
||||
close(fd);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
@ -540,69 +583,64 @@ static void add_device_fd(int fd)
|
|||
* watch, but handing a file descriptor mask through to the kernel is fairly
|
||||
* icky.
|
||||
*
|
||||
* Instead, we fork off a process which watches the file descriptors and writes
|
||||
* Instead, we clone off a thread which watches the file descriptors and writes
|
||||
* the LHREQ_BREAK command to the /dev/lguest file descriptor to tell the Host
|
||||
* stop running the Guest. This causes the Launcher to return from the
|
||||
* /dev/lguest read with -EAGAIN, where it will write to /dev/lguest to reset
|
||||
* the LHREQ_BREAK and wake us up again.
|
||||
*
|
||||
* This, of course, is merely a different *kind* of icky.
|
||||
*
|
||||
* Given my well-known antipathy to threads, I'd prefer to use processes. But
|
||||
* it's easier to share Guest memory with threads, and trivial to share the
|
||||
* devices.infds as the Launcher changes it.
|
||||
*/
|
||||
static void wake_parent(int pipefd, int lguest_fd)
|
||||
static int waker(void *unused)
|
||||
{
|
||||
/* Add the pipe from the Launcher to the fdset in the device_list, so
|
||||
* we watch it, too. */
|
||||
add_device_fd(pipefd);
|
||||
/* Close the write end of the pipe: only the Launcher has it open. */
|
||||
close(waker_fds.pipe[1]);
|
||||
|
||||
for (;;) {
|
||||
fd_set rfds = devices.infds;
|
||||
unsigned long args[] = { LHREQ_BREAK, 1 };
|
||||
unsigned int maxfd = devices.max_infd;
|
||||
|
||||
/* We also listen to the pipe from the Launcher. */
|
||||
FD_SET(waker_fds.pipe[0], &rfds);
|
||||
if (waker_fds.pipe[0] > maxfd)
|
||||
maxfd = waker_fds.pipe[0];
|
||||
|
||||
/* Wait until input is ready from one of the devices. */
|
||||
select(devices.max_infd+1, &rfds, NULL, NULL, NULL);
|
||||
/* Is it a message from the Launcher? */
|
||||
if (FD_ISSET(pipefd, &rfds)) {
|
||||
int fd;
|
||||
/* If read() returns 0, it means the Launcher has
|
||||
* exited. We silently follow. */
|
||||
if (read(pipefd, &fd, sizeof(fd)) == 0)
|
||||
exit(0);
|
||||
/* Otherwise it's telling us to change what file
|
||||
* descriptors we're to listen to. Positive means
|
||||
* listen to a new one, negative means stop
|
||||
* listening. */
|
||||
if (fd >= 0)
|
||||
FD_SET(fd, &devices.infds);
|
||||
else
|
||||
FD_CLR(-fd - 1, &devices.infds);
|
||||
} else /* Send LHREQ_BREAK command. */
|
||||
pwrite(lguest_fd, args, sizeof(args), cpu_id);
|
||||
select(maxfd+1, &rfds, NULL, NULL, NULL);
|
||||
|
||||
/* Message from Launcher? */
|
||||
if (FD_ISSET(waker_fds.pipe[0], &rfds)) {
|
||||
char c;
|
||||
/* If this fails, then assume Launcher has exited.
|
||||
* Don't do anything on exit: we're just a thread! */
|
||||
if (read(waker_fds.pipe[0], &c, 1) != 1)
|
||||
_exit(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Send LHREQ_BREAK command to snap the Launcher out of it. */
|
||||
pwrite(waker_fds.lguest_fd, args, sizeof(args), cpu_id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This routine just sets up a pipe to the Waker process. */
|
||||
static int setup_waker(int lguest_fd)
|
||||
static void setup_waker(int lguest_fd)
|
||||
{
|
||||
int pipefd[2], child;
|
||||
/* This pipe is closed when Launcher dies, telling Waker. */
|
||||
if (pipe(waker_fds.pipe) != 0)
|
||||
err(1, "Creating pipe for Waker");
|
||||
|
||||
/* We create a pipe to talk to the Waker, and also so it knows when the
|
||||
* Launcher dies (and closes pipe). */
|
||||
pipe(pipefd);
|
||||
child = fork();
|
||||
if (child == -1)
|
||||
err(1, "forking");
|
||||
/* Waker also needs to know the lguest fd */
|
||||
waker_fds.lguest_fd = lguest_fd;
|
||||
|
||||
if (child == 0) {
|
||||
/* We are the Waker: close the "writing" end of our copy of the
|
||||
* pipe and start waiting for input. */
|
||||
close(pipefd[1]);
|
||||
wake_parent(pipefd[0], lguest_fd);
|
||||
}
|
||||
/* Close the reading end of our copy of the pipe. */
|
||||
close(pipefd[0]);
|
||||
|
||||
/* Here is the fd used to talk to the waker. */
|
||||
return pipefd[1];
|
||||
if (clone(waker, malloc(4096) + 4096, CLONE_VM | SIGCHLD, NULL) == -1)
|
||||
err(1, "Creating Waker");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -661,19 +699,22 @@ static unsigned get_vq_desc(struct virtqueue *vq,
|
|||
unsigned int *out_num, unsigned int *in_num)
|
||||
{
|
||||
unsigned int i, head;
|
||||
u16 last_avail;
|
||||
|
||||
/* Check it isn't doing very strange things with descriptor numbers. */
|
||||
if ((u16)(vq->vring.avail->idx - vq->last_avail_idx) > vq->vring.num)
|
||||
last_avail = lg_last_avail(vq);
|
||||
if ((u16)(vq->vring.avail->idx - last_avail) > vq->vring.num)
|
||||
errx(1, "Guest moved used index from %u to %u",
|
||||
vq->last_avail_idx, vq->vring.avail->idx);
|
||||
last_avail, vq->vring.avail->idx);
|
||||
|
||||
/* If there's nothing new since last we looked, return invalid. */
|
||||
if (vq->vring.avail->idx == vq->last_avail_idx)
|
||||
if (vq->vring.avail->idx == last_avail)
|
||||
return vq->vring.num;
|
||||
|
||||
/* Grab the next descriptor number they're advertising, and increment
|
||||
* the index we've seen. */
|
||||
head = vq->vring.avail->ring[vq->last_avail_idx++ % vq->vring.num];
|
||||
head = vq->vring.avail->ring[last_avail % vq->vring.num];
|
||||
lg_last_avail(vq)++;
|
||||
|
||||
/* If their number is silly, that's a fatal mistake. */
|
||||
if (head >= vq->vring.num)
|
||||
|
@ -821,8 +862,8 @@ static bool handle_console_input(int fd, struct device *dev)
|
|||
unsigned long args[] = { LHREQ_BREAK, 0 };
|
||||
/* Close the fd so Waker will know it has to
|
||||
* exit. */
|
||||
close(waker_fd);
|
||||
/* Just in case waker is blocked in BREAK, send
|
||||
close(waker_fds.pipe[1]);
|
||||
/* Just in case Waker is blocked in BREAK, send
|
||||
* unbreak now. */
|
||||
write(fd, args, sizeof(args));
|
||||
exit(2);
|
||||
|
@ -839,7 +880,7 @@ static bool handle_console_input(int fd, struct device *dev)
|
|||
|
||||
/* Handling output for console is simple: we just get all the output buffers
|
||||
* and write them to stdout. */
|
||||
static void handle_console_output(int fd, struct virtqueue *vq)
|
||||
static void handle_console_output(int fd, struct virtqueue *vq, bool timeout)
|
||||
{
|
||||
unsigned int head, out, in;
|
||||
int len;
|
||||
|
@ -854,6 +895,21 @@ static void handle_console_output(int fd, struct virtqueue *vq)
|
|||
}
|
||||
}
|
||||
|
||||
static void block_vq(struct virtqueue *vq)
|
||||
{
|
||||
struct itimerval itm;
|
||||
|
||||
vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
|
||||
vq->blocked = true;
|
||||
|
||||
itm.it_interval.tv_sec = 0;
|
||||
itm.it_interval.tv_usec = 0;
|
||||
itm.it_value.tv_sec = 0;
|
||||
itm.it_value.tv_usec = timeout_usec;
|
||||
|
||||
setitimer(ITIMER_REAL, &itm, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Network
|
||||
*
|
||||
|
@ -861,22 +917,34 @@ static void handle_console_output(int fd, struct virtqueue *vq)
|
|||
* and write them (ignoring the first element) to this device's file descriptor
|
||||
* (/dev/net/tun).
|
||||
*/
|
||||
static void handle_net_output(int fd, struct virtqueue *vq)
|
||||
static void handle_net_output(int fd, struct virtqueue *vq, bool timeout)
|
||||
{
|
||||
unsigned int head, out, in;
|
||||
unsigned int head, out, in, num = 0;
|
||||
int len;
|
||||
struct iovec iov[vq->vring.num];
|
||||
static int last_timeout_num;
|
||||
|
||||
/* Keep getting output buffers from the Guest until we run out. */
|
||||
while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) {
|
||||
if (in)
|
||||
errx(1, "Input buffers in output queue?");
|
||||
/* Check header, but otherwise ignore it (we told the Guest we
|
||||
* supported no features, so it shouldn't have anything
|
||||
* interesting). */
|
||||
(void)convert(&iov[0], struct virtio_net_hdr);
|
||||
len = writev(vq->dev->fd, iov+1, out-1);
|
||||
len = writev(vq->dev->fd, iov, out);
|
||||
if (len < 0)
|
||||
err(1, "Writing network packet to tun");
|
||||
add_used_and_trigger(fd, vq, head, len);
|
||||
num++;
|
||||
}
|
||||
|
||||
/* Block further kicks and set up a timer if we saw anything. */
|
||||
if (!timeout && num)
|
||||
block_vq(vq);
|
||||
|
||||
if (timeout) {
|
||||
if (num < last_timeout_num)
|
||||
timeout_usec += 10;
|
||||
else if (timeout_usec > 1)
|
||||
timeout_usec--;
|
||||
last_timeout_num = num;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -887,7 +955,6 @@ static bool handle_tun_input(int fd, struct device *dev)
|
|||
unsigned int head, in_num, out_num;
|
||||
int len;
|
||||
struct iovec iov[dev->vq->vring.num];
|
||||
struct virtio_net_hdr *hdr;
|
||||
|
||||
/* First we need a network buffer from the Guests's recv virtqueue. */
|
||||
head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
|
||||
|
@ -896,25 +963,23 @@ static bool handle_tun_input(int fd, struct device *dev)
|
|||
* early, the Guest won't be ready yet. Wait until the device
|
||||
* status says it's ready. */
|
||||
/* FIXME: Actually want DRIVER_ACTIVE here. */
|
||||
if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK)
|
||||
warn("network: no dma buffer!");
|
||||
|
||||
/* Now tell it we want to know if new things appear. */
|
||||
dev->vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
|
||||
wmb();
|
||||
|
||||
/* We'll turn this back on if input buffers are registered. */
|
||||
return false;
|
||||
} else if (out_num)
|
||||
errx(1, "Output buffers in network recv queue?");
|
||||
|
||||
/* First element is the header: we set it to 0 (no features). */
|
||||
hdr = convert(&iov[0], struct virtio_net_hdr);
|
||||
hdr->flags = 0;
|
||||
hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
|
||||
|
||||
/* Read the packet from the device directly into the Guest's buffer. */
|
||||
len = readv(dev->fd, iov+1, in_num-1);
|
||||
len = readv(dev->fd, iov, in_num);
|
||||
if (len <= 0)
|
||||
err(1, "reading network");
|
||||
|
||||
/* Tell the Guest about the new packet. */
|
||||
add_used_and_trigger(fd, dev->vq, head, sizeof(*hdr) + len);
|
||||
add_used_and_trigger(fd, dev->vq, head, len);
|
||||
|
||||
verbose("tun input packet len %i [%02x %02x] (%s)\n", len,
|
||||
((u8 *)iov[1].iov_base)[0], ((u8 *)iov[1].iov_base)[1],
|
||||
|
@ -927,11 +992,18 @@ static bool handle_tun_input(int fd, struct device *dev)
|
|||
/*L:215 This is the callback attached to the network and console input
|
||||
* virtqueues: it ensures we try again, in case we stopped console or net
|
||||
* delivery because Guest didn't have any buffers. */
|
||||
static void enable_fd(int fd, struct virtqueue *vq)
|
||||
static void enable_fd(int fd, struct virtqueue *vq, bool timeout)
|
||||
{
|
||||
add_device_fd(vq->dev->fd);
|
||||
/* Tell waker to listen to it again */
|
||||
write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd));
|
||||
/* Snap the Waker out of its select loop. */
|
||||
write(waker_fds.pipe[1], "", 1);
|
||||
}
|
||||
|
||||
static void net_enable_fd(int fd, struct virtqueue *vq, bool timeout)
|
||||
{
|
||||
/* We don't need to know again when Guest refills receive buffer. */
|
||||
vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
|
||||
enable_fd(fd, vq, timeout);
|
||||
}
|
||||
|
||||
/* When the Guest tells us they updated the status field, we handle it. */
|
||||
|
@ -951,7 +1023,7 @@ static void update_device_status(struct device *dev)
|
|||
for (vq = dev->vq; vq; vq = vq->next) {
|
||||
memset(vq->vring.desc, 0,
|
||||
vring_size(vq->config.num, getpagesize()));
|
||||
vq->last_avail_idx = 0;
|
||||
lg_last_avail(vq) = 0;
|
||||
}
|
||||
} else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) {
|
||||
warnx("Device %s configuration FAILED", dev->name);
|
||||
|
@ -960,10 +1032,10 @@ static void update_device_status(struct device *dev)
|
|||
|
||||
verbose("Device %s OK: offered", dev->name);
|
||||
for (i = 0; i < dev->desc->feature_len; i++)
|
||||
verbose(" %08x", get_feature_bits(dev)[i]);
|
||||
verbose(" %02x", get_feature_bits(dev)[i]);
|
||||
verbose(", accepted");
|
||||
for (i = 0; i < dev->desc->feature_len; i++)
|
||||
verbose(" %08x", get_feature_bits(dev)
|
||||
verbose(" %02x", get_feature_bits(dev)
|
||||
[dev->desc->feature_len+i]);
|
||||
|
||||
if (dev->ready)
|
||||
|
@ -1000,7 +1072,7 @@ static void handle_output(int fd, unsigned long addr)
|
|||
if (strcmp(vq->dev->name, "console") != 0)
|
||||
verbose("Output to %s\n", vq->dev->name);
|
||||
if (vq->handle_output)
|
||||
vq->handle_output(fd, vq);
|
||||
vq->handle_output(fd, vq, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1014,6 +1086,29 @@ static void handle_output(int fd, unsigned long addr)
|
|||
strnlen(from_guest_phys(addr), guest_limit - addr));
|
||||
}
|
||||
|
||||
static void handle_timeout(int fd)
|
||||
{
|
||||
char buf[32];
|
||||
struct device *i;
|
||||
struct virtqueue *vq;
|
||||
|
||||
/* Clear the pipe */
|
||||
read(timeoutpipe[0], buf, sizeof(buf));
|
||||
|
||||
/* Check each device and virtqueue: flush blocked ones. */
|
||||
for (i = devices.dev; i; i = i->next) {
|
||||
for (vq = i->vq; vq; vq = vq->next) {
|
||||
if (!vq->blocked)
|
||||
continue;
|
||||
|
||||
vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
|
||||
vq->blocked = false;
|
||||
if (vq->handle_output)
|
||||
vq->handle_output(fd, vq, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This is called when the Waker wakes us up: check for incoming file
|
||||
* descriptors. */
|
||||
static void handle_input(int fd)
|
||||
|
@ -1024,16 +1119,20 @@ static void handle_input(int fd)
|
|||
for (;;) {
|
||||
struct device *i;
|
||||
fd_set fds = devices.infds;
|
||||
int num;
|
||||
|
||||
num = select(devices.max_infd+1, &fds, NULL, NULL, &poll);
|
||||
/* Could get interrupted */
|
||||
if (num < 0)
|
||||
continue;
|
||||
/* If nothing is ready, we're done. */
|
||||
if (select(devices.max_infd+1, &fds, NULL, NULL, &poll) == 0)
|
||||
if (num == 0)
|
||||
break;
|
||||
|
||||
/* Otherwise, call the device(s) which have readable file
|
||||
* descriptors and a method of handling them. */
|
||||
for (i = devices.dev; i; i = i->next) {
|
||||
if (i->handle_input && FD_ISSET(i->fd, &fds)) {
|
||||
int dev_fd;
|
||||
if (i->handle_input(fd, i))
|
||||
continue;
|
||||
|
||||
|
@ -1043,13 +1142,12 @@ static void handle_input(int fd)
|
|||
* buffers to deliver into. Console also uses
|
||||
* it when it discovers that stdin is closed. */
|
||||
FD_CLR(i->fd, &devices.infds);
|
||||
/* Tell waker to ignore it too, by sending a
|
||||
* negative fd number (-1, since 0 is a valid
|
||||
* FD number). */
|
||||
dev_fd = -i->fd - 1;
|
||||
write(waker_fd, &dev_fd, sizeof(dev_fd));
|
||||
}
|
||||
}
|
||||
|
||||
/* Is this the timeout fd? */
|
||||
if (FD_ISSET(timeoutpipe[0], &fds))
|
||||
handle_timeout(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1098,7 +1196,7 @@ static struct lguest_device_desc *new_dev_desc(u16 type)
|
|||
/* Each device descriptor is followed by the description of its virtqueues. We
|
||||
* specify how many descriptors the virtqueue is to have. */
|
||||
static void add_virtqueue(struct device *dev, unsigned int num_descs,
|
||||
void (*handle_output)(int fd, struct virtqueue *me))
|
||||
void (*handle_output)(int, struct virtqueue *, bool))
|
||||
{
|
||||
unsigned int pages;
|
||||
struct virtqueue **i, *vq = malloc(sizeof(*vq));
|
||||
|
@ -1114,6 +1212,7 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
|
|||
vq->last_avail_idx = 0;
|
||||
vq->dev = dev;
|
||||
vq->inflight = 0;
|
||||
vq->blocked = false;
|
||||
|
||||
/* Initialize the configuration. */
|
||||
vq->config.num = num_descs;
|
||||
|
@ -1246,6 +1345,24 @@ static void setup_console(void)
|
|||
}
|
||||
/*:*/
|
||||
|
||||
static void timeout_alarm(int sig)
|
||||
{
|
||||
write(timeoutpipe[1], "", 1);
|
||||
}
|
||||
|
||||
static void setup_timeout(void)
|
||||
{
|
||||
if (pipe(timeoutpipe) != 0)
|
||||
err(1, "Creating timeout pipe");
|
||||
|
||||
if (fcntl(timeoutpipe[1], F_SETFL,
|
||||
fcntl(timeoutpipe[1], F_GETFL) | O_NONBLOCK) != 0)
|
||||
err(1, "Making timeout pipe nonblocking");
|
||||
|
||||
add_device_fd(timeoutpipe[0]);
|
||||
signal(SIGALRM, timeout_alarm);
|
||||
}
|
||||
|
||||
/*M:010 Inter-guest networking is an interesting area. Simplest is to have a
|
||||
* --sharenet=<name> option which opens or creates a named pipe. This can be
|
||||
* used to send packets to another guest in a 1:1 manner.
|
||||
|
@ -1264,10 +1381,25 @@ static void setup_console(void)
|
|||
|
||||
static u32 str2ip(const char *ipaddr)
|
||||
{
|
||||
unsigned int byte[4];
|
||||
unsigned int b[4];
|
||||
|
||||
sscanf(ipaddr, "%u.%u.%u.%u", &byte[0], &byte[1], &byte[2], &byte[3]);
|
||||
return (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | byte[3];
|
||||
if (sscanf(ipaddr, "%u.%u.%u.%u", &b[0], &b[1], &b[2], &b[3]) != 4)
|
||||
errx(1, "Failed to parse IP address '%s'", ipaddr);
|
||||
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
|
||||
}
|
||||
|
||||
static void str2mac(const char *macaddr, unsigned char mac[6])
|
||||
{
|
||||
unsigned int m[6];
|
||||
if (sscanf(macaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
&m[0], &m[1], &m[2], &m[3], &m[4], &m[5]) != 6)
|
||||
errx(1, "Failed to parse mac address '%s'", macaddr);
|
||||
mac[0] = m[0];
|
||||
mac[1] = m[1];
|
||||
mac[2] = m[2];
|
||||
mac[3] = m[3];
|
||||
mac[4] = m[4];
|
||||
mac[5] = m[5];
|
||||
}
|
||||
|
||||
/* This code is "adapted" from libbridge: it attaches the Host end of the
|
||||
|
@ -1288,6 +1420,7 @@ static void add_to_bridge(int fd, const char *if_name, const char *br_name)
|
|||
errx(1, "interface %s does not exist!", if_name);
|
||||
|
||||
strncpy(ifr.ifr_name, br_name, IFNAMSIZ);
|
||||
ifr.ifr_name[IFNAMSIZ-1] = '\0';
|
||||
ifr.ifr_ifindex = ifidx;
|
||||
if (ioctl(fd, SIOCBRADDIF, &ifr) < 0)
|
||||
err(1, "can't add %s to bridge %s", if_name, br_name);
|
||||
|
@ -1296,64 +1429,90 @@ static void add_to_bridge(int fd, const char *if_name, const char *br_name)
|
|||
/* This sets up the Host end of the network device with an IP address, brings
|
||||
* it up so packets will flow, the copies the MAC address into the hwaddr
|
||||
* pointer. */
|
||||
static void configure_device(int fd, const char *devname, u32 ipaddr,
|
||||
unsigned char hwaddr[6])
|
||||
static void configure_device(int fd, const char *tapif, u32 ipaddr)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
|
||||
|
||||
/* Don't read these incantations. Just cut & paste them like I did! */
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strcpy(ifr.ifr_name, devname);
|
||||
strcpy(ifr.ifr_name, tapif);
|
||||
|
||||
/* Don't read these incantations. Just cut & paste them like I did! */
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr.s_addr = htonl(ipaddr);
|
||||
if (ioctl(fd, SIOCSIFADDR, &ifr) != 0)
|
||||
err(1, "Setting %s interface address", devname);
|
||||
err(1, "Setting %s interface address", tapif);
|
||||
ifr.ifr_flags = IFF_UP;
|
||||
if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0)
|
||||
err(1, "Bringing interface %s up", devname);
|
||||
err(1, "Bringing interface %s up", tapif);
|
||||
}
|
||||
|
||||
static void get_mac(int fd, const char *tapif, unsigned char hwaddr[6])
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strcpy(ifr.ifr_name, tapif);
|
||||
|
||||
/* SIOC stands for Socket I/O Control. G means Get (vs S for Set
|
||||
* above). IF means Interface, and HWADDR is hardware address.
|
||||
* Simple! */
|
||||
if (ioctl(fd, SIOCGIFHWADDR, &ifr) != 0)
|
||||
err(1, "getting hw address for %s", devname);
|
||||
err(1, "getting hw address for %s", tapif);
|
||||
memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6);
|
||||
}
|
||||
|
||||
/*L:195 Our network is a Host<->Guest network. This can either use bridging or
|
||||
* routing, but the principle is the same: it uses the "tun" device to inject
|
||||
* packets into the Host as if they came in from a normal network card. We
|
||||
* just shunt packets between the Guest and the tun device. */
|
||||
static void setup_tun_net(const char *arg)
|
||||
static int get_tun_device(char tapif[IFNAMSIZ])
|
||||
{
|
||||
struct device *dev;
|
||||
struct ifreq ifr;
|
||||
int netfd, ipfd;
|
||||
u32 ip;
|
||||
const char *br_name = NULL;
|
||||
struct virtio_net_config conf;
|
||||
int netfd;
|
||||
|
||||
/* Start with this zeroed. Messy but sure. */
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
|
||||
/* We open the /dev/net/tun device and tell it we want a tap device. A
|
||||
* tap device is like a tun device, only somehow different. To tell
|
||||
* the truth, I completely blundered my way through this code, but it
|
||||
* works now! */
|
||||
netfd = open_or_die("/dev/net/tun", O_RDWR);
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
|
||||
strcpy(ifr.ifr_name, "tap%d");
|
||||
if (ioctl(netfd, TUNSETIFF, &ifr) != 0)
|
||||
err(1, "configuring /dev/net/tun");
|
||||
|
||||
if (ioctl(netfd, TUNSETOFFLOAD,
|
||||
TUN_F_CSUM|TUN_F_TSO4|TUN_F_TSO6|TUN_F_TSO_ECN) != 0)
|
||||
err(1, "Could not set features for tun device");
|
||||
|
||||
/* We don't need checksums calculated for packets coming in this
|
||||
* device: trust us! */
|
||||
ioctl(netfd, TUNSETNOCSUM, 1);
|
||||
|
||||
memcpy(tapif, ifr.ifr_name, IFNAMSIZ);
|
||||
return netfd;
|
||||
}
|
||||
|
||||
/*L:195 Our network is a Host<->Guest network. This can either use bridging or
|
||||
* routing, but the principle is the same: it uses the "tun" device to inject
|
||||
* packets into the Host as if they came in from a normal network card. We
|
||||
* just shunt packets between the Guest and the tun device. */
|
||||
static void setup_tun_net(char *arg)
|
||||
{
|
||||
struct device *dev;
|
||||
int netfd, ipfd;
|
||||
u32 ip = INADDR_ANY;
|
||||
bool bridging = false;
|
||||
char tapif[IFNAMSIZ], *p;
|
||||
struct virtio_net_config conf;
|
||||
|
||||
netfd = get_tun_device(tapif);
|
||||
|
||||
/* First we create a new network device. */
|
||||
dev = new_device("net", VIRTIO_ID_NET, netfd, handle_tun_input);
|
||||
|
||||
/* Network devices need a receive and a send queue, just like
|
||||
* console. */
|
||||
add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
|
||||
add_virtqueue(dev, VIRTQUEUE_NUM, net_enable_fd);
|
||||
add_virtqueue(dev, VIRTQUEUE_NUM, handle_net_output);
|
||||
|
||||
/* We need a socket to perform the magic network ioctls to bring up the
|
||||
|
@ -1364,28 +1523,56 @@ static void setup_tun_net(const char *arg)
|
|||
|
||||
/* If the command line was --tunnet=bridge:<name> do bridging. */
|
||||
if (!strncmp(BRIDGE_PFX, arg, strlen(BRIDGE_PFX))) {
|
||||
ip = INADDR_ANY;
|
||||
br_name = arg + strlen(BRIDGE_PFX);
|
||||
add_to_bridge(ipfd, ifr.ifr_name, br_name);
|
||||
} else /* It is an IP address to set up the device with */
|
||||
arg += strlen(BRIDGE_PFX);
|
||||
bridging = true;
|
||||
}
|
||||
|
||||
/* A mac address may follow the bridge name or IP address */
|
||||
p = strchr(arg, ':');
|
||||
if (p) {
|
||||
str2mac(p+1, conf.mac);
|
||||
*p = '\0';
|
||||
} else {
|
||||
p = arg + strlen(arg);
|
||||
/* None supplied; query the randomly assigned mac. */
|
||||
get_mac(ipfd, tapif, conf.mac);
|
||||
}
|
||||
|
||||
/* arg is now either an IP address or a bridge name */
|
||||
if (bridging)
|
||||
add_to_bridge(ipfd, tapif, arg);
|
||||
else
|
||||
ip = str2ip(arg);
|
||||
|
||||
/* Set up the tun device, and get the mac address for the interface. */
|
||||
configure_device(ipfd, ifr.ifr_name, ip, conf.mac);
|
||||
/* Set up the tun device. */
|
||||
configure_device(ipfd, tapif, ip);
|
||||
|
||||
/* Tell Guest what MAC address to use. */
|
||||
add_feature(dev, VIRTIO_NET_F_MAC);
|
||||
add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY);
|
||||
/* Expect Guest to handle everything except UFO */
|
||||
add_feature(dev, VIRTIO_NET_F_CSUM);
|
||||
add_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
|
||||
add_feature(dev, VIRTIO_NET_F_MAC);
|
||||
add_feature(dev, VIRTIO_NET_F_GUEST_TSO4);
|
||||
add_feature(dev, VIRTIO_NET_F_GUEST_TSO6);
|
||||
add_feature(dev, VIRTIO_NET_F_GUEST_ECN);
|
||||
add_feature(dev, VIRTIO_NET_F_HOST_TSO4);
|
||||
add_feature(dev, VIRTIO_NET_F_HOST_TSO6);
|
||||
add_feature(dev, VIRTIO_NET_F_HOST_ECN);
|
||||
set_config(dev, sizeof(conf), &conf);
|
||||
|
||||
/* We don't need the socket any more; setup is done. */
|
||||
close(ipfd);
|
||||
|
||||
verbose("device %u: tun net %u.%u.%u.%u\n",
|
||||
devices.device_num++,
|
||||
(u8)(ip>>24),(u8)(ip>>16),(u8)(ip>>8),(u8)ip);
|
||||
if (br_name)
|
||||
verbose("attached to bridge: %s\n", br_name);
|
||||
devices.device_num++;
|
||||
|
||||
if (bridging)
|
||||
verbose("device %u: tun %s attached to bridge: %s\n",
|
||||
devices.device_num, tapif, arg);
|
||||
else
|
||||
verbose("device %u: tun %s: %s\n",
|
||||
devices.device_num, tapif, arg);
|
||||
}
|
||||
|
||||
/* Our block (disk) device should be really simple: the Guest asks for a block
|
||||
|
@ -1550,7 +1737,7 @@ static bool handle_io_finish(int fd, struct device *dev)
|
|||
}
|
||||
|
||||
/* When the Guest submits some I/O, we just need to wake the I/O thread. */
|
||||
static void handle_virtblk_output(int fd, struct virtqueue *vq)
|
||||
static void handle_virtblk_output(int fd, struct virtqueue *vq, bool timeout)
|
||||
{
|
||||
struct vblk_info *vblk = vq->dev->priv;
|
||||
char c = 0;
|
||||
|
@ -1621,6 +1808,64 @@ static void setup_block_file(const char *filename)
|
|||
verbose("device %u: virtblock %llu sectors\n",
|
||||
devices.device_num, le64_to_cpu(conf.capacity));
|
||||
}
|
||||
|
||||
/* Our random number generator device reads from /dev/random into the Guest's
|
||||
* input buffers. The usual case is that the Guest doesn't want random numbers
|
||||
* and so has no buffers although /dev/random is still readable, whereas
|
||||
* console is the reverse.
|
||||
*
|
||||
* The same logic applies, however. */
|
||||
static bool handle_rng_input(int fd, struct device *dev)
|
||||
{
|
||||
int len;
|
||||
unsigned int head, in_num, out_num, totlen = 0;
|
||||
struct iovec iov[dev->vq->vring.num];
|
||||
|
||||
/* First we need a buffer from the Guests's virtqueue. */
|
||||
head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
|
||||
|
||||
/* If they're not ready for input, stop listening to this file
|
||||
* descriptor. We'll start again once they add an input buffer. */
|
||||
if (head == dev->vq->vring.num)
|
||||
return false;
|
||||
|
||||
if (out_num)
|
||||
errx(1, "Output buffers in rng?");
|
||||
|
||||
/* This is why we convert to iovecs: the readv() call uses them, and so
|
||||
* it reads straight into the Guest's buffer. We loop to make sure we
|
||||
* fill it. */
|
||||
while (!iov_empty(iov, in_num)) {
|
||||
len = readv(dev->fd, iov, in_num);
|
||||
if (len <= 0)
|
||||
err(1, "Read from /dev/random gave %i", len);
|
||||
iov_consume(iov, in_num, len);
|
||||
totlen += len;
|
||||
}
|
||||
|
||||
/* Tell the Guest about the new input. */
|
||||
add_used_and_trigger(fd, dev->vq, head, totlen);
|
||||
|
||||
/* Everything went OK! */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* And this creates a "hardware" random number device for the Guest. */
|
||||
static void setup_rng(void)
|
||||
{
|
||||
struct device *dev;
|
||||
int fd;
|
||||
|
||||
fd = open_or_die("/dev/random", O_RDONLY);
|
||||
|
||||
/* The device responds to return from I/O thread. */
|
||||
dev = new_device("rng", VIRTIO_ID_RNG, fd, handle_rng_input);
|
||||
|
||||
/* The device has one virtqueue, where the Guest places inbufs. */
|
||||
add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
|
||||
|
||||
verbose("device %u: rng\n", devices.device_num++);
|
||||
}
|
||||
/* That's the end of device setup. */
|
||||
|
||||
/*L:230 Reboot is pretty easy: clean up and exec() the Launcher afresh. */
|
||||
|
@ -1628,11 +1873,12 @@ static void __attribute__((noreturn)) restart_guest(void)
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Closing pipes causes the Waker thread and io_threads to die, and
|
||||
* closing /dev/lguest cleans up the Guest. Since we don't track all
|
||||
* open fds, we simply close everything beyond stderr. */
|
||||
/* Since we don't track all open fds, we simply close everything beyond
|
||||
* stderr. */
|
||||
for (i = 3; i < FD_SETSIZE; i++)
|
||||
close(i);
|
||||
|
||||
/* The exec automatically gets rid of the I/O and Waker threads. */
|
||||
execv(main_args[0], main_args);
|
||||
err(1, "Could not exec %s", main_args[0]);
|
||||
}
|
||||
|
@ -1663,7 +1909,7 @@ static void __attribute__((noreturn)) run_guest(int lguest_fd)
|
|||
/* ERESTART means that we need to reboot the guest */
|
||||
} else if (errno == ERESTART) {
|
||||
restart_guest();
|
||||
/* EAGAIN means the Waker wanted us to look at some input.
|
||||
/* EAGAIN means a signal (timeout).
|
||||
* Anything else means a bug or incompatible change. */
|
||||
} else if (errno != EAGAIN)
|
||||
err(1, "Running guest failed");
|
||||
|
@ -1691,13 +1937,14 @@ static struct option opts[] = {
|
|||
{ "verbose", 0, NULL, 'v' },
|
||||
{ "tunnet", 1, NULL, 't' },
|
||||
{ "block", 1, NULL, 'b' },
|
||||
{ "rng", 0, NULL, 'r' },
|
||||
{ "initrd", 1, NULL, 'i' },
|
||||
{ NULL },
|
||||
};
|
||||
static void usage(void)
|
||||
{
|
||||
errx(1, "Usage: lguest [--verbose] "
|
||||
"[--tunnet=(<ipaddr>|bridge:<bridgename>)\n"
|
||||
"[--tunnet=(<ipaddr>:<macaddr>|bridge:<bridgename>:<macaddr>)\n"
|
||||
"|--block=<filename>|--initrd=<filename>]...\n"
|
||||
"<mem-in-mb> vmlinux [args...]");
|
||||
}
|
||||
|
@ -1765,6 +2012,9 @@ int main(int argc, char *argv[])
|
|||
case 'b':
|
||||
setup_block_file(optarg);
|
||||
break;
|
||||
case 'r':
|
||||
setup_rng();
|
||||
break;
|
||||
case 'i':
|
||||
initrd_name = optarg;
|
||||
break;
|
||||
|
@ -1783,6 +2033,9 @@ int main(int argc, char *argv[])
|
|||
/* We always have a console device */
|
||||
setup_console();
|
||||
|
||||
/* We can timeout waiting for Guest network transmit. */
|
||||
setup_timeout();
|
||||
|
||||
/* Now we load the kernel */
|
||||
start = load_kernel(open_or_die(argv[optind+1], O_RDONLY));
|
||||
|
||||
|
@ -1826,10 +2079,10 @@ int main(int argc, char *argv[])
|
|||
* /dev/lguest file descriptor. */
|
||||
lguest_fd = tell_kernel(pgdir, start);
|
||||
|
||||
/* We fork off a child process, which wakes the Launcher whenever one
|
||||
* of the input file descriptors needs attention. We call this the
|
||||
* Waker, and we'll cover it in a moment. */
|
||||
waker_fd = setup_waker(lguest_fd);
|
||||
/* We clone off a thread, which wakes the Launcher whenever one of the
|
||||
* input file descriptors needs attention. We call this the Waker, and
|
||||
* we'll cover it in a moment. */
|
||||
setup_waker(lguest_fd);
|
||||
|
||||
/* Finally, run the Guest. This doesn't return. */
|
||||
run_guest(lguest_fd);
|
||||
|
|
|
@ -1024,6 +1024,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
intel-mac-v3 Intel Mac Type 3
|
||||
intel-mac-v4 Intel Mac Type 4
|
||||
intel-mac-v5 Intel Mac Type 5
|
||||
intel-mac-auto Intel Mac (detect type according to subsystem id)
|
||||
macmini Intel Mac Mini (equivalent with type 3)
|
||||
macbook Intel Mac Book (eq. type 5)
|
||||
macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3)
|
||||
|
|
|
@ -73,10 +73,10 @@ recompiled, or use "make C=2" to run sparse on the files whether they need to
|
|||
be recompiled or not. The latter is a fast way to check the whole tree if you
|
||||
have already built it.
|
||||
|
||||
The optional make variable CHECKFLAGS can be used to pass arguments to sparse.
|
||||
The build system passes -Wbitwise to sparse automatically. To perform
|
||||
endianness checks, you may define __CHECK_ENDIAN__:
|
||||
The optional make variable CF can be used to pass arguments to sparse. The
|
||||
build system passes -Wbitwise to sparse automatically. To perform endianness
|
||||
checks, you may define __CHECK_ENDIAN__:
|
||||
|
||||
make C=2 CHECKFLAGS="-D__CHECK_ENDIAN__"
|
||||
make C=2 CF="-D__CHECK_ENDIAN__"
|
||||
|
||||
These checks are disabled by default as they generate a host of warnings.
|
||||
|
|
|
@ -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
|
||||
|
|
3
Kbuild
3
Kbuild
|
@ -43,7 +43,7 @@ $(obj)/$(bounds-file): kernel/bounds.s Kbuild
|
|||
# 2) Generate asm-offsets.h
|
||||
#
|
||||
|
||||
offsets-file := include/asm-$(SRCARCH)/asm-offsets.h
|
||||
offsets-file := include/asm/asm-offsets.h
|
||||
|
||||
always += $(offsets-file)
|
||||
targets += $(offsets-file)
|
||||
|
@ -81,7 +81,6 @@ arch/$(SRCARCH)/kernel/asm-offsets.s: arch/$(SRCARCH)/kernel/asm-offsets.c \
|
|||
$(call if_changed_dep,cc_s_c)
|
||||
|
||||
$(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s Kbuild
|
||||
$(Q)mkdir -p $(dir $@)
|
||||
$(call cmd,offsets)
|
||||
|
||||
#####
|
||||
|
|
|
@ -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
|
||||
|
|
123
Makefile
123
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 26
|
||||
EXTRAVERSION =
|
||||
SUBLEVEL = 27
|
||||
EXTRAVERSION = -rc1
|
||||
NAME = Rotary Wombat
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -205,6 +205,13 @@ ifeq ($(ARCH),x86_64)
|
|||
SRCARCH := x86
|
||||
endif
|
||||
|
||||
# Where to locate arch specific headers
|
||||
ifeq ($(ARCH),sparc64)
|
||||
hdr-arch := sparc
|
||||
else
|
||||
hdr-arch := $(SRCARCH)
|
||||
endif
|
||||
|
||||
KCONFIG_CONFIG ?= .config
|
||||
|
||||
# SHELL used by kbuild
|
||||
|
@ -326,7 +333,8 @@ AFLAGS_KERNEL =
|
|||
# Needed to be compatible with the O= option
|
||||
LINUXINCLUDE := -Iinclude \
|
||||
$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
|
||||
-include include/linux/autoconf.h
|
||||
-I$(srctree)/arch/$(hdr-arch)/include \
|
||||
-include include/linux/autoconf.h
|
||||
|
||||
KBUILD_CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
|
||||
|
||||
|
@ -922,7 +930,9 @@ ifneq ($(KBUILD_SRC),)
|
|||
/bin/false; \
|
||||
fi;
|
||||
$(Q)if [ ! -d include2 ]; then mkdir -p include2; fi;
|
||||
$(Q)ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm
|
||||
$(Q)if [ -e $(srctree)/include/asm-$(SRCARCH)/system.h ]; then \
|
||||
ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \
|
||||
fi
|
||||
endif
|
||||
|
||||
# prepare2 creates a makefile if using a separate output directory
|
||||
|
@ -948,22 +958,34 @@ export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
|
|||
|
||||
# The asm symlink changes when $(ARCH) changes.
|
||||
# Detect this and ask user to run make mrproper
|
||||
|
||||
include/asm: FORCE
|
||||
$(Q)set -e; asmlink=`readlink include/asm | cut -d '-' -f 2`; \
|
||||
if [ -L include/asm ]; then \
|
||||
if [ "$$asmlink" != "$(SRCARCH)" ]; then \
|
||||
define check-symlink
|
||||
set -e; \
|
||||
if [ -L include/asm ]; then \
|
||||
asmlink=`readlink include/asm | cut -d '-' -f 2`; \
|
||||
if [ "$$asmlink" != "$(SRCARCH)" ]; then \
|
||||
echo "ERROR: the symlink $@ points to asm-$$asmlink but asm-$(SRCARCH) was expected"; \
|
||||
echo " set ARCH or save .config and run 'make mrproper' to fix it"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
else \
|
||||
echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \
|
||||
if [ ! -d include ]; then \
|
||||
mkdir -p include; \
|
||||
fi; \
|
||||
ln -fsn asm-$(SRCARCH) $@; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
fi
|
||||
endef
|
||||
|
||||
# We create the target directory of the symlink if it does
|
||||
# not exist so the test in chack-symlink works and we have a
|
||||
# directory for generated filesas used by some architectures.
|
||||
define create-symlink
|
||||
if [ ! -L include/asm ]; then \
|
||||
echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \
|
||||
if [ ! -d include/asm-$(SRCARCH) ]; then \
|
||||
mkdir -p include/asm-$(SRCARCH); \
|
||||
fi; \
|
||||
ln -fsn asm-$(SRCARCH) $@; \
|
||||
fi
|
||||
endef
|
||||
|
||||
include/asm: FORCE
|
||||
$(Q)$(check-symlink)
|
||||
$(Q)$(create-symlink)
|
||||
|
||||
# Generate some files
|
||||
# ---------------------------------------------------------------------------
|
||||
|
@ -1010,36 +1032,43 @@ firmware_install: FORCE
|
|||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Kernel headers
|
||||
INSTALL_HDR_PATH=$(objtree)/usr
|
||||
export INSTALL_HDR_PATH
|
||||
|
||||
HDRFILTER=generic i386 x86_64
|
||||
HDRARCHES=$(filter-out $(HDRFILTER),$(patsubst $(srctree)/include/asm-%/Kbuild,%,$(wildcard $(srctree)/include/asm-*/Kbuild)))
|
||||
#Default location for installed headers
|
||||
export INSTALL_HDR_PATH = $(objtree)/usr
|
||||
|
||||
hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj
|
||||
# Find out where the Kbuild file is located to support
|
||||
# arch/$(ARCH)/include/asm
|
||||
hdr-dir = $(strip \
|
||||
$(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/asm/Kbuild), \
|
||||
arch/$(hdr-arch)/include/asm, include/asm-$(hdr-arch)))
|
||||
|
||||
# If we do an all arch process set dst to asm-$(hdr-arch)
|
||||
hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm)
|
||||
|
||||
PHONY += __headers
|
||||
__headers: include/linux/version.h scripts_basic FORCE
|
||||
$(Q)$(MAKE) $(build)=scripts scripts/unifdef
|
||||
|
||||
PHONY += headers_install_all
|
||||
headers_install_all: include/linux/version.h scripts_basic FORCE
|
||||
$(Q)$(MAKE) $(build)=scripts scripts/unifdef
|
||||
$(Q)for arch in $(HDRARCHES); do \
|
||||
$(MAKE) ARCH=$$arch -f $(srctree)/scripts/Makefile.headersinst obj=include BIASMDIR=-bi-$$arch ;\
|
||||
done
|
||||
headers_install_all:
|
||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/headers.sh install
|
||||
|
||||
PHONY += headers_install
|
||||
headers_install: include/linux/version.h scripts_basic FORCE
|
||||
@if [ ! -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
|
||||
echo '*** Error: Headers not exportable for this architecture ($(SRCARCH))'; \
|
||||
exit 1 ; fi
|
||||
$(Q)$(MAKE) $(build)=scripts scripts/unifdef
|
||||
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst ARCH=$(SRCARCH) obj=include
|
||||
headers_install: __headers
|
||||
$(if $(wildcard $(srctree)/$(hdr-dir)/Kbuild),, \
|
||||
$(error Headers not exportable for the $(SRCARCH) architecture))
|
||||
$(Q)$(MAKE) $(hdr-inst)=include
|
||||
$(Q)$(MAKE) $(hdr-inst)=$(hdr-dir) $(hdr-dst)
|
||||
|
||||
PHONY += headers_check_all
|
||||
headers_check_all: headers_install_all
|
||||
$(Q)for arch in $(HDRARCHES); do \
|
||||
$(MAKE) ARCH=$$arch -f $(srctree)/scripts/Makefile.headersinst obj=include BIASMDIR=-bi-$$arch HDRCHECK=1 ;\
|
||||
done
|
||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/headers.sh check
|
||||
|
||||
PHONY += headers_check
|
||||
headers_check: headers_install
|
||||
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst ARCH=$(SRCARCH) obj=include HDRCHECK=1
|
||||
$(Q)$(MAKE) $(hdr-inst)=include HDRCHECK=1
|
||||
$(Q)$(MAKE) $(hdr-inst)=$(hdr-dir) $(hdr-dst) HDRCHECK=1
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Modules
|
||||
|
@ -1131,7 +1160,7 @@ MRPROPER_FILES += .config .config.old include/asm .version .old_version \
|
|||
include/linux/autoconf.h include/linux/version.h \
|
||||
include/linux/utsrelease.h \
|
||||
include/linux/bounds.h include/asm*/asm-offsets.h \
|
||||
Module.symvers tags TAGS cscope*
|
||||
Module.symvers Module.markers tags TAGS cscope*
|
||||
|
||||
# clean - Delete most, but leave enough to build external modules
|
||||
#
|
||||
|
@ -1150,7 +1179,7 @@ clean: archclean $(clean-dirs)
|
|||
\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
|
||||
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
|
||||
-o -name '*.symtypes' -o -name 'modules.order' \
|
||||
-o -name 'Module.markers' \) \
|
||||
-o -name 'Module.markers' -o -name '.tmp_*.o.*' \) \
|
||||
-type f -print | xargs rm -f
|
||||
|
||||
# mrproper - Delete all generated files, including .config
|
||||
|
@ -1224,21 +1253,17 @@ help:
|
|||
@echo ' cscope - Generate cscope index'
|
||||
@echo ' kernelrelease - Output the release version string'
|
||||
@echo ' kernelversion - Output the version stored in Makefile'
|
||||
@if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
|
||||
echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \
|
||||
@echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \
|
||||
echo ' (default: $(INSTALL_HDR_PATH))'; \
|
||||
fi
|
||||
@echo ''
|
||||
echo ''
|
||||
@echo 'Static analysers'
|
||||
@echo ' checkstack - Generate a list of stack hogs'
|
||||
@echo ' namespacecheck - Name space analysis on compiled kernel'
|
||||
@echo ' versioncheck - Sanity check on version.h usage'
|
||||
@echo ' includecheck - Check for duplicate included header files'
|
||||
@echo ' export_report - List the usages of all exported symbols'
|
||||
@if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
|
||||
echo ' headers_check - Sanity check on exported headers'; \
|
||||
fi
|
||||
@echo ''
|
||||
@echo ' headers_check - Sanity check on exported headers'; \
|
||||
echo ''
|
||||
@echo 'Kernel packaging:'
|
||||
@$(MAKE) $(build)=$(package-dir) help
|
||||
@echo ''
|
||||
|
@ -1411,7 +1436,11 @@ define find-sources
|
|||
\( -name config -o -name 'asm-*' \) -prune \
|
||||
-o -name $1 -print; \
|
||||
for arch in $(ALLINCLUDE_ARCHS) ; do \
|
||||
find $(__srctree)include/asm-$${arch} $(RCS_FIND_IGNORE) \
|
||||
test -e $(__srctree)include/asm-$${arch} && \
|
||||
find $(__srctree)include/asm-$${arch} $(RCS_FIND_IGNORE) \
|
||||
-name $1 -print; \
|
||||
test -e $(__srctree)arch/$${arch}/include/asm && \
|
||||
find $(__srctree)arch/$${arch}/include/asm $(RCS_FIND_IGNORE) \
|
||||
-name $1 -print; \
|
||||
done ; \
|
||||
find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
|
||||
|
|
|
@ -17,6 +17,7 @@ config ARM
|
|||
select HAVE_KRETPROBES if (HAVE_KPROBES)
|
||||
select HAVE_FTRACE if (!XIP_KERNEL)
|
||||
select HAVE_DYNAMIC_FTRACE if (HAVE_FTRACE)
|
||||
select HAVE_GENERIC_DMA_COHERENT
|
||||
help
|
||||
The ARM series is a line of low-power-consumption RISC chip designs
|
||||
licensed by ARM Ltd and targeted at embedded applications and
|
||||
|
@ -234,6 +235,7 @@ config ARCH_VERSATILE
|
|||
config ARCH_AT91
|
||||
bool "Atmel AT91"
|
||||
select GENERIC_GPIO
|
||||
select HAVE_CLK
|
||||
help
|
||||
This enables support for systems based on the Atmel AT91RM9200,
|
||||
AT91SAM9 and AT91CAP9 processors.
|
||||
|
@ -267,7 +269,6 @@ config ARCH_EP93XX
|
|||
select ARM_VIC
|
||||
select GENERIC_GPIO
|
||||
select HAVE_CLK
|
||||
select HAVE_CLK
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
help
|
||||
This enables support for the Cirrus EP93xx series of CPUs.
|
||||
|
@ -314,7 +315,7 @@ config ARCH_IOP32X
|
|||
select PLAT_IOP
|
||||
select PCI
|
||||
select GENERIC_GPIO
|
||||
select HAVE_GPIO_LIB
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
help
|
||||
Support for Intel's 80219 and IOP32X (XScale) family of
|
||||
processors.
|
||||
|
@ -325,7 +326,7 @@ config ARCH_IOP33X
|
|||
select PLAT_IOP
|
||||
select PCI
|
||||
select GENERIC_GPIO
|
||||
select HAVE_GPIO_LIB
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
help
|
||||
Support for Intel's IOP33X (XScale) family of processors.
|
||||
|
||||
|
@ -418,7 +419,7 @@ config ARCH_MXC
|
|||
select GENERIC_CLOCKEVENTS
|
||||
select ARCH_MTD_XIP
|
||||
select GENERIC_GPIO
|
||||
select HAVE_GPIO_LIB
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
help
|
||||
Support for Freescale MXC/iMX-based family of processors
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi
|
|||
tune-$(CONFIG_CPU_ARM740T) :=-mtune=arm7tdmi
|
||||
tune-$(CONFIG_CPU_ARM9TDMI) :=-mtune=arm9tdmi
|
||||
tune-$(CONFIG_CPU_ARM940T) :=-mtune=arm9tdmi
|
||||
tune-$(CONFIG_CPU_ARM946T) :=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi)
|
||||
tune-$(CONFIG_CPU_ARM946E) :=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi)
|
||||
tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi
|
||||
tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi
|
||||
tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi
|
||||
|
|
|
@ -331,17 +331,17 @@ static int locomo_gpio_type(unsigned int irq, unsigned int type)
|
|||
|
||||
mask = 1 << (irq - LOCOMO_IRQ_GPIO_START);
|
||||
|
||||
if (type == IRQT_PROBE) {
|
||||
if (type == IRQ_TYPE_PROBE) {
|
||||
if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
|
||||
return 0;
|
||||
type = __IRQT_RISEDGE | __IRQT_FALEDGE;
|
||||
type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
|
||||
}
|
||||
|
||||
if (type & __IRQT_RISEDGE)
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
GPIO_IRQ_rising_edge |= mask;
|
||||
else
|
||||
GPIO_IRQ_rising_edge &= ~mask;
|
||||
if (type & __IRQT_FALEDGE)
|
||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
GPIO_IRQ_falling_edge |= mask;
|
||||
else
|
||||
GPIO_IRQ_falling_edge &= ~mask;
|
||||
|
@ -473,7 +473,7 @@ static void locomo_setup_irq(struct locomo *lchip)
|
|||
/*
|
||||
* Install handler for IRQ_LOCOMO_HW.
|
||||
*/
|
||||
set_irq_type(lchip->irq, IRQT_FALLING);
|
||||
set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
|
||||
set_irq_chip_data(lchip->irq, irqbase);
|
||||
set_irq_chained_handler(lchip->irq, locomo_handler);
|
||||
|
||||
|
|
|
@ -241,14 +241,14 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
|
|||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned long ip0;
|
||||
|
||||
if (flags == IRQT_PROBE)
|
||||
if (flags == IRQ_TYPE_PROBE)
|
||||
return 0;
|
||||
|
||||
if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0)
|
||||
if ((!(flags & IRQ_TYPE_EDGE_RISING) ^ !(flags & IRQ_TYPE_EDGE_FALLING)) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
ip0 = sa1111_readl(mapbase + SA1111_INTPOL0);
|
||||
if (flags & __IRQT_RISEDGE)
|
||||
if (flags & IRQ_TYPE_EDGE_RISING)
|
||||
ip0 &= ~mask;
|
||||
else
|
||||
ip0 |= mask;
|
||||
|
@ -338,14 +338,14 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
|
|||
void __iomem *mapbase = get_irq_chip_data(irq);
|
||||
unsigned long ip1;
|
||||
|
||||
if (flags == IRQT_PROBE)
|
||||
if (flags == IRQ_TYPE_PROBE)
|
||||
return 0;
|
||||
|
||||
if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0)
|
||||
if ((!(flags & IRQ_TYPE_EDGE_RISING) ^ !(flags & IRQ_TYPE_EDGE_FALLING)) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
ip1 = sa1111_readl(mapbase + SA1111_INTPOL1);
|
||||
if (flags & __IRQT_RISEDGE)
|
||||
if (flags & IRQ_TYPE_EDGE_RISING)
|
||||
ip1 &= ~mask;
|
||||
else
|
||||
ip1 |= mask;
|
||||
|
@ -427,7 +427,7 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
|
|||
/*
|
||||
* Register SA1111 interrupt
|
||||
*/
|
||||
set_irq_type(sachip->irq, IRQT_RISING);
|
||||
set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
|
||||
set_irq_data(sachip->irq, irqbase);
|
||||
set_irq_chained_handler(sachip->irq, sa1111_irq_handler);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -330,10 +330,10 @@ static void __init cap9adk_board_init(void)
|
|||
/* Serial */
|
||||
at91_add_device_serial();
|
||||
/* USB Host */
|
||||
set_irq_type(AT91CAP9_ID_UHP, IRQT_HIGH);
|
||||
set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH);
|
||||
at91_add_device_usbh(&cap9adk_usbh_data);
|
||||
/* USB HS */
|
||||
set_irq_type(AT91CAP9_ID_UDPHS, IRQT_HIGH);
|
||||
set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH);
|
||||
at91_add_device_usba(&cap9adk_usba_udc_data);
|
||||
/* SPI */
|
||||
at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices));
|
||||
|
@ -350,7 +350,7 @@ static void __init cap9adk_board_init(void)
|
|||
/* I2C */
|
||||
at91_add_device_i2c(NULL, 0);
|
||||
/* LCD Controller */
|
||||
set_irq_type(AT91CAP9_ID_LCDC, IRQT_HIGH);
|
||||
set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH);
|
||||
at91_add_device_lcdc(&cap9adk_lcdc_data);
|
||||
/* AC97 */
|
||||
at91_add_device_ac97(&cap9adk_ac97_data);
|
||||
|
|
|
@ -56,19 +56,19 @@ static int at91_aic_set_type(unsigned irq, unsigned type)
|
|||
unsigned int smr, srctype;
|
||||
|
||||
switch (type) {
|
||||
case IRQT_HIGH:
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
srctype = AT91_AIC_SRCTYPE_HIGH;
|
||||
break;
|
||||
case IRQT_RISING:
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
srctype = AT91_AIC_SRCTYPE_RISING;
|
||||
break;
|
||||
case IRQT_LOW:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */
|
||||
srctype = AT91_AIC_SRCTYPE_LOW;
|
||||
else
|
||||
return -EINVAL;
|
||||
break;
|
||||
case IRQT_FALLING:
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */
|
||||
srctype = AT91_AIC_SRCTYPE_FALLING;
|
||||
else
|
||||
|
|
|
@ -226,7 +226,7 @@ static void ep93xx_gpio_irq_ack(unsigned int irq)
|
|||
int port = line >> 3;
|
||||
int port_mask = 1 << (line & 7);
|
||||
|
||||
if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) {
|
||||
if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
|
||||
gpio_int_type2[port] ^= port_mask; /* switch edge direction */
|
||||
ep93xx_gpio_update_int_params(port);
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
|
|||
int port = line >> 3;
|
||||
int port_mask = 1 << (line & 7);
|
||||
|
||||
if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE)
|
||||
if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
|
||||
gpio_int_type2[port] ^= port_mask; /* switch edge direction */
|
||||
|
||||
gpio_int_unmasked[port] &= ~port_mask;
|
||||
|
@ -283,27 +283,27 @@ static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
|
|||
gpio_direction_input(gpio);
|
||||
|
||||
switch (type) {
|
||||
case IRQT_RISING:
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
gpio_int_type1[port] |= port_mask;
|
||||
gpio_int_type2[port] |= port_mask;
|
||||
desc->handle_irq = handle_edge_irq;
|
||||
break;
|
||||
case IRQT_FALLING:
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
gpio_int_type1[port] |= port_mask;
|
||||
gpio_int_type2[port] &= ~port_mask;
|
||||
desc->handle_irq = handle_edge_irq;
|
||||
break;
|
||||
case IRQT_HIGH:
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
gpio_int_type1[port] &= ~port_mask;
|
||||
gpio_int_type2[port] |= port_mask;
|
||||
desc->handle_irq = handle_level_irq;
|
||||
break;
|
||||
case IRQT_LOW:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
gpio_int_type1[port] &= ~port_mask;
|
||||
gpio_int_type2[port] &= ~port_mask;
|
||||
desc->handle_irq = handle_level_irq;
|
||||
break;
|
||||
case IRQT_BOTHEDGE:
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
gpio_int_type1[port] |= port_mask;
|
||||
/* set initial polarity based on current input level */
|
||||
if (gpio_get_value(gpio))
|
||||
|
|
|
@ -111,7 +111,7 @@ imx_gpio_irq_type(unsigned int _irq, unsigned int type)
|
|||
reg = irq >> 5;
|
||||
bit = 1 << (irq % 32);
|
||||
|
||||
if (type == IRQT_PROBE) {
|
||||
if (type == IRQ_TYPE_PROBE) {
|
||||
/* Don't mess with enabled GPIOs using preconfigured edges or
|
||||
GPIOs set to alternate function during probe */
|
||||
/* TODO: support probe */
|
||||
|
@ -120,7 +120,7 @@ imx_gpio_irq_type(unsigned int _irq, unsigned int type)
|
|||
// return 0;
|
||||
// if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))
|
||||
// return 0;
|
||||
// type = __IRQT_RISEDGE | __IRQT_FALEDGE;
|
||||
// type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
|
||||
}
|
||||
|
||||
GIUS(reg) |= bit;
|
||||
|
@ -128,19 +128,19 @@ imx_gpio_irq_type(unsigned int _irq, unsigned int type)
|
|||
|
||||
DEBUG_IRQ("setting type of irq %d to ", _irq);
|
||||
|
||||
if (type & __IRQT_RISEDGE) {
|
||||
if (type & IRQ_TYPE_EDGE_RISING) {
|
||||
DEBUG_IRQ("rising edges\n");
|
||||
irq_type = 0x0;
|
||||
}
|
||||
if (type & __IRQT_FALEDGE) {
|
||||
if (type & IRQ_TYPE_EDGE_FALLING) {
|
||||
DEBUG_IRQ("falling edges\n");
|
||||
irq_type = 0x1;
|
||||
}
|
||||
if (type & __IRQT_LOWLVL) {
|
||||
if (type & IRQ_TYPE_LEVEL_LOW) {
|
||||
DEBUG_IRQ("low level\n");
|
||||
irq_type = 0x3;
|
||||
}
|
||||
if (type & __IRQT_HIGHLVL) {
|
||||
if (type & IRQ_TYPE_LEVEL_HIGH) {
|
||||
DEBUG_IRQ("high level\n");
|
||||
irq_type = 0x2;
|
||||
}
|
||||
|
|
|
@ -329,19 +329,19 @@ static int ixp2000_GPIO_irq_type(unsigned int irq, unsigned int type)
|
|||
/*
|
||||
* Then, set the proper trigger type.
|
||||
*/
|
||||
if (type & IRQT_FALLING)
|
||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
GPIO_IRQ_falling_edge |= 1 << line;
|
||||
else
|
||||
GPIO_IRQ_falling_edge &= ~(1 << line);
|
||||
if (type & IRQT_RISING)
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
GPIO_IRQ_rising_edge |= 1 << line;
|
||||
else
|
||||
GPIO_IRQ_rising_edge &= ~(1 << line);
|
||||
if (type & IRQT_LOW)
|
||||
if (type & IRQ_TYPE_LEVEL_LOW)
|
||||
GPIO_IRQ_level_low |= 1 << line;
|
||||
else
|
||||
GPIO_IRQ_level_low &= ~(1 << line);
|
||||
if (type & IRQT_HIGH)
|
||||
if (type & IRQ_TYPE_LEVEL_HIGH)
|
||||
GPIO_IRQ_level_high |= 1 << line;
|
||||
else
|
||||
GPIO_IRQ_level_high &= ~(1 << line);
|
||||
|
|
|
@ -126,23 +126,23 @@ static int ixp23xx_irq_set_type(unsigned int irq, unsigned int type)
|
|||
return -EINVAL;
|
||||
|
||||
switch (type) {
|
||||
case IRQT_BOTHEDGE:
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
int_style = IXP23XX_GPIO_STYLE_TRANSITIONAL;
|
||||
irq_type = IXP23XX_IRQ_EDGE;
|
||||
break;
|
||||
case IRQT_RISING:
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
int_style = IXP23XX_GPIO_STYLE_RISING_EDGE;
|
||||
irq_type = IXP23XX_IRQ_EDGE;
|
||||
break;
|
||||
case IRQT_FALLING:
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
int_style = IXP23XX_GPIO_STYLE_FALLING_EDGE;
|
||||
irq_type = IXP23XX_IRQ_EDGE;
|
||||
break;
|
||||
case IRQT_HIGH:
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
int_style = IXP23XX_GPIO_STYLE_ACTIVE_HIGH;
|
||||
irq_type = IXP23XX_IRQ_LEVEL;
|
||||
break;
|
||||
case IRQT_LOW:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
int_style = IXP23XX_GPIO_STYLE_ACTIVE_LOW;
|
||||
irq_type = IXP23XX_IRQ_LEVEL;
|
||||
break;
|
||||
|
|
|
@ -110,8 +110,8 @@ static int __init roadrunner_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
|
|||
|
||||
static void __init roadrunner_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQT_LOW);
|
||||
set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQT_LOW);
|
||||
set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
|
||||
|
||||
ixp23xx_pci_preinit();
|
||||
}
|
||||
|
|
|
@ -30,10 +30,10 @@
|
|||
|
||||
void __init avila_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_AVILA_PCI_INTA, IRQT_LOW);
|
||||
set_irq_type(IRQ_AVILA_PCI_INTB, IRQT_LOW);
|
||||
set_irq_type(IRQ_AVILA_PCI_INTC, IRQT_LOW);
|
||||
set_irq_type(IRQ_AVILA_PCI_INTD, IRQT_LOW);
|
||||
set_irq_type(IRQ_AVILA_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_AVILA_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_AVILA_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_AVILA_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
|
|
@ -142,23 +142,23 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
|
|||
return -EINVAL;
|
||||
|
||||
switch (type){
|
||||
case IRQT_BOTHEDGE:
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
break;
|
||||
case IRQT_RISING:
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
int_style = IXP4XX_GPIO_STYLE_RISING_EDGE;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
break;
|
||||
case IRQT_FALLING:
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
break;
|
||||
case IRQT_HIGH:
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
|
||||
irq_type = IXP4XX_IRQ_LEVEL;
|
||||
break;
|
||||
case IRQT_LOW:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
|
||||
irq_type = IXP4XX_IRQ_LEVEL;
|
||||
break;
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
void __init coyote_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQT_LOW);
|
||||
set_irq_type(IRQ_COYOTE_PCI_SLOT1, IRQT_LOW);
|
||||
set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_COYOTE_PCI_SLOT1, IRQ_TYPE_LEVEL_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
|
||||
void __init dsmg600_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_DSMG600_PCI_INTA, IRQT_LOW);
|
||||
set_irq_type(IRQ_DSMG600_PCI_INTB, IRQT_LOW);
|
||||
set_irq_type(IRQ_DSMG600_PCI_INTC, IRQT_LOW);
|
||||
set_irq_type(IRQ_DSMG600_PCI_INTD, IRQT_LOW);
|
||||
set_irq_type(IRQ_DSMG600_PCI_INTE, IRQT_LOW);
|
||||
set_irq_type(IRQ_DSMG600_PCI_INTF, IRQT_LOW);
|
||||
set_irq_type(IRQ_DSMG600_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_DSMG600_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_DSMG600_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_DSMG600_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_DSMG600_PCI_INTE, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_DSMG600_PCI_INTF, IRQ_TYPE_LEVEL_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
void __init fsg_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_FSG_PCI_INTA, IRQT_LOW);
|
||||
set_irq_type(IRQ_FSG_PCI_INTB, IRQT_LOW);
|
||||
set_irq_type(IRQ_FSG_PCI_INTC, IRQT_LOW);
|
||||
set_irq_type(IRQ_FSG_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_FSG_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_FSG_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
|
||||
void __init gateway7001_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_IXP4XX_GPIO10, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXP4XX_GPIO11, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
|
|
@ -41,10 +41,10 @@
|
|||
*/
|
||||
void __init gtwx5715_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(GTWX5715_PCI_SLOT0_INTA_IRQ, IRQT_LOW);
|
||||
set_irq_type(GTWX5715_PCI_SLOT0_INTB_IRQ, IRQT_LOW);
|
||||
set_irq_type(GTWX5715_PCI_SLOT1_INTA_IRQ, IRQT_LOW);
|
||||
set_irq_type(GTWX5715_PCI_SLOT1_INTB_IRQ, IRQT_LOW);
|
||||
set_irq_type(GTWX5715_PCI_SLOT0_INTA_IRQ, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(GTWX5715_PCI_SLOT0_INTB_IRQ, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(GTWX5715_PCI_SLOT1_INTA_IRQ, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(GTWX5715_PCI_SLOT1_INTB_IRQ, IRQ_TYPE_LEVEL_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
|
||||
void __init ixdp425_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_IXDP425_PCI_INTA, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXDP425_PCI_INTB, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXDP425_PCI_INTC, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXDP425_PCI_INTD, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXDP425_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_IXDP425_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_IXDP425_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_IXDP425_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
void __init ixdpg425_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_IXP4XX_GPIO6, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXP4XX_GPIO7, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_IXP4XX_GPIO7, IRQ_TYPE_LEVEL_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
|
|
@ -24,11 +24,11 @@
|
|||
|
||||
void __init nas100d_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_NAS100D_PCI_INTA, IRQT_LOW);
|
||||
set_irq_type(IRQ_NAS100D_PCI_INTB, IRQT_LOW);
|
||||
set_irq_type(IRQ_NAS100D_PCI_INTC, IRQT_LOW);
|
||||
set_irq_type(IRQ_NAS100D_PCI_INTD, IRQT_LOW);
|
||||
set_irq_type(IRQ_NAS100D_PCI_INTE, IRQT_LOW);
|
||||
set_irq_type(IRQ_NAS100D_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_NAS100D_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_NAS100D_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_NAS100D_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_NAS100D_PCI_INTE, IRQ_TYPE_LEVEL_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
|
||||
void __init nslu2_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_NSLU2_PCI_INTA, IRQT_LOW);
|
||||
set_irq_type(IRQ_NSLU2_PCI_INTB, IRQT_LOW);
|
||||
set_irq_type(IRQ_NSLU2_PCI_INTC, IRQT_LOW);
|
||||
set_irq_type(IRQ_NSLU2_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_NSLU2_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_NSLU2_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
|
||||
void __init wg302v2_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_IXP4XX_GPIO8, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXP4XX_GPIO9, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW);
|
||||
set_irq_type(IRQ_IXP4XX_GPIO9, IRQ_TYPE_LEVEL_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
|
|
@ -72,21 +72,21 @@ static int ks8695_irq_set_type(unsigned int irqno, unsigned int type)
|
|||
ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
|
||||
|
||||
switch (type) {
|
||||
case IRQT_HIGH:
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
mode = IOPC_TM_HIGH;
|
||||
level_triggered = 1;
|
||||
break;
|
||||
case IRQT_LOW:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
mode = IOPC_TM_LOW;
|
||||
level_triggered = 1;
|
||||
break;
|
||||
case IRQT_RISING:
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
mode = IOPC_TM_RISING;
|
||||
break;
|
||||
case IRQT_FALLING:
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
mode = IOPC_TM_FALLING;
|
||||
break;
|
||||
case IRQT_BOTHEDGE:
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
mode = IOPC_TM_EDGE;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -99,19 +99,19 @@ netx_hif_irq_type(unsigned int _irq, unsigned int type)
|
|||
|
||||
irq = _irq - NETX_IRQ_HIF_CHAINED(0);
|
||||
|
||||
if (type & __IRQT_RISEDGE) {
|
||||
if (type & IRQ_TYPE_EDGE_RISING) {
|
||||
DEBUG_IRQ("rising edges\n");
|
||||
val |= (1 << 26) << irq;
|
||||
}
|
||||
if (type & __IRQT_FALEDGE) {
|
||||
if (type & IRQ_TYPE_EDGE_FALLING) {
|
||||
DEBUG_IRQ("falling edges\n");
|
||||
val &= ~((1 << 26) << irq);
|
||||
}
|
||||
if (type & __IRQT_LOWLVL) {
|
||||
if (type & IRQ_TYPE_LEVEL_LOW) {
|
||||
DEBUG_IRQ("low level\n");
|
||||
val &= ~((1 << 26) << irq);
|
||||
}
|
||||
if (type & __IRQT_HIGHLVL) {
|
||||
if (type & IRQ_TYPE_LEVEL_HIGH) {
|
||||
DEBUG_IRQ("high level\n");
|
||||
val |= (1 << 26) << irq;
|
||||
}
|
||||
|
|
|
@ -288,7 +288,7 @@ static void __init osk_init_cf(void)
|
|||
return;
|
||||
}
|
||||
/* the CF I/O IRQ is really active-low */
|
||||
set_irq_type(OMAP_GPIO_IRQ(62), IRQT_FALLING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(62), IRQ_TYPE_EDGE_FALLING);
|
||||
}
|
||||
|
||||
static void __init osk_init_irq(void)
|
||||
|
@ -483,7 +483,7 @@ static void __init osk_mistral_init(void)
|
|||
omap_cfg_reg(P20_1610_GPIO4); /* PENIRQ */
|
||||
gpio_request(4, "ts_int");
|
||||
gpio_direction_input(4);
|
||||
set_irq_type(OMAP_GPIO_IRQ(4), IRQT_FALLING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(4), IRQ_TYPE_EDGE_FALLING);
|
||||
|
||||
spi_register_board_info(mistral_boardinfo,
|
||||
ARRAY_SIZE(mistral_boardinfo));
|
||||
|
@ -494,7 +494,7 @@ static void __init osk_mistral_init(void)
|
|||
int ret = 0;
|
||||
|
||||
gpio_direction_input(OMAP_MPUIO(2));
|
||||
set_irq_type(OMAP_GPIO_IRQ(OMAP_MPUIO(2)), IRQT_RISING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(OMAP_MPUIO(2)), IRQ_TYPE_EDGE_RISING);
|
||||
#ifdef CONFIG_PM
|
||||
/* share the IRQ in case someone wants to use the
|
||||
* button for more than wakeup from system sleep.
|
||||
|
|
|
@ -298,11 +298,11 @@ palmz71_powercable(int irq, void *dev_id)
|
|||
if (omap_get_gpio_datain(PALMZ71_USBDETECT_GPIO)) {
|
||||
printk(KERN_INFO "PM: Power cable connected\n");
|
||||
set_irq_type(OMAP_GPIO_IRQ(PALMZ71_USBDETECT_GPIO),
|
||||
IRQT_FALLING);
|
||||
IRQ_TYPE_EDGE_FALLING);
|
||||
} else {
|
||||
printk(KERN_INFO "PM: Power cable disconnected\n");
|
||||
set_irq_type(OMAP_GPIO_IRQ(PALMZ71_USBDETECT_GPIO),
|
||||
IRQT_RISING);
|
||||
IRQ_TYPE_EDGE_RISING);
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
|
|
@ -186,10 +186,10 @@ static void __init voiceblue_init(void)
|
|||
omap_request_gpio(13);
|
||||
omap_request_gpio(14);
|
||||
omap_request_gpio(15);
|
||||
set_irq_type(OMAP_GPIO_IRQ(12), IRQT_RISING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(13), IRQT_RISING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(14), IRQT_RISING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(15), IRQT_RISING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(12), IRQ_TYPE_EDGE_RISING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(13), IRQ_TYPE_EDGE_RISING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(14), IRQ_TYPE_EDGE_RISING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(15), IRQ_TYPE_EDGE_RISING);
|
||||
|
||||
platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
|
||||
omap_board_config = voiceblue_config;
|
||||
|
|
|
@ -181,7 +181,7 @@ void omap1510_fpga_init_irq(void)
|
|||
*/
|
||||
omap_request_gpio(13);
|
||||
omap_set_gpio_direction(13, 1);
|
||||
set_irq_type(OMAP_GPIO_IRQ(13), IRQT_RISING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(13), IRQ_TYPE_EDGE_RISING);
|
||||
set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux);
|
||||
}
|
||||
|
||||
|
|
|
@ -337,17 +337,17 @@ static void __init apollon_sw_init(void)
|
|||
omap_request_gpio(SW_DOWN_GPIO58);
|
||||
omap_set_gpio_direction(SW_DOWN_GPIO58, 1);
|
||||
|
||||
set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQT_RISING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQ_TYPE_EDGE_RISING);
|
||||
if (request_irq(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), &apollon_sw_interrupt,
|
||||
IRQF_SHARED, "enter sw",
|
||||
&apollon_sw_interrupt))
|
||||
return;
|
||||
set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQT_RISING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQ_TYPE_EDGE_RISING);
|
||||
if (request_irq(OMAP_GPIO_IRQ(SW_UP_GPIO17), &apollon_sw_interrupt,
|
||||
IRQF_SHARED, "up sw",
|
||||
&apollon_sw_interrupt))
|
||||
return;
|
||||
set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQT_RISING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQ_TYPE_EDGE_RISING);
|
||||
if (request_irq(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), &apollon_sw_interrupt,
|
||||
IRQF_SHARED, "down sw",
|
||||
&apollon_sw_interrupt))
|
||||
|
|
|
@ -213,7 +213,7 @@ void __init db88f5281_pci_preinit(void)
|
|||
pin = DB88F5281_PCI_SLOT0_IRQ_PIN;
|
||||
if (gpio_request(pin, "PCI Int1") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
set_irq_type(gpio_to_irq(pin), IRQT_LOW);
|
||||
set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "db88f5281_pci_preinit faield to "
|
||||
"set_irq_type pin %d\n", pin);
|
||||
|
@ -226,7 +226,7 @@ void __init db88f5281_pci_preinit(void)
|
|||
pin = DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN;
|
||||
if (gpio_request(pin, "PCI Int2") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
set_irq_type(gpio_to_irq(pin), IRQT_LOW);
|
||||
set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "db88f5281_pci_preinit faield "
|
||||
"to set_irq_type pin %d\n", pin);
|
||||
|
|
|
@ -91,27 +91,27 @@ static int orion5x_gpio_set_irq_type(u32 irq, u32 type)
|
|||
desc = irq_desc + irq;
|
||||
|
||||
switch (type) {
|
||||
case IRQT_HIGH:
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
desc->handle_irq = handle_level_irq;
|
||||
desc->status |= IRQ_LEVEL;
|
||||
orion5x_clrbits(GPIO_IN_POL, (1 << pin));
|
||||
break;
|
||||
case IRQT_LOW:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
desc->handle_irq = handle_level_irq;
|
||||
desc->status |= IRQ_LEVEL;
|
||||
orion5x_setbits(GPIO_IN_POL, (1 << pin));
|
||||
break;
|
||||
case IRQT_RISING:
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
desc->handle_irq = handle_edge_irq;
|
||||
desc->status &= ~IRQ_LEVEL;
|
||||
orion5x_clrbits(GPIO_IN_POL, (1 << pin));
|
||||
break;
|
||||
case IRQT_FALLING:
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
desc->handle_irq = handle_edge_irq;
|
||||
desc->status &= ~IRQ_LEVEL;
|
||||
orion5x_setbits(GPIO_IN_POL, (1 << pin));
|
||||
break;
|
||||
case IRQT_BOTHEDGE:
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
desc->handle_irq = handle_edge_irq;
|
||||
desc->status &= ~IRQ_LEVEL;
|
||||
/*
|
||||
|
@ -156,7 +156,7 @@ static void orion5x_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|||
if (cause & (1 << pin)) {
|
||||
irq = gpio_to_irq(pin);
|
||||
desc = irq_desc + irq;
|
||||
if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) {
|
||||
if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
|
||||
/* Swap polarity (race with GPIO line) */
|
||||
u32 polarity = readl(GPIO_IN_POL);
|
||||
polarity ^= 1 << pin;
|
||||
|
|
|
@ -148,7 +148,7 @@ void __init rd88f5182_pci_preinit(void)
|
|||
pin = RD88F5182_PCI_SLOT0_IRQ_A_PIN;
|
||||
if (gpio_request(pin, "PCI IntA") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
set_irq_type(gpio_to_irq(pin), IRQT_LOW);
|
||||
set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "rd88f5182_pci_preinit faield to "
|
||||
"set_irq_type pin %d\n", pin);
|
||||
|
@ -161,7 +161,7 @@ void __init rd88f5182_pci_preinit(void)
|
|||
pin = RD88F5182_PCI_SLOT0_IRQ_B_PIN;
|
||||
if (gpio_request(pin, "PCI IntB") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
set_irq_type(gpio_to_irq(pin), IRQT_LOW);
|
||||
set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "rd88f5182_pci_preinit faield to "
|
||||
"set_irq_type pin %d\n", pin);
|
||||
|
|
|
@ -117,7 +117,7 @@ void __init qnap_ts209_pci_preinit(void)
|
|||
pin = QNAP_TS209_PCI_SLOT0_IRQ_PIN;
|
||||
if (gpio_request(pin, "PCI Int1") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
set_irq_type(gpio_to_irq(pin), IRQT_LOW);
|
||||
set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "qnap_ts209_pci_preinit failed to "
|
||||
"set_irq_type pin %d\n", pin);
|
||||
|
@ -131,7 +131,7 @@ void __init qnap_ts209_pci_preinit(void)
|
|||
pin = QNAP_TS209_PCI_SLOT1_IRQ_PIN;
|
||||
if (gpio_request(pin, "PCI Int2") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
set_irq_type(gpio_to_irq(pin), IRQT_LOW);
|
||||
set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "qnap_ts209_pci_preinit failed "
|
||||
"to set_irq_type pin %d\n", pin);
|
||||
|
|
|
@ -56,28 +56,28 @@ static void pnx4008_mask_ack_irq(unsigned int irq)
|
|||
static int pnx4008_set_irq_type(unsigned int irq, unsigned int type)
|
||||
{
|
||||
switch (type) {
|
||||
case IRQT_RISING:
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
__raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */
|
||||
__raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /*rising edge */
|
||||
set_irq_handler(irq, handle_edge_irq);
|
||||
break;
|
||||
case IRQT_FALLING:
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
__raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */
|
||||
__raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*falling edge */
|
||||
set_irq_handler(irq, handle_edge_irq);
|
||||
break;
|
||||
case IRQT_LOW:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
__raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */
|
||||
__raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*low level */
|
||||
set_irq_handler(irq, handle_level_irq);
|
||||
break;
|
||||
case IRQT_HIGH:
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
__raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */
|
||||
__raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /* high level */
|
||||
set_irq_handler(irq, handle_level_irq);
|
||||
break;
|
||||
|
||||
/* IRQT_BOTHEDGE is not supported */
|
||||
/* IRQ_TYPE_EDGE_BOTH is not supported */
|
||||
default:
|
||||
printk(KERN_ERR "PNX4008 IRQ: Unsupported irq type %d\n", type);
|
||||
return -1;
|
||||
|
|
|
@ -71,7 +71,7 @@ void __cmx270_pci_init_irq(int irq_gpio)
|
|||
|
||||
cmx270_it8152_irq_gpio = irq_gpio;
|
||||
|
||||
set_irq_type(gpio_to_irq(irq_gpio), IRQT_RISING);
|
||||
set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING);
|
||||
|
||||
set_irq_chained_handler(gpio_to_irq(irq_gpio), cmx270_it8152_irq_demux);
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ static void __init lpd270_init_irq(void)
|
|||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
set_irq_chained_handler(IRQ_GPIO(0), lpd270_irq_handler);
|
||||
set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
|
||||
set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@ static void __init lubbock_init_irq(void)
|
|||
}
|
||||
|
||||
set_irq_chained_handler(IRQ_GPIO(0), lubbock_irq_handler);
|
||||
set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
|
||||
set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
|
|
@ -191,7 +191,7 @@ static void __init mainstone_init_irq(void)
|
|||
MST_INTSETCLR = 0;
|
||||
|
||||
set_irq_chained_handler(IRQ_GPIO(0), mainstone_irq_handler);
|
||||
set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
|
||||
set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
|
|
@ -146,18 +146,18 @@ void sharpsl_pm_pxa_init(void)
|
|||
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED, "AC Input Detect", sharpsl_ac_isr)) {
|
||||
dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin));
|
||||
}
|
||||
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQT_BOTHEDGE);
|
||||
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQ_TYPE_EDGE_BOTH);
|
||||
|
||||
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED, "Battery Cover", sharpsl_fatal_isr)) {
|
||||
dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock));
|
||||
}
|
||||
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQT_FALLING);
|
||||
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQ_TYPE_EDGE_FALLING);
|
||||
|
||||
if (sharpsl_pm.machinfo->gpio_fatal) {
|
||||
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED, "Fatal Battery", sharpsl_fatal_isr)) {
|
||||
dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal));
|
||||
}
|
||||
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQT_FALLING);
|
||||
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQ_TYPE_EDGE_FALLING);
|
||||
}
|
||||
|
||||
if (sharpsl_pm.machinfo->batfull_irq)
|
||||
|
@ -166,7 +166,7 @@ void sharpsl_pm_pxa_init(void)
|
|||
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED, "CO", sharpsl_chrg_full_isr)) {
|
||||
dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull));
|
||||
}
|
||||
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING);
|
||||
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQ_TYPE_EDGE_RISING);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ static struct resource dm9000_resources[] = {
|
|||
[2] = {
|
||||
.start = TRIZEPS4_ETH_IRQ,
|
||||
.end = TRIZEPS4_ETH_IRQ,
|
||||
.flags = (IORESOURCE_IRQ | IRQT_RISING),
|
||||
.flags = (IORESOURCE_IRQ | IRQ_TYPE_EDGE_RISING),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ static struct resource cerf_flash_resource = {
|
|||
static void __init cerf_init_irq(void)
|
||||
{
|
||||
sa1100_init_irq();
|
||||
set_irq_type(CERF_ETH_IRQ, IRQT_RISING);
|
||||
set_irq_type(CERF_ETH_IRQ, IRQ_TYPE_EDGE_RISING);
|
||||
}
|
||||
|
||||
static struct map_desc cerf_io_desc[] __initdata = {
|
||||
|
|
|
@ -834,7 +834,7 @@ static void __init h3800_init_irq(void)
|
|||
set_irq_chip(irq, &h3800_gpio_irqchip);
|
||||
}
|
||||
#endif
|
||||
set_irq_type(IRQ_GPIO_H3800_ASIC, IRQT_RISING);
|
||||
set_irq_type(IRQ_GPIO_H3800_ASIC, IRQ_TYPE_EDGE_RISING);
|
||||
set_irq_chained_handler(IRQ_GPIO_H3800_ASIC, h3800_IRQ_demux);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,17 +46,17 @@ static int sa1100_gpio_type(unsigned int irq, unsigned int type)
|
|||
else
|
||||
mask = GPIO11_27_MASK(irq);
|
||||
|
||||
if (type == IRQT_PROBE) {
|
||||
if (type == IRQ_TYPE_PROBE) {
|
||||
if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
|
||||
return 0;
|
||||
type = __IRQT_RISEDGE | __IRQT_FALEDGE;
|
||||
type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
|
||||
}
|
||||
|
||||
if (type & __IRQT_RISEDGE) {
|
||||
if (type & IRQ_TYPE_EDGE_RISING) {
|
||||
GPIO_IRQ_rising_edge |= mask;
|
||||
} else
|
||||
GPIO_IRQ_rising_edge &= ~mask;
|
||||
if (type & __IRQT_FALEDGE) {
|
||||
if (type & IRQ_TYPE_EDGE_FALLING) {
|
||||
GPIO_IRQ_falling_edge |= mask;
|
||||
} else
|
||||
GPIO_IRQ_falling_edge &= ~mask;
|
||||
|
|
|
@ -151,7 +151,7 @@ static int __devinit neponset_probe(struct platform_device *dev)
|
|||
/*
|
||||
* Install handler for GPIO25.
|
||||
*/
|
||||
set_irq_type(IRQ_GPIO25, IRQT_RISING);
|
||||
set_irq_type(IRQ_GPIO25, IRQ_TYPE_EDGE_RISING);
|
||||
set_irq_chained_handler(IRQ_GPIO25, neponset_irq_handler);
|
||||
|
||||
/*
|
||||
|
|
|
@ -143,7 +143,7 @@ static void __init pleb_map_io(void)
|
|||
|
||||
GPDR &= ~GPIO_ETH0_IRQ;
|
||||
|
||||
set_irq_type(GPIO_ETH0_IRQ, IRQT_FALLING);
|
||||
set_irq_type(GPIO_ETH0_IRQ, IRQ_TYPE_EDGE_FALLING);
|
||||
}
|
||||
|
||||
MACHINE_START(PLEB, "PLEB")
|
||||
|
|
|
@ -274,6 +274,11 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
|
|||
void *
|
||||
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
|
||||
{
|
||||
void *memory;
|
||||
|
||||
if (dma_alloc_from_coherent(dev, size, handle, &memory))
|
||||
return memory;
|
||||
|
||||
if (arch_is_coherent()) {
|
||||
void *virt;
|
||||
|
||||
|
@ -362,6 +367,9 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
|
|||
|
||||
WARN_ON(irqs_disabled());
|
||||
|
||||
if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
|
||||
return;
|
||||
|
||||
if (arch_is_coherent()) {
|
||||
kfree(cpu_addr);
|
||||
return;
|
||||
|
|
|
@ -37,7 +37,7 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
|
|||
pgd_t *pgd;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte, entry;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
pgd = pgd_offset(vma->vm_mm, address);
|
||||
if (pgd_none(*pgd))
|
||||
|
@ -54,16 +54,20 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
|
|||
pte = pte_offset_map(pmd, address);
|
||||
entry = *pte;
|
||||
|
||||
/*
|
||||
* If this page is present, it's actually being shared.
|
||||
*/
|
||||
ret = pte_present(entry);
|
||||
|
||||
/*
|
||||
* If this page isn't present, or is already setup to
|
||||
* fault (ie, is old), we can safely ignore any issues.
|
||||
*/
|
||||
if (pte_present(entry) && pte_val(entry) & shared_pte_mask) {
|
||||
if (ret && pte_val(entry) & shared_pte_mask) {
|
||||
flush_cache_page(vma, address, pte_pfn(entry));
|
||||
pte_val(entry) &= ~shared_pte_mask;
|
||||
set_pte_at(vma->vm_mm, address, pte, entry);
|
||||
flush_tlb_page(vma, address);
|
||||
ret = 1;
|
||||
}
|
||||
pte_unmap(pte);
|
||||
return ret;
|
||||
|
|
|
@ -73,19 +73,19 @@ static int gpio_set_irq_type(u32 irq, u32 type)
|
|||
void __iomem *reg = port->base;
|
||||
|
||||
switch (type) {
|
||||
case IRQT_RISING:
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
edge = GPIO_INT_RISE_EDGE;
|
||||
break;
|
||||
case IRQT_FALLING:
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
edge = GPIO_INT_FALL_EDGE;
|
||||
break;
|
||||
case IRQT_LOW:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
edge = GPIO_INT_LOW_LEV;
|
||||
break;
|
||||
case IRQT_HIGH:
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
edge = GPIO_INT_HIGH_LEV;
|
||||
break;
|
||||
default: /* this includes IRQT_BOTHEDGE */
|
||||
default: /* this includes IRQ_TYPE_EDGE_BOTH */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -517,13 +517,13 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
|
|||
u32 gpio_bit = 1 << gpio;
|
||||
|
||||
MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
|
||||
trigger & __IRQT_LOWLVL);
|
||||
trigger & IRQ_TYPE_LEVEL_LOW);
|
||||
MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
|
||||
trigger & __IRQT_HIGHLVL);
|
||||
trigger & IRQ_TYPE_LEVEL_HIGH);
|
||||
MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
|
||||
trigger & __IRQT_RISEDGE);
|
||||
trigger & IRQ_TYPE_EDGE_RISING);
|
||||
MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
|
||||
trigger & __IRQT_FALEDGE);
|
||||
trigger & IRQ_TYPE_EDGE_FALLING);
|
||||
|
||||
if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
|
||||
if (trigger != 0)
|
||||
|
@ -555,9 +555,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
|
|||
case METHOD_MPUIO:
|
||||
reg += OMAP_MPUIO_GPIO_INT_EDGE;
|
||||
l = __raw_readl(reg);
|
||||
if (trigger & __IRQT_RISEDGE)
|
||||
if (trigger & IRQ_TYPE_EDGE_RISING)
|
||||
l |= 1 << gpio;
|
||||
else if (trigger & __IRQT_FALEDGE)
|
||||
else if (trigger & IRQ_TYPE_EDGE_FALLING)
|
||||
l &= ~(1 << gpio);
|
||||
else
|
||||
goto bad;
|
||||
|
@ -567,9 +567,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
|
|||
case METHOD_GPIO_1510:
|
||||
reg += OMAP1510_GPIO_INT_CONTROL;
|
||||
l = __raw_readl(reg);
|
||||
if (trigger & __IRQT_RISEDGE)
|
||||
if (trigger & IRQ_TYPE_EDGE_RISING)
|
||||
l |= 1 << gpio;
|
||||
else if (trigger & __IRQT_FALEDGE)
|
||||
else if (trigger & IRQ_TYPE_EDGE_FALLING)
|
||||
l &= ~(1 << gpio);
|
||||
else
|
||||
goto bad;
|
||||
|
@ -584,9 +584,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
|
|||
gpio &= 0x07;
|
||||
l = __raw_readl(reg);
|
||||
l &= ~(3 << (gpio << 1));
|
||||
if (trigger & __IRQT_RISEDGE)
|
||||
if (trigger & IRQ_TYPE_EDGE_RISING)
|
||||
l |= 2 << (gpio << 1);
|
||||
if (trigger & __IRQT_FALEDGE)
|
||||
if (trigger & IRQ_TYPE_EDGE_FALLING)
|
||||
l |= 1 << (gpio << 1);
|
||||
if (trigger)
|
||||
/* Enable wake-up during idle for dynamic tick */
|
||||
|
@ -599,9 +599,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
|
|||
case METHOD_GPIO_730:
|
||||
reg += OMAP730_GPIO_INT_CONTROL;
|
||||
l = __raw_readl(reg);
|
||||
if (trigger & __IRQT_RISEDGE)
|
||||
if (trigger & IRQ_TYPE_EDGE_RISING)
|
||||
l |= 1 << gpio;
|
||||
else if (trigger & __IRQT_FALEDGE)
|
||||
else if (trigger & IRQ_TYPE_EDGE_FALLING)
|
||||
l &= ~(1 << gpio);
|
||||
else
|
||||
goto bad;
|
||||
|
@ -887,7 +887,7 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio)
|
|||
_set_gpio_direction(bank, get_gpio_index(gpio), 1);
|
||||
_set_gpio_irqenable(bank, gpio, 0);
|
||||
_clear_gpio_irqstatus(bank, gpio);
|
||||
_set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE);
|
||||
_set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
|
||||
}
|
||||
|
||||
/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
|
||||
|
@ -924,7 +924,7 @@ int omap_request_gpio(int gpio)
|
|||
/* Set trigger to none. You need to enable the desired trigger with
|
||||
* request_irq() or set_irq_type().
|
||||
*/
|
||||
_set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE);
|
||||
_set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (bank->method == METHOD_GPIO_1510) {
|
||||
|
|
|
@ -9,7 +9,7 @@ config PLAT_S3C24XX
|
|||
depends on ARCH_S3C2410
|
||||
default y if ARCH_S3C2410
|
||||
select NO_IOPORT
|
||||
select HAVE_GPIO_LIB
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
help
|
||||
Base platform code for any Samsung S3C24XX device
|
||||
|
||||
|
|
|
@ -292,27 +292,27 @@ s3c_irqext_type(unsigned int irq, unsigned int type)
|
|||
/* Set the external interrupt to pointed trigger type */
|
||||
switch (type)
|
||||
{
|
||||
case IRQT_NOEDGE:
|
||||
case IRQ_TYPE_NONE:
|
||||
printk(KERN_WARNING "No edge setting!\n");
|
||||
break;
|
||||
|
||||
case IRQT_RISING:
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
newvalue = S3C2410_EXTINT_RISEEDGE;
|
||||
break;
|
||||
|
||||
case IRQT_FALLING:
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
newvalue = S3C2410_EXTINT_FALLEDGE;
|
||||
break;
|
||||
|
||||
case IRQT_BOTHEDGE:
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
newvalue = S3C2410_EXTINT_BOTHEDGE;
|
||||
break;
|
||||
|
||||
case IRQT_LOW:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
newvalue = S3C2410_EXTINT_LOWLEV;
|
||||
break;
|
||||
|
||||
case IRQT_HIGH:
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
newvalue = S3C2410_EXTINT_HILEV;
|
||||
break;
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include <asm/io.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/atmel-mci.h>
|
||||
|
||||
#include <asm/arch/at32ap700x.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/init.h>
|
||||
|
@ -260,6 +262,21 @@ void __init setup_board(void)
|
|||
at32_setup_serial_console(0);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
|
||||
|
||||
/* MMC card detect requires MACB0 *NOT* be used */
|
||||
#ifdef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM
|
||||
static struct mci_platform_data __initdata mci0_data = {
|
||||
.detect_pin = GPIO_PIN_PC(14), /* gpio30/sdcd */
|
||||
.wp_pin = GPIO_PIN_PC(15), /* gpio31/sdwp */
|
||||
};
|
||||
#define MCI_PDATA &mci0_data
|
||||
#else
|
||||
#define MCI_PDATA NULL
|
||||
#endif /* SW6 for sd{cd,wp} routing */
|
||||
|
||||
#endif /* SW2 for MMC signal routing */
|
||||
|
||||
static int __init atstk1002_init(void)
|
||||
{
|
||||
/*
|
||||
|
@ -309,7 +326,7 @@ static int __init atstk1002_init(void)
|
|||
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
|
||||
#endif
|
||||
#ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM
|
||||
at32_add_device_mci(0, NULL);
|
||||
at32_add_device_mci(0, MCI_PDATA);
|
||||
#endif
|
||||
#ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM
|
||||
set_hw_addr(at32_add_device_eth(1, ð_data[1]));
|
||||
|
|
|
@ -154,7 +154,7 @@ static int __init atstk1003_init(void)
|
|||
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
|
||||
#endif
|
||||
#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
|
||||
at32_add_device_mci(0);
|
||||
at32_add_device_mci(0, NULL);
|
||||
#endif
|
||||
at32_add_device_usba(0, NULL);
|
||||
#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM
|
||||
|
|
|
@ -137,7 +137,7 @@ static int __init atstk1004_init(void)
|
|||
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
|
||||
#endif
|
||||
#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
|
||||
at32_add_device_mci(0);
|
||||
at32_add_device_mci(0, NULL);
|
||||
#endif
|
||||
at32_add_device_lcdc(0, &atstk1000_lcdc_data,
|
||||
fbmem_start, fbmem_size, 0);
|
||||
|
|
|
@ -43,6 +43,9 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
|
|||
{
|
||||
struct clock_event_device *evdev = dev_id;
|
||||
|
||||
if (unlikely(!(intc_get_pending(0) & 1)))
|
||||
return IRQ_NONE;
|
||||
|
||||
/*
|
||||
* Disable the interrupt until the clockevent subsystem
|
||||
* reprograms it.
|
||||
|
@ -55,7 +58,8 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
|
|||
|
||||
static struct irqaction timer_irqaction = {
|
||||
.handler = timer_interrupt,
|
||||
.flags = IRQF_TIMER | IRQF_DISABLED,
|
||||
/* Oprofile uses the same irq as the timer, so allow it to be shared */
|
||||
.flags = IRQF_TIMER | IRQF_DISABLED | IRQF_SHARED,
|
||||
.name = "avr32_comparator",
|
||||
};
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/usb/atmel_usba_udc.h>
|
||||
|
||||
|
@ -1285,7 +1286,6 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
|
|||
{
|
||||
struct mci_platform_data _data;
|
||||
struct platform_device *pdev;
|
||||
struct dw_dma_slave *dws;
|
||||
|
||||
if (id != 0)
|
||||
return NULL;
|
||||
|
@ -1300,7 +1300,9 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
|
|||
|
||||
if (!data) {
|
||||
data = &_data;
|
||||
memset(data, 0, sizeof(struct mci_platform_data));
|
||||
memset(data, -1, sizeof(struct mci_platform_data));
|
||||
data->detect_pin = GPIO_PIN_NONE;
|
||||
data->wp_pin = GPIO_PIN_NONE;
|
||||
}
|
||||
|
||||
if (platform_device_add_data(pdev, data,
|
||||
|
@ -1314,12 +1316,10 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
|
|||
select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */
|
||||
select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */
|
||||
|
||||
if (data) {
|
||||
if (data->detect_pin != GPIO_PIN_NONE)
|
||||
at32_select_gpio(data->detect_pin, 0);
|
||||
if (data->wp_pin != GPIO_PIN_NONE)
|
||||
at32_select_gpio(data->wp_pin, 0);
|
||||
}
|
||||
if (gpio_is_valid(data->detect_pin))
|
||||
at32_select_gpio(data->detect_pin, 0);
|
||||
if (gpio_is_valid(data->wp_pin))
|
||||
at32_select_gpio(data->wp_pin, 0);
|
||||
|
||||
atmel_mci0_pclk.dev = &pdev->dev;
|
||||
|
||||
|
@ -1853,11 +1853,11 @@ at32_add_device_cf(unsigned int id, unsigned int extint,
|
|||
if (at32_init_ide_or_cf(pdev, data->cs, extint))
|
||||
goto fail;
|
||||
|
||||
if (data->detect_pin != GPIO_PIN_NONE)
|
||||
if (gpio_is_valid(data->detect_pin))
|
||||
at32_select_gpio(data->detect_pin, AT32_GPIOF_DEGLITCH);
|
||||
if (data->reset_pin != GPIO_PIN_NONE)
|
||||
if (gpio_is_valid(data->reset_pin))
|
||||
at32_select_gpio(data->reset_pin, 0);
|
||||
if (data->vcc_pin != GPIO_PIN_NONE)
|
||||
if (gpio_is_valid(data->vcc_pin))
|
||||
at32_select_gpio(data->vcc_pin, 0);
|
||||
/* READY is used as extint, so we can't select it as gpio */
|
||||
|
||||
|
@ -1937,9 +1937,11 @@ static struct clk atmel_ac97c0_pclk = {
|
|||
.index = 10,
|
||||
};
|
||||
|
||||
struct platform_device *__init at32_add_device_ac97c(unsigned int id)
|
||||
struct platform_device *__init
|
||||
at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct ac97c_platform_data _data;
|
||||
|
||||
if (id != 0)
|
||||
return NULL;
|
||||
|
@ -1950,19 +1952,37 @@ struct platform_device *__init at32_add_device_ac97c(unsigned int id)
|
|||
|
||||
if (platform_device_add_resources(pdev, atmel_ac97c0_resource,
|
||||
ARRAY_SIZE(atmel_ac97c0_resource)))
|
||||
goto err_add_resources;
|
||||
goto fail;
|
||||
|
||||
select_peripheral(PB(20), PERIPH_B, 0); /* SYNC */
|
||||
select_peripheral(PB(21), PERIPH_B, 0); /* SDO */
|
||||
select_peripheral(PB(22), PERIPH_B, 0); /* SDI */
|
||||
select_peripheral(PB(23), PERIPH_B, 0); /* SCLK */
|
||||
if (!data) {
|
||||
data = &_data;
|
||||
memset(data, 0, sizeof(struct ac97c_platform_data));
|
||||
data->reset_pin = GPIO_PIN_NONE;
|
||||
}
|
||||
|
||||
data->dma_rx_periph_id = 3;
|
||||
data->dma_tx_periph_id = 4;
|
||||
data->dma_controller_id = 0;
|
||||
|
||||
if (platform_device_add_data(pdev, data,
|
||||
sizeof(struct ac97c_platform_data)))
|
||||
goto fail;
|
||||
|
||||
select_peripheral(PB(20), PERIPH_B, 0); /* SDO */
|
||||
select_peripheral(PB(21), PERIPH_B, 0); /* SYNC */
|
||||
select_peripheral(PB(22), PERIPH_B, 0); /* SCLK */
|
||||
select_peripheral(PB(23), PERIPH_B, 0); /* SDI */
|
||||
|
||||
/* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */
|
||||
if (data->reset_pin != GPIO_PIN_NONE)
|
||||
at32_select_gpio(data->reset_pin, 0);
|
||||
|
||||
atmel_ac97c0_pclk.dev = &pdev->dev;
|
||||
|
||||
platform_device_add(pdev);
|
||||
return pdev;
|
||||
|
||||
err_add_resources:
|
||||
fail:
|
||||
platform_device_put(pdev);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -641,6 +641,7 @@ config PCI
|
|||
bool
|
||||
depends on ETRAX_CARDBUS
|
||||
default y
|
||||
select HAVE_GENERIC_DMA_COHERENT
|
||||
|
||||
config ETRAX_IOP_FW_LOAD
|
||||
tristate "IO-processor hotplug firmware loading support"
|
||||
|
|
|
@ -15,35 +15,16 @@
|
|||
#include <linux/pci.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
struct dma_coherent_mem {
|
||||
void *virt_base;
|
||||
u32 device_base;
|
||||
int size;
|
||||
int flags;
|
||||
unsigned long *bitmap;
|
||||
};
|
||||
|
||||
void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t gfp)
|
||||
{
|
||||
void *ret;
|
||||
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
|
||||
int order = get_order(size);
|
||||
/* ignore region specifiers */
|
||||
gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
|
||||
|
||||
if (mem) {
|
||||
int page = bitmap_find_free_region(mem->bitmap, mem->size,
|
||||
order);
|
||||
if (page >= 0) {
|
||||
*dma_handle = mem->device_base + (page << PAGE_SHIFT);
|
||||
ret = mem->virt_base + (page << PAGE_SHIFT);
|
||||
memset(ret, 0, size);
|
||||
return ret;
|
||||
}
|
||||
if (mem->flags & DMA_MEMORY_EXCLUSIVE)
|
||||
return NULL;
|
||||
}
|
||||
if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
|
||||
return ret;
|
||||
|
||||
if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
|
||||
gfp |= GFP_DMA;
|
||||
|
@ -60,90 +41,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
|
|||
void dma_free_coherent(struct device *dev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle)
|
||||
{
|
||||
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
|
||||
int order = get_order(size);
|
||||
|
||||
if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
|
||||
int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
|
||||
|
||||
bitmap_release_region(mem->bitmap, page, order);
|
||||
} else
|
||||
if (!dma_release_from_coherent(dev, order, vaddr))
|
||||
free_pages((unsigned long)vaddr, order);
|
||||
}
|
||||
|
||||
int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
|
||||
dma_addr_t device_addr, size_t size, int flags)
|
||||
{
|
||||
void __iomem *mem_base;
|
||||
int pages = size >> PAGE_SHIFT;
|
||||
int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
|
||||
|
||||
if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
|
||||
goto out;
|
||||
if (!size)
|
||||
goto out;
|
||||
if (dev->dma_mem)
|
||||
goto out;
|
||||
|
||||
/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
|
||||
|
||||
mem_base = ioremap(bus_addr, size);
|
||||
if (!mem_base)
|
||||
goto out;
|
||||
|
||||
dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
|
||||
if (!dev->dma_mem)
|
||||
goto iounmap_out;
|
||||
dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
|
||||
if (!dev->dma_mem->bitmap)
|
||||
goto free1_out;
|
||||
|
||||
dev->dma_mem->virt_base = mem_base;
|
||||
dev->dma_mem->device_base = device_addr;
|
||||
dev->dma_mem->size = pages;
|
||||
dev->dma_mem->flags = flags;
|
||||
|
||||
if (flags & DMA_MEMORY_MAP)
|
||||
return DMA_MEMORY_MAP;
|
||||
|
||||
return DMA_MEMORY_IO;
|
||||
|
||||
free1_out:
|
||||
kfree(dev->dma_mem);
|
||||
iounmap_out:
|
||||
iounmap(mem_base);
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_declare_coherent_memory);
|
||||
|
||||
void dma_release_declared_memory(struct device *dev)
|
||||
{
|
||||
struct dma_coherent_mem *mem = dev->dma_mem;
|
||||
|
||||
if(!mem)
|
||||
return;
|
||||
dev->dma_mem = NULL;
|
||||
iounmap(mem->virt_base);
|
||||
kfree(mem->bitmap);
|
||||
kfree(mem);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_release_declared_memory);
|
||||
|
||||
void *dma_mark_declared_memory_occupied(struct device *dev,
|
||||
dma_addr_t device_addr, size_t size)
|
||||
{
|
||||
struct dma_coherent_mem *mem = dev->dma_mem;
|
||||
int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
int pos, err;
|
||||
|
||||
if (!mem)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
|
||||
err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
|
||||
if (err != 0)
|
||||
return ERR_PTR(err);
|
||||
return mem->virt_base + (pos << PAGE_SHIFT);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
|
||||
|
|
|
@ -125,9 +125,9 @@ void kvm_arch_hardware_enable(void *garbage)
|
|||
PAGE_KERNEL));
|
||||
local_irq_save(saved_psr);
|
||||
slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
|
||||
local_irq_restore(saved_psr);
|
||||
if (slot < 0)
|
||||
return;
|
||||
local_irq_restore(saved_psr);
|
||||
|
||||
spin_lock(&vp_lock);
|
||||
status = ia64_pal_vp_init_env(kvm_vsa_base ?
|
||||
|
@ -160,9 +160,9 @@ void kvm_arch_hardware_disable(void *garbage)
|
|||
|
||||
local_irq_save(saved_psr);
|
||||
slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
|
||||
local_irq_restore(saved_psr);
|
||||
if (slot < 0)
|
||||
return;
|
||||
local_irq_restore(saved_psr);
|
||||
|
||||
status = ia64_pal_vp_exit_env(host_iva);
|
||||
if (status)
|
||||
|
@ -1253,6 +1253,7 @@ static int vti_vcpu_setup(struct kvm_vcpu *vcpu, int id)
|
|||
uninit:
|
||||
kvm_vcpu_uninit(vcpu);
|
||||
fail:
|
||||
local_irq_restore(psr);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
static DEFINE_PER_CPU(struct cpu, cpu_devices);
|
||||
|
||||
static DEFINE_PER_CPU(struct kobject *, cache_toplevel);
|
||||
|
||||
/* SMT stuff */
|
||||
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
|
@ -297,8 +299,289 @@ static struct sysdev_attribute pa6t_attrs[] = {
|
|||
#endif /* CONFIG_DEBUG_KERNEL */
|
||||
};
|
||||
|
||||
struct cache_desc {
|
||||
struct kobject kobj;
|
||||
struct cache_desc *next;
|
||||
const char *type; /* Instruction, Data, or Unified */
|
||||
u32 size; /* total cache size in KB */
|
||||
u32 line_size; /* in bytes */
|
||||
u32 nr_sets; /* number of sets */
|
||||
u32 level; /* e.g. 1, 2, 3... */
|
||||
u32 associativity; /* e.g. 8-way... 0 is fully associative */
|
||||
};
|
||||
|
||||
static void register_cpu_online(unsigned int cpu)
|
||||
DEFINE_PER_CPU(struct cache_desc *, cache_desc);
|
||||
|
||||
static struct cache_desc *kobj_to_cache_desc(struct kobject *k)
|
||||
{
|
||||
return container_of(k, struct cache_desc, kobj);
|
||||
}
|
||||
|
||||
static void cache_desc_release(struct kobject *k)
|
||||
{
|
||||
struct cache_desc *desc = kobj_to_cache_desc(k);
|
||||
|
||||
pr_debug("%s: releasing %s\n", __func__, kobject_name(k));
|
||||
|
||||
if (desc->next)
|
||||
kobject_put(&desc->next->kobj);
|
||||
|
||||
kfree(kobj_to_cache_desc(k));
|
||||
}
|
||||
|
||||
static ssize_t cache_desc_show(struct kobject *k, struct attribute *attr, char *buf)
|
||||
{
|
||||
struct kobj_attribute *kobj_attr;
|
||||
|
||||
kobj_attr = container_of(attr, struct kobj_attribute, attr);
|
||||
|
||||
return kobj_attr->show(k, kobj_attr, buf);
|
||||
}
|
||||
|
||||
static struct sysfs_ops cache_desc_sysfs_ops = {
|
||||
.show = cache_desc_show,
|
||||
};
|
||||
|
||||
static struct kobj_type cache_desc_type = {
|
||||
.release = cache_desc_release,
|
||||
.sysfs_ops = &cache_desc_sysfs_ops,
|
||||
};
|
||||
|
||||
static ssize_t cache_size_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct cache_desc *cache = kobj_to_cache_desc(k);
|
||||
|
||||
return sprintf(buf, "%uK\n", cache->size);
|
||||
}
|
||||
|
||||
static struct kobj_attribute cache_size_attr =
|
||||
__ATTR(size, 0444, cache_size_show, NULL);
|
||||
|
||||
static ssize_t cache_line_size_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct cache_desc *cache = kobj_to_cache_desc(k);
|
||||
|
||||
return sprintf(buf, "%u\n", cache->line_size);
|
||||
}
|
||||
|
||||
static struct kobj_attribute cache_line_size_attr =
|
||||
__ATTR(coherency_line_size, 0444, cache_line_size_show, NULL);
|
||||
|
||||
static ssize_t cache_nr_sets_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct cache_desc *cache = kobj_to_cache_desc(k);
|
||||
|
||||
return sprintf(buf, "%u\n", cache->nr_sets);
|
||||
}
|
||||
|
||||
static struct kobj_attribute cache_nr_sets_attr =
|
||||
__ATTR(number_of_sets, 0444, cache_nr_sets_show, NULL);
|
||||
|
||||
static ssize_t cache_type_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct cache_desc *cache = kobj_to_cache_desc(k);
|
||||
|
||||
return sprintf(buf, "%s\n", cache->type);
|
||||
}
|
||||
|
||||
static struct kobj_attribute cache_type_attr =
|
||||
__ATTR(type, 0444, cache_type_show, NULL);
|
||||
|
||||
static ssize_t cache_level_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct cache_desc *cache = kobj_to_cache_desc(k);
|
||||
|
||||
return sprintf(buf, "%u\n", cache->level);
|
||||
}
|
||||
|
||||
static struct kobj_attribute cache_level_attr =
|
||||
__ATTR(level, 0444, cache_level_show, NULL);
|
||||
|
||||
static ssize_t cache_assoc_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct cache_desc *cache = kobj_to_cache_desc(k);
|
||||
|
||||
return sprintf(buf, "%u\n", cache->associativity);
|
||||
}
|
||||
|
||||
static struct kobj_attribute cache_assoc_attr =
|
||||
__ATTR(ways_of_associativity, 0444, cache_assoc_show, NULL);
|
||||
|
||||
struct cache_desc_info {
|
||||
const char *type;
|
||||
const char *size_prop;
|
||||
const char *line_size_prop;
|
||||
const char *nr_sets_prop;
|
||||
};
|
||||
|
||||
/* PowerPC Processor binding says the [di]-cache-* must be equal on
|
||||
* unified caches, so just use d-cache properties. */
|
||||
static struct cache_desc_info ucache_info = {
|
||||
.type = "Unified",
|
||||
.size_prop = "d-cache-size",
|
||||
.line_size_prop = "d-cache-line-size",
|
||||
.nr_sets_prop = "d-cache-sets",
|
||||
};
|
||||
|
||||
static struct cache_desc_info dcache_info = {
|
||||
.type = "Data",
|
||||
.size_prop = "d-cache-size",
|
||||
.line_size_prop = "d-cache-line-size",
|
||||
.nr_sets_prop = "d-cache-sets",
|
||||
};
|
||||
|
||||
static struct cache_desc_info icache_info = {
|
||||
.type = "Instruction",
|
||||
.size_prop = "i-cache-size",
|
||||
.line_size_prop = "i-cache-line-size",
|
||||
.nr_sets_prop = "i-cache-sets",
|
||||
};
|
||||
|
||||
static struct cache_desc * __cpuinit create_cache_desc(struct device_node *np, struct kobject *parent, int index, int level, struct cache_desc_info *info)
|
||||
{
|
||||
const u32 *cache_line_size;
|
||||
struct cache_desc *new;
|
||||
const u32 *cache_size;
|
||||
const u32 *nr_sets;
|
||||
int rc;
|
||||
|
||||
new = kzalloc(sizeof(*new), GFP_KERNEL);
|
||||
if (!new)
|
||||
return NULL;
|
||||
|
||||
rc = kobject_init_and_add(&new->kobj, &cache_desc_type, parent,
|
||||
"index%d", index);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
/* type */
|
||||
new->type = info->type;
|
||||
rc = sysfs_create_file(&new->kobj, &cache_type_attr.attr);
|
||||
WARN_ON(rc);
|
||||
|
||||
/* level */
|
||||
new->level = level;
|
||||
rc = sysfs_create_file(&new->kobj, &cache_level_attr.attr);
|
||||
WARN_ON(rc);
|
||||
|
||||
/* size */
|
||||
cache_size = of_get_property(np, info->size_prop, NULL);
|
||||
if (cache_size) {
|
||||
new->size = *cache_size / 1024;
|
||||
rc = sysfs_create_file(&new->kobj,
|
||||
&cache_size_attr.attr);
|
||||
WARN_ON(rc);
|
||||
}
|
||||
|
||||
/* coherency_line_size */
|
||||
cache_line_size = of_get_property(np, info->line_size_prop, NULL);
|
||||
if (cache_line_size) {
|
||||
new->line_size = *cache_line_size;
|
||||
rc = sysfs_create_file(&new->kobj,
|
||||
&cache_line_size_attr.attr);
|
||||
WARN_ON(rc);
|
||||
}
|
||||
|
||||
/* number_of_sets */
|
||||
nr_sets = of_get_property(np, info->nr_sets_prop, NULL);
|
||||
if (nr_sets) {
|
||||
new->nr_sets = *nr_sets;
|
||||
rc = sysfs_create_file(&new->kobj,
|
||||
&cache_nr_sets_attr.attr);
|
||||
WARN_ON(rc);
|
||||
}
|
||||
|
||||
/* ways_of_associativity */
|
||||
if (new->nr_sets == 1) {
|
||||
/* fully associative */
|
||||
new->associativity = 0;
|
||||
goto create_assoc;
|
||||
}
|
||||
|
||||
if (new->nr_sets && new->size && new->line_size) {
|
||||
/* If we have values for all of these we can derive
|
||||
* the associativity. */
|
||||
new->associativity =
|
||||
((new->size * 1024) / new->nr_sets) / new->line_size;
|
||||
create_assoc:
|
||||
rc = sysfs_create_file(&new->kobj,
|
||||
&cache_assoc_attr.attr);
|
||||
WARN_ON(rc);
|
||||
}
|
||||
|
||||
return new;
|
||||
err:
|
||||
kfree(new);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool cache_is_unified(struct device_node *np)
|
||||
{
|
||||
return of_get_property(np, "cache-unified", NULL);
|
||||
}
|
||||
|
||||
static struct cache_desc * __cpuinit create_cache_index_info(struct device_node *np, struct kobject *parent, int index, int level)
|
||||
{
|
||||
const phandle *next_cache_phandle;
|
||||
struct device_node *next_cache;
|
||||
struct cache_desc *new, **end;
|
||||
|
||||
pr_debug("%s(node = %s, index = %d)\n", __func__, np->full_name, index);
|
||||
|
||||
if (cache_is_unified(np)) {
|
||||
new = create_cache_desc(np, parent, index, level,
|
||||
&ucache_info);
|
||||
} else {
|
||||
new = create_cache_desc(np, parent, index, level,
|
||||
&dcache_info);
|
||||
if (new) {
|
||||
index++;
|
||||
new->next = create_cache_desc(np, parent, index, level,
|
||||
&icache_info);
|
||||
}
|
||||
}
|
||||
if (!new)
|
||||
return NULL;
|
||||
|
||||
end = &new->next;
|
||||
while (*end)
|
||||
end = &(*end)->next;
|
||||
|
||||
next_cache_phandle = of_get_property(np, "l2-cache", NULL);
|
||||
if (!next_cache_phandle)
|
||||
goto out;
|
||||
|
||||
next_cache = of_find_node_by_phandle(*next_cache_phandle);
|
||||
if (!next_cache)
|
||||
goto out;
|
||||
|
||||
*end = create_cache_index_info(next_cache, parent, ++index, ++level);
|
||||
|
||||
of_node_put(next_cache);
|
||||
out:
|
||||
return new;
|
||||
}
|
||||
|
||||
static void __cpuinit create_cache_info(struct sys_device *sysdev)
|
||||
{
|
||||
struct kobject *cache_toplevel;
|
||||
struct device_node *np = NULL;
|
||||
int cpu = sysdev->id;
|
||||
|
||||
cache_toplevel = kobject_create_and_add("cache", &sysdev->kobj);
|
||||
if (!cache_toplevel)
|
||||
return;
|
||||
per_cpu(cache_toplevel, cpu) = cache_toplevel;
|
||||
np = of_get_cpu_node(cpu, NULL);
|
||||
if (np != NULL) {
|
||||
per_cpu(cache_desc, cpu) =
|
||||
create_cache_index_info(np, cache_toplevel, 0, 1);
|
||||
of_node_put(np);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void __cpuinit register_cpu_online(unsigned int cpu)
|
||||
{
|
||||
struct cpu *c = &per_cpu(cpu_devices, cpu);
|
||||
struct sys_device *s = &c->sysdev;
|
||||
|
@ -346,9 +629,33 @@ static void register_cpu_online(unsigned int cpu)
|
|||
|
||||
if (cpu_has_feature(CPU_FTR_DSCR))
|
||||
sysdev_create_file(s, &attr_dscr);
|
||||
|
||||
create_cache_info(s);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
static void remove_cache_info(struct sys_device *sysdev)
|
||||
{
|
||||
struct kobject *cache_toplevel;
|
||||
struct cache_desc *cache_desc;
|
||||
int cpu = sysdev->id;
|
||||
|
||||
cache_desc = per_cpu(cache_desc, cpu);
|
||||
if (cache_desc != NULL) {
|
||||
sysfs_remove_file(&cache_desc->kobj, &cache_size_attr.attr);
|
||||
sysfs_remove_file(&cache_desc->kobj, &cache_line_size_attr.attr);
|
||||
sysfs_remove_file(&cache_desc->kobj, &cache_type_attr.attr);
|
||||
sysfs_remove_file(&cache_desc->kobj, &cache_level_attr.attr);
|
||||
sysfs_remove_file(&cache_desc->kobj, &cache_nr_sets_attr.attr);
|
||||
sysfs_remove_file(&cache_desc->kobj, &cache_assoc_attr.attr);
|
||||
|
||||
kobject_put(&cache_desc->kobj);
|
||||
}
|
||||
cache_toplevel = per_cpu(cache_toplevel, cpu);
|
||||
if (cache_toplevel != NULL)
|
||||
kobject_put(cache_toplevel);
|
||||
}
|
||||
|
||||
static void unregister_cpu_online(unsigned int cpu)
|
||||
{
|
||||
struct cpu *c = &per_cpu(cpu_devices, cpu);
|
||||
|
@ -399,6 +706,8 @@ static void unregister_cpu_online(unsigned int cpu)
|
|||
|
||||
if (cpu_has_feature(CPU_FTR_DSCR))
|
||||
sysdev_remove_file(s, &attr_dscr);
|
||||
|
||||
remove_cache_info(s);
|
||||
}
|
||||
#endif /* CONFIG_HOTPLUG_CPU */
|
||||
|
||||
|
|
|
@ -530,7 +530,7 @@ static dma_addr_t vio_dma_iommu_map_single(struct device *dev, void *vaddr,
|
|||
}
|
||||
|
||||
ret = dma_iommu_ops.map_single(dev, vaddr, size, direction, attrs);
|
||||
if (unlikely(dma_mapping_error(ret))) {
|
||||
if (unlikely(dma_mapping_error(dev, ret))) {
|
||||
vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE));
|
||||
atomic_inc(&viodev->cmo.allocs_failed);
|
||||
}
|
||||
|
@ -1031,8 +1031,8 @@ void vio_cmo_set_dev_desired(struct vio_dev *viodev, size_t desired) {}
|
|||
static int vio_cmo_bus_probe(struct vio_dev *viodev) { return 0; }
|
||||
static void vio_cmo_bus_remove(struct vio_dev *viodev) {}
|
||||
static void vio_cmo_set_dma_ops(struct vio_dev *viodev) {}
|
||||
static void vio_cmo_bus_init() {}
|
||||
static void vio_cmo_sysfs_init() { }
|
||||
static void vio_cmo_bus_init(void) {}
|
||||
static void vio_cmo_sysfs_init(void) { }
|
||||
#endif /* CONFIG_PPC_SMLPAR */
|
||||
EXPORT_SYMBOL(vio_cmo_entitlement_update);
|
||||
EXPORT_SYMBOL(vio_cmo_set_dev_desired);
|
||||
|
|
|
@ -177,7 +177,8 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid,
|
|||
vcpu->arch.msr & MSR_PR);
|
||||
}
|
||||
|
||||
void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid)
|
||||
void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
|
||||
gva_t eend, u32 asid)
|
||||
{
|
||||
unsigned int pid = asid & 0xff;
|
||||
int i;
|
||||
|
@ -191,7 +192,7 @@ void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid)
|
|||
if (!get_tlb_v(stlbe))
|
||||
continue;
|
||||
|
||||
if (eaddr < get_tlb_eaddr(stlbe))
|
||||
if (eend < get_tlb_eaddr(stlbe))
|
||||
continue;
|
||||
|
||||
if (eaddr > get_tlb_end(stlbe))
|
||||
|
|
|
@ -137,7 +137,7 @@ static int kvmppc_emul_tlbwe(struct kvm_vcpu *vcpu, u32 inst)
|
|||
if (tlbe->word0 & PPC44x_TLB_VALID) {
|
||||
eaddr = get_tlb_eaddr(tlbe);
|
||||
asid = (tlbe->word0 & PPC44x_TLB_TS) | tlbe->tid;
|
||||
kvmppc_mmu_invalidate(vcpu, eaddr, asid);
|
||||
kvmppc_mmu_invalidate(vcpu, eaddr, get_tlb_end(tlbe), asid);
|
||||
}
|
||||
|
||||
switch (ws) {
|
||||
|
|
|
@ -736,14 +736,21 @@ static int __init hugetlbpage_init(void)
|
|||
|
||||
if (!cpu_has_feature(CPU_FTR_16M_PAGE))
|
||||
return -ENODEV;
|
||||
|
||||
/* Add supported huge page sizes. Need to change HUGE_MAX_HSTATE
|
||||
* and adjust PTE_NONCACHE_NUM if the number of supported huge page
|
||||
* sizes changes.
|
||||
*/
|
||||
set_huge_psize(MMU_PAGE_16M);
|
||||
set_huge_psize(MMU_PAGE_64K);
|
||||
set_huge_psize(MMU_PAGE_16G);
|
||||
|
||||
/* Temporarily disable support for 64K huge pages when 64K SPU local
|
||||
* store support is enabled as the current implementation conflicts.
|
||||
*/
|
||||
#ifndef CONFIG_SPU_FS_64K_LS
|
||||
set_huge_psize(MMU_PAGE_64K);
|
||||
#endif
|
||||
|
||||
for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
|
||||
if (mmu_huge_psizes[psize]) {
|
||||
huge_pgtable_cache(psize) = kmem_cache_create(
|
||||
|
|
|
@ -541,6 +541,78 @@ static int __init pmac_declare_of_platform_devices(void)
|
|||
}
|
||||
machine_device_initcall(powermac, pmac_declare_of_platform_devices);
|
||||
|
||||
#ifdef CONFIG_SERIAL_PMACZILOG_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.
|
||||
*/
|
||||
static int __init check_pmac_serial_console(void)
|
||||
{
|
||||
struct device_node *prom_stdout = NULL;
|
||||
int offset = 0;
|
||||
const char *name;
|
||||
#ifdef CONFIG_SERIAL_PMACZILOG_TTYS
|
||||
char *devname = "ttyS";
|
||||
#else
|
||||
char *devname = "ttyPZ";
|
||||
#endif
|
||||
|
||||
pr_debug(" -> check_pmac_serial_console()\n");
|
||||
|
||||
/* The user has requested a console so this is already set up. */
|
||||
if (strstr(boot_command_line, "console=")) {
|
||||
pr_debug(" console was specified !\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (!of_chosen) {
|
||||
pr_debug(" of_chosen is NULL !\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* We are getting a weird phandle from OF ... */
|
||||
/* ... So use the full path instead */
|
||||
name = of_get_property(of_chosen, "linux,stdout-path", NULL);
|
||||
if (name == NULL) {
|
||||
pr_debug(" no linux,stdout-path !\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
prom_stdout = of_find_node_by_path(name);
|
||||
if (!prom_stdout) {
|
||||
pr_debug(" can't find stdout package %s !\n", name);
|
||||
return -ENODEV;
|
||||
}
|
||||
pr_debug("stdout is %s\n", prom_stdout->full_name);
|
||||
|
||||
name = of_get_property(prom_stdout, "name", NULL);
|
||||
if (!name) {
|
||||
pr_debug(" stdout package has no name !\n");
|
||||
goto not_found;
|
||||
}
|
||||
|
||||
if (strcmp(name, "ch-a") == 0)
|
||||
offset = 0;
|
||||
else if (strcmp(name, "ch-b") == 0)
|
||||
offset = 1;
|
||||
else
|
||||
goto not_found;
|
||||
of_node_put(prom_stdout);
|
||||
|
||||
pr_debug("Found serial console at %s%d\n", devname, offset);
|
||||
|
||||
return add_preferred_console(devname, offset, NULL);
|
||||
|
||||
not_found:
|
||||
pr_debug("No preferred console found !\n");
|
||||
of_node_put(prom_stdout);
|
||||
return -ENODEV;
|
||||
}
|
||||
console_initcall(check_pmac_serial_console);
|
||||
|
||||
#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
|
||||
|
||||
/*
|
||||
* Called very early, MMU is off, device-tree isn't unflattened
|
||||
*/
|
||||
|
|
|
@ -125,13 +125,23 @@ void udbg_scc_init(int force_scc)
|
|||
out_8(sccc, 0xc0);
|
||||
|
||||
/* If SCC was the OF output port, read the BRG value, else
|
||||
* Setup for 57600 8N1
|
||||
* Setup for 38400 or 57600 8N1 depending on the machine
|
||||
*/
|
||||
if (ch_def != NULL) {
|
||||
out_8(sccc, 13);
|
||||
scc_inittab[1] = in_8(sccc);
|
||||
out_8(sccc, 12);
|
||||
scc_inittab[3] = in_8(sccc);
|
||||
} else if (machine_is_compatible("RackMac1,1")
|
||||
|| machine_is_compatible("RackMac1,2")
|
||||
|| machine_is_compatible("MacRISC4")) {
|
||||
/* Xserves and G5s default to 57600 */
|
||||
scc_inittab[1] = 0;
|
||||
scc_inittab[3] = 0;
|
||||
} else {
|
||||
/* Others default to 38400 */
|
||||
scc_inittab[1] = 0;
|
||||
scc_inittab[3] = 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(scc_inittab); ++i)
|
||||
|
|
|
@ -289,7 +289,9 @@ static int cmm_thread(void *dummy)
|
|||
}
|
||||
|
||||
#define CMM_SHOW(name, format, args...) \
|
||||
static ssize_t show_##name(struct sys_device *dev, char *buf) \
|
||||
static ssize_t show_##name(struct sys_device *dev, \
|
||||
struct sysdev_attribute *attr, \
|
||||
char *buf) \
|
||||
{ \
|
||||
return sprintf(buf, format, ##args); \
|
||||
} \
|
||||
|
@ -298,12 +300,14 @@ static int cmm_thread(void *dummy)
|
|||
CMM_SHOW(loaned_kb, "%lu\n", PAGES2KB(loaned_pages));
|
||||
CMM_SHOW(loaned_target_kb, "%lu\n", PAGES2KB(loaned_pages_target));
|
||||
|
||||
static ssize_t show_oom_pages(struct sys_device *dev, char *buf)
|
||||
static ssize_t show_oom_pages(struct sys_device *dev,
|
||||
struct sysdev_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%lu\n", PAGES2KB(oom_freed_pages));
|
||||
}
|
||||
|
||||
static ssize_t store_oom_pages(struct sys_device *dev,
|
||||
struct sysdev_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long val = simple_strtoul (buf, NULL, 10);
|
||||
|
|
|
@ -197,7 +197,7 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
|
|||
args.new = BREAKPOINT_INSTRUCTION;
|
||||
|
||||
kcb->kprobe_status = KPROBE_SWAP_INST;
|
||||
stop_machine_run(swap_instruction, &args, NR_CPUS);
|
||||
stop_machine(swap_instruction, &args, NULL);
|
||||
kcb->kprobe_status = status;
|
||||
}
|
||||
|
||||
|
@ -212,7 +212,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
|
|||
args.new = p->opcode;
|
||||
|
||||
kcb->kprobe_status = KPROBE_SWAP_INST;
|
||||
stop_machine_run(swap_instruction, &args, NR_CPUS);
|
||||
stop_machine(swap_instruction, &args, NULL);
|
||||
kcb->kprobe_status = status;
|
||||
}
|
||||
|
||||
|
@ -331,7 +331,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
|||
* No kprobe at this address. The fault has not been
|
||||
* caused by a kprobe breakpoint. The race of breakpoint
|
||||
* vs. kprobe remove does not exist because on s390 we
|
||||
* use stop_machine_run to arm/disarm the breakpoints.
|
||||
* use stop_machine to arm/disarm the breakpoints.
|
||||
*/
|
||||
goto no_kprobe;
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
#include <asm/uaccess.h>
|
||||
|
||||
static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu,
|
||||
u64 guestaddr)
|
||||
unsigned long guestaddr)
|
||||
{
|
||||
u64 prefix = vcpu->arch.sie_block->prefix;
|
||||
u64 origin = vcpu->kvm->arch.guest_origin;
|
||||
u64 memsize = vcpu->kvm->arch.guest_memsize;
|
||||
unsigned long prefix = vcpu->arch.sie_block->prefix;
|
||||
unsigned long origin = vcpu->kvm->arch.guest_origin;
|
||||
unsigned long memsize = vcpu->kvm->arch.guest_memsize;
|
||||
|
||||
if (guestaddr < 2 * PAGE_SIZE)
|
||||
guestaddr += prefix;
|
||||
|
@ -37,7 +37,7 @@ static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu,
|
|||
return (void __user *) guestaddr;
|
||||
}
|
||||
|
||||
static inline int get_guest_u64(struct kvm_vcpu *vcpu, u64 guestaddr,
|
||||
static inline int get_guest_u64(struct kvm_vcpu *vcpu, unsigned long guestaddr,
|
||||
u64 *result)
|
||||
{
|
||||
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
|
||||
|
@ -47,10 +47,10 @@ static inline int get_guest_u64(struct kvm_vcpu *vcpu, u64 guestaddr,
|
|||
if (IS_ERR((void __force *) uptr))
|
||||
return PTR_ERR((void __force *) uptr);
|
||||
|
||||
return get_user(*result, (u64 __user *) uptr);
|
||||
return get_user(*result, (unsigned long __user *) uptr);
|
||||
}
|
||||
|
||||
static inline int get_guest_u32(struct kvm_vcpu *vcpu, u64 guestaddr,
|
||||
static inline int get_guest_u32(struct kvm_vcpu *vcpu, unsigned long guestaddr,
|
||||
u32 *result)
|
||||
{
|
||||
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
|
||||
|
@ -63,7 +63,7 @@ static inline int get_guest_u32(struct kvm_vcpu *vcpu, u64 guestaddr,
|
|||
return get_user(*result, (u32 __user *) uptr);
|
||||
}
|
||||
|
||||
static inline int get_guest_u16(struct kvm_vcpu *vcpu, u64 guestaddr,
|
||||
static inline int get_guest_u16(struct kvm_vcpu *vcpu, unsigned long guestaddr,
|
||||
u16 *result)
|
||||
{
|
||||
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
|
||||
|
@ -76,7 +76,7 @@ static inline int get_guest_u16(struct kvm_vcpu *vcpu, u64 guestaddr,
|
|||
return get_user(*result, (u16 __user *) uptr);
|
||||
}
|
||||
|
||||
static inline int get_guest_u8(struct kvm_vcpu *vcpu, u64 guestaddr,
|
||||
static inline int get_guest_u8(struct kvm_vcpu *vcpu, unsigned long guestaddr,
|
||||
u8 *result)
|
||||
{
|
||||
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
|
||||
|
@ -87,7 +87,7 @@ static inline int get_guest_u8(struct kvm_vcpu *vcpu, u64 guestaddr,
|
|||
return get_user(*result, (u8 __user *) uptr);
|
||||
}
|
||||
|
||||
static inline int put_guest_u64(struct kvm_vcpu *vcpu, u64 guestaddr,
|
||||
static inline int put_guest_u64(struct kvm_vcpu *vcpu, unsigned long guestaddr,
|
||||
u64 value)
|
||||
{
|
||||
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
|
||||
|
@ -100,7 +100,7 @@ static inline int put_guest_u64(struct kvm_vcpu *vcpu, u64 guestaddr,
|
|||
return put_user(value, (u64 __user *) uptr);
|
||||
}
|
||||
|
||||
static inline int put_guest_u32(struct kvm_vcpu *vcpu, u64 guestaddr,
|
||||
static inline int put_guest_u32(struct kvm_vcpu *vcpu, unsigned long guestaddr,
|
||||
u32 value)
|
||||
{
|
||||
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
|
||||
|
@ -113,7 +113,7 @@ static inline int put_guest_u32(struct kvm_vcpu *vcpu, u64 guestaddr,
|
|||
return put_user(value, (u32 __user *) uptr);
|
||||
}
|
||||
|
||||
static inline int put_guest_u16(struct kvm_vcpu *vcpu, u64 guestaddr,
|
||||
static inline int put_guest_u16(struct kvm_vcpu *vcpu, unsigned long guestaddr,
|
||||
u16 value)
|
||||
{
|
||||
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
|
||||
|
@ -126,7 +126,7 @@ static inline int put_guest_u16(struct kvm_vcpu *vcpu, u64 guestaddr,
|
|||
return put_user(value, (u16 __user *) uptr);
|
||||
}
|
||||
|
||||
static inline int put_guest_u8(struct kvm_vcpu *vcpu, u64 guestaddr,
|
||||
static inline int put_guest_u8(struct kvm_vcpu *vcpu, unsigned long guestaddr,
|
||||
u8 value)
|
||||
{
|
||||
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
|
||||
|
@ -138,7 +138,8 @@ static inline int put_guest_u8(struct kvm_vcpu *vcpu, u64 guestaddr,
|
|||
}
|
||||
|
||||
|
||||
static inline int __copy_to_guest_slow(struct kvm_vcpu *vcpu, u64 guestdest,
|
||||
static inline int __copy_to_guest_slow(struct kvm_vcpu *vcpu,
|
||||
unsigned long guestdest,
|
||||
const void *from, unsigned long n)
|
||||
{
|
||||
int rc;
|
||||
|
@ -153,12 +154,12 @@ static inline int __copy_to_guest_slow(struct kvm_vcpu *vcpu, u64 guestdest,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int copy_to_guest(struct kvm_vcpu *vcpu, u64 guestdest,
|
||||
static inline int copy_to_guest(struct kvm_vcpu *vcpu, unsigned long guestdest,
|
||||
const void *from, unsigned long n)
|
||||
{
|
||||
u64 prefix = vcpu->arch.sie_block->prefix;
|
||||
u64 origin = vcpu->kvm->arch.guest_origin;
|
||||
u64 memsize = vcpu->kvm->arch.guest_memsize;
|
||||
unsigned long prefix = vcpu->arch.sie_block->prefix;
|
||||
unsigned long origin = vcpu->kvm->arch.guest_origin;
|
||||
unsigned long memsize = vcpu->kvm->arch.guest_memsize;
|
||||
|
||||
if ((guestdest < 2 * PAGE_SIZE) && (guestdest + n > 2 * PAGE_SIZE))
|
||||
goto slowpath;
|
||||
|
@ -189,7 +190,8 @@ static inline int copy_to_guest(struct kvm_vcpu *vcpu, u64 guestdest,
|
|||
}
|
||||
|
||||
static inline int __copy_from_guest_slow(struct kvm_vcpu *vcpu, void *to,
|
||||
u64 guestsrc, unsigned long n)
|
||||
unsigned long guestsrc,
|
||||
unsigned long n)
|
||||
{
|
||||
int rc;
|
||||
unsigned long i;
|
||||
|
@ -204,11 +206,11 @@ static inline int __copy_from_guest_slow(struct kvm_vcpu *vcpu, void *to,
|
|||
}
|
||||
|
||||
static inline int copy_from_guest(struct kvm_vcpu *vcpu, void *to,
|
||||
u64 guestsrc, unsigned long n)
|
||||
unsigned long guestsrc, unsigned long n)
|
||||
{
|
||||
u64 prefix = vcpu->arch.sie_block->prefix;
|
||||
u64 origin = vcpu->kvm->arch.guest_origin;
|
||||
u64 memsize = vcpu->kvm->arch.guest_memsize;
|
||||
unsigned long prefix = vcpu->arch.sie_block->prefix;
|
||||
unsigned long origin = vcpu->kvm->arch.guest_origin;
|
||||
unsigned long memsize = vcpu->kvm->arch.guest_memsize;
|
||||
|
||||
if ((guestsrc < 2 * PAGE_SIZE) && (guestsrc + n > 2 * PAGE_SIZE))
|
||||
goto slowpath;
|
||||
|
@ -238,11 +240,12 @@ static inline int copy_from_guest(struct kvm_vcpu *vcpu, void *to,
|
|||
return __copy_from_guest_slow(vcpu, to, guestsrc, n);
|
||||
}
|
||||
|
||||
static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu, u64 guestdest,
|
||||
static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu,
|
||||
unsigned long guestdest,
|
||||
const void *from, unsigned long n)
|
||||
{
|
||||
u64 origin = vcpu->kvm->arch.guest_origin;
|
||||
u64 memsize = vcpu->kvm->arch.guest_memsize;
|
||||
unsigned long origin = vcpu->kvm->arch.guest_origin;
|
||||
unsigned long memsize = vcpu->kvm->arch.guest_memsize;
|
||||
|
||||
if (guestdest + n > memsize)
|
||||
return -EFAULT;
|
||||
|
@ -256,10 +259,11 @@ static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu, u64 guestdest,
|
|||
}
|
||||
|
||||
static inline int copy_from_guest_absolute(struct kvm_vcpu *vcpu, void *to,
|
||||
u64 guestsrc, unsigned long n)
|
||||
unsigned long guestsrc,
|
||||
unsigned long n)
|
||||
{
|
||||
u64 origin = vcpu->kvm->arch.guest_origin;
|
||||
u64 memsize = vcpu->kvm->arch.guest_memsize;
|
||||
unsigned long origin = vcpu->kvm->arch.guest_origin;
|
||||
unsigned long memsize = vcpu->kvm->arch.guest_memsize;
|
||||
|
||||
if (guestsrc + n > memsize)
|
||||
return -EFAULT;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "kvm-s390.h"
|
||||
#include "gaccess.h"
|
||||
|
||||
static int handle_lctg(struct kvm_vcpu *vcpu)
|
||||
static int handle_lctlg(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
|
||||
int reg3 = vcpu->arch.sie_block->ipa & 0x000f;
|
||||
|
@ -30,7 +30,7 @@ static int handle_lctg(struct kvm_vcpu *vcpu)
|
|||
u64 useraddr;
|
||||
int reg, rc;
|
||||
|
||||
vcpu->stat.instruction_lctg++;
|
||||
vcpu->stat.instruction_lctlg++;
|
||||
if ((vcpu->arch.sie_block->ipb & 0xff) != 0x2f)
|
||||
return -ENOTSUPP;
|
||||
|
||||
|
@ -38,9 +38,12 @@ static int handle_lctg(struct kvm_vcpu *vcpu)
|
|||
if (base2)
|
||||
useraddr += vcpu->arch.guest_gprs[base2];
|
||||
|
||||
if (useraddr & 7)
|
||||
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
|
||||
|
||||
reg = reg1;
|
||||
|
||||
VCPU_EVENT(vcpu, 5, "lctg r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2,
|
||||
VCPU_EVENT(vcpu, 5, "lctlg r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2,
|
||||
disp2);
|
||||
|
||||
do {
|
||||
|
@ -74,6 +77,9 @@ static int handle_lctl(struct kvm_vcpu *vcpu)
|
|||
if (base2)
|
||||
useraddr += vcpu->arch.guest_gprs[base2];
|
||||
|
||||
if (useraddr & 3)
|
||||
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
|
||||
|
||||
VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2,
|
||||
disp2);
|
||||
|
||||
|
@ -99,7 +105,7 @@ static intercept_handler_t instruction_handlers[256] = {
|
|||
[0xae] = kvm_s390_handle_sigp,
|
||||
[0xb2] = kvm_s390_handle_priv,
|
||||
[0xb7] = handle_lctl,
|
||||
[0xeb] = handle_lctg,
|
||||
[0xeb] = handle_lctlg,
|
||||
};
|
||||
|
||||
static int handle_noop(struct kvm_vcpu *vcpu)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <asm/lowcore.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/kvm_host.h>
|
||||
#include <linux/signal.h>
|
||||
#include "kvm-s390.h"
|
||||
#include "gaccess.h"
|
||||
|
||||
|
@ -246,15 +247,10 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
|
|||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
if (exception) {
|
||||
VCPU_EVENT(vcpu, 1, "%s", "program exception while delivering"
|
||||
" interrupt");
|
||||
kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
|
||||
if (inti->type == KVM_S390_PROGRAM_INT) {
|
||||
printk(KERN_WARNING "kvm: recursive program check\n");
|
||||
BUG();
|
||||
}
|
||||
printk("kvm: The guest lowcore is not mapped during interrupt "
|
||||
"delivery, killing userspace\n");
|
||||
do_exit(SIGKILL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,14 +273,11 @@ static int __try_deliver_ckc_interrupt(struct kvm_vcpu *vcpu)
|
|||
__LC_EXT_NEW_PSW, sizeof(psw_t));
|
||||
if (rc == -EFAULT)
|
||||
exception = 1;
|
||||
|
||||
if (exception) {
|
||||
VCPU_EVENT(vcpu, 1, "%s", "program exception while delivering" \
|
||||
" ckc interrupt");
|
||||
kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
|
||||
return 0;
|
||||
printk("kvm: The guest lowcore is not mapped during interrupt "
|
||||
"delivery, killing userspace\n");
|
||||
do_exit(SIGKILL);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue