You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge /spare/repo/linux-2.6/
This commit is contained in:
@@ -2423,8 +2423,7 @@ S: Toronto, Ontario
|
|||||||
S: Canada
|
S: Canada
|
||||||
|
|
||||||
N: Zwane Mwaikambo
|
N: Zwane Mwaikambo
|
||||||
E: zwane@linuxpower.ca
|
E: zwane@arm.linux.org.uk
|
||||||
W: http://function.linuxpower.ca
|
|
||||||
D: Various driver hacking
|
D: Various driver hacking
|
||||||
D: Lowlevel x86 kernel hacking
|
D: Lowlevel x86 kernel hacking
|
||||||
D: General debugging
|
D: General debugging
|
||||||
|
|||||||
@@ -0,0 +1,288 @@
|
|||||||
|
|
||||||
|
-------
|
||||||
|
PHY Abstraction Layer
|
||||||
|
(Updated 2005-07-21)
|
||||||
|
|
||||||
|
Purpose
|
||||||
|
|
||||||
|
Most network devices consist of set of registers which provide an interface
|
||||||
|
to a MAC layer, which communicates with the physical connection through a
|
||||||
|
PHY. The PHY concerns itself with negotiating link parameters with the link
|
||||||
|
partner on the other side of the network connection (typically, an ethernet
|
||||||
|
cable), and provides a register interface to allow drivers to determine what
|
||||||
|
settings were chosen, and to configure what settings are allowed.
|
||||||
|
|
||||||
|
While these devices are distinct from the network devices, and conform to a
|
||||||
|
standard layout for the registers, it has been common practice to integrate
|
||||||
|
the PHY management code with the network driver. This has resulted in large
|
||||||
|
amounts of redundant code. Also, on embedded systems with multiple (and
|
||||||
|
sometimes quite different) ethernet controllers connected to the same
|
||||||
|
management bus, it is difficult to ensure safe use of the bus.
|
||||||
|
|
||||||
|
Since the PHYs are devices, and the management busses through which they are
|
||||||
|
accessed are, in fact, busses, the PHY Abstraction Layer treats them as such.
|
||||||
|
In doing so, it has these goals:
|
||||||
|
|
||||||
|
1) Increase code-reuse
|
||||||
|
2) Increase overall code-maintainability
|
||||||
|
3) Speed development time for new network drivers, and for new systems
|
||||||
|
|
||||||
|
Basically, this layer is meant to provide an interface to PHY devices which
|
||||||
|
allows network driver writers to write as little code as possible, while
|
||||||
|
still providing a full feature set.
|
||||||
|
|
||||||
|
The MDIO bus
|
||||||
|
|
||||||
|
Most network devices are connected to a PHY by means of a management bus.
|
||||||
|
Different devices use different busses (though some share common interfaces).
|
||||||
|
In order to take advantage of the PAL, each bus interface needs to be
|
||||||
|
registered as a distinct device.
|
||||||
|
|
||||||
|
1) read and write functions must be implemented. Their prototypes are:
|
||||||
|
|
||||||
|
int write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
|
||||||
|
int read(struct mii_bus *bus, int mii_id, int regnum);
|
||||||
|
|
||||||
|
mii_id is the address on the bus for the PHY, and regnum is the register
|
||||||
|
number. These functions are guaranteed not to be called from interrupt
|
||||||
|
time, so it is safe for them to block, waiting for an interrupt to signal
|
||||||
|
the operation is complete
|
||||||
|
|
||||||
|
2) A reset function is necessary. This is used to return the bus to an
|
||||||
|
initialized state.
|
||||||
|
|
||||||
|
3) A probe function is needed. This function should set up anything the bus
|
||||||
|
driver needs, setup the mii_bus structure, and register with the PAL using
|
||||||
|
mdiobus_register. Similarly, there's a remove function to undo all of
|
||||||
|
that (use mdiobus_unregister).
|
||||||
|
|
||||||
|
4) Like any driver, the device_driver structure must be configured, and init
|
||||||
|
exit functions are used to register the driver.
|
||||||
|
|
||||||
|
5) The bus must also be declared somewhere as a device, and registered.
|
||||||
|
|
||||||
|
As an example for how one driver implemented an mdio bus driver, see
|
||||||
|
drivers/net/gianfar_mii.c and arch/ppc/syslib/mpc85xx_devices.c
|
||||||
|
|
||||||
|
Connecting to a PHY
|
||||||
|
|
||||||
|
Sometime during startup, the network driver needs to establish a connection
|
||||||
|
between the PHY device, and the network device. At this time, the PHY's bus
|
||||||
|
and drivers need to all have been loaded, so it is ready for the connection.
|
||||||
|
At this point, there are several ways to connect to the PHY:
|
||||||
|
|
||||||
|
1) The PAL handles everything, and only calls the network driver when
|
||||||
|
the link state changes, so it can react.
|
||||||
|
|
||||||
|
2) The PAL handles everything except interrupts (usually because the
|
||||||
|
controller has the interrupt registers).
|
||||||
|
|
||||||
|
3) The PAL handles everything, but checks in with the driver every second,
|
||||||
|
allowing the network driver to react first to any changes before the PAL
|
||||||
|
does.
|
||||||
|
|
||||||
|
4) The PAL serves only as a library of functions, with the network device
|
||||||
|
manually calling functions to update status, and configure the PHY
|
||||||
|
|
||||||
|
|
||||||
|
Letting the PHY Abstraction Layer do Everything
|
||||||
|
|
||||||
|
If you choose option 1 (The hope is that every driver can, but to still be
|
||||||
|
useful to drivers that can't), connecting to the PHY is simple:
|
||||||
|
|
||||||
|
First, you need a function to react to changes in the link state. This
|
||||||
|
function follows this protocol:
|
||||||
|
|
||||||
|
static void adjust_link(struct net_device *dev);
|
||||||
|
|
||||||
|
Next, you need to know the device name of the PHY connected to this device.
|
||||||
|
The name will look something like, "phy0:0", where the first number is the
|
||||||
|
bus id, and the second is the PHY's address on that bus.
|
||||||
|
|
||||||
|
Now, to connect, just call this function:
|
||||||
|
|
||||||
|
phydev = phy_connect(dev, phy_name, &adjust_link, flags);
|
||||||
|
|
||||||
|
phydev is a pointer to the phy_device structure which represents the PHY. If
|
||||||
|
phy_connect is successful, it will return the pointer. dev, here, is the
|
||||||
|
pointer to your net_device. Once done, this function will have started the
|
||||||
|
PHY's software state machine, and registered for the PHY's interrupt, if it
|
||||||
|
has one. The phydev structure will be populated with information about the
|
||||||
|
current state, though the PHY will not yet be truly operational at this
|
||||||
|
point.
|
||||||
|
|
||||||
|
flags is a u32 which can optionally contain phy-specific flags.
|
||||||
|
This is useful if the system has put hardware restrictions on
|
||||||
|
the PHY/controller, of which the PHY needs to be aware.
|
||||||
|
|
||||||
|
Now just make sure that phydev->supported and phydev->advertising have any
|
||||||
|
values pruned from them which don't make sense for your controller (a 10/100
|
||||||
|
controller may be connected to a gigabit capable PHY, so you would need to
|
||||||
|
mask off SUPPORTED_1000baseT*). See include/linux/ethtool.h for definitions
|
||||||
|
for these bitfields. Note that you should not SET any bits, or the PHY may
|
||||||
|
get put into an unsupported state.
|
||||||
|
|
||||||
|
Lastly, once the controller is ready to handle network traffic, you call
|
||||||
|
phy_start(phydev). This tells the PAL that you are ready, and configures the
|
||||||
|
PHY to connect to the network. If you want to handle your own interrupts,
|
||||||
|
just set phydev->irq to PHY_IGNORE_INTERRUPT before you call phy_start.
|
||||||
|
Similarly, if you don't want to use interrupts, set phydev->irq to PHY_POLL.
|
||||||
|
|
||||||
|
When you want to disconnect from the network (even if just briefly), you call
|
||||||
|
phy_stop(phydev).
|
||||||
|
|
||||||
|
Keeping Close Tabs on the PAL
|
||||||
|
|
||||||
|
It is possible that the PAL's built-in state machine needs a little help to
|
||||||
|
keep your network device and the PHY properly in sync. If so, you can
|
||||||
|
register a helper function when connecting to the PHY, which will be called
|
||||||
|
every second before the state machine reacts to any changes. To do this, you
|
||||||
|
need to manually call phy_attach() and phy_prepare_link(), and then call
|
||||||
|
phy_start_machine() with the second argument set to point to your special
|
||||||
|
handler.
|
||||||
|
|
||||||
|
Currently there are no examples of how to use this functionality, and testing
|
||||||
|
on it has been limited because the author does not have any drivers which use
|
||||||
|
it (they all use option 1). So Caveat Emptor.
|
||||||
|
|
||||||
|
Doing it all yourself
|
||||||
|
|
||||||
|
There's a remote chance that the PAL's built-in state machine cannot track
|
||||||
|
the complex interactions between the PHY and your network device. If this is
|
||||||
|
so, you can simply call phy_attach(), and not call phy_start_machine or
|
||||||
|
phy_prepare_link(). This will mean that phydev->state is entirely yours to
|
||||||
|
handle (phy_start and phy_stop toggle between some of the states, so you
|
||||||
|
might need to avoid them).
|
||||||
|
|
||||||
|
An effort has been made to make sure that useful functionality can be
|
||||||
|
accessed without the state-machine running, and most of these functions are
|
||||||
|
descended from functions which did not interact with a complex state-machine.
|
||||||
|
However, again, no effort has been made so far to test running without the
|
||||||
|
state machine, so tryer beware.
|
||||||
|
|
||||||
|
Here is a brief rundown of the functions:
|
||||||
|
|
||||||
|
int phy_read(struct phy_device *phydev, u16 regnum);
|
||||||
|
int phy_write(struct phy_device *phydev, u16 regnum, u16 val);
|
||||||
|
|
||||||
|
Simple read/write primitives. They invoke the bus's read/write function
|
||||||
|
pointers.
|
||||||
|
|
||||||
|
void phy_print_status(struct phy_device *phydev);
|
||||||
|
|
||||||
|
A convenience function to print out the PHY status neatly.
|
||||||
|
|
||||||
|
int phy_clear_interrupt(struct phy_device *phydev);
|
||||||
|
int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
|
||||||
|
|
||||||
|
Clear the PHY's interrupt, and configure which ones are allowed,
|
||||||
|
respectively. Currently only supports all on, or all off.
|
||||||
|
|
||||||
|
int phy_enable_interrupts(struct phy_device *phydev);
|
||||||
|
int phy_disable_interrupts(struct phy_device *phydev);
|
||||||
|
|
||||||
|
Functions which enable/disable PHY interrupts, clearing them
|
||||||
|
before and after, respectively.
|
||||||
|
|
||||||
|
int phy_start_interrupts(struct phy_device *phydev);
|
||||||
|
int phy_stop_interrupts(struct phy_device *phydev);
|
||||||
|
|
||||||
|
Requests the IRQ for the PHY interrupts, then enables them for
|
||||||
|
start, or disables then frees them for stop.
|
||||||
|
|
||||||
|
struct phy_device * phy_attach(struct net_device *dev, const char *phy_id,
|
||||||
|
u32 flags);
|
||||||
|
|
||||||
|
Attaches a network device to a particular PHY, binding the PHY to a generic
|
||||||
|
driver if none was found during bus initialization. Passes in
|
||||||
|
any phy-specific flags as needed.
|
||||||
|
|
||||||
|
int phy_start_aneg(struct phy_device *phydev);
|
||||||
|
|
||||||
|
Using variables inside the phydev structure, either configures advertising
|
||||||
|
and resets autonegotiation, or disables autonegotiation, and configures
|
||||||
|
forced settings.
|
||||||
|
|
||||||
|
static inline int phy_read_status(struct phy_device *phydev);
|
||||||
|
|
||||||
|
Fills the phydev structure with up-to-date information about the current
|
||||||
|
settings in the PHY.
|
||||||
|
|
||||||
|
void phy_sanitize_settings(struct phy_device *phydev)
|
||||||
|
|
||||||
|
Resolves differences between currently desired settings, and
|
||||||
|
supported settings for the given PHY device. Does not make
|
||||||
|
the changes in the hardware, though.
|
||||||
|
|
||||||
|
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
|
||||||
|
int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
|
||||||
|
|
||||||
|
Ethtool convenience functions.
|
||||||
|
|
||||||
|
int phy_mii_ioctl(struct phy_device *phydev,
|
||||||
|
struct mii_ioctl_data *mii_data, int cmd);
|
||||||
|
|
||||||
|
The MII ioctl. Note that this function will completely screw up the state
|
||||||
|
machine if you write registers like BMCR, BMSR, ADVERTISE, etc. Best to
|
||||||
|
use this only to write registers which are not standard, and don't set off
|
||||||
|
a renegotiation.
|
||||||
|
|
||||||
|
|
||||||
|
PHY Device Drivers
|
||||||
|
|
||||||
|
With the PHY Abstraction Layer, adding support for new PHYs is
|
||||||
|
quite easy. In some cases, no work is required at all! However,
|
||||||
|
many PHYs require a little hand-holding to get up-and-running.
|
||||||
|
|
||||||
|
Generic PHY driver
|
||||||
|
|
||||||
|
If the desired PHY doesn't have any errata, quirks, or special
|
||||||
|
features you want to support, then it may be best to not add
|
||||||
|
support, and let the PHY Abstraction Layer's Generic PHY Driver
|
||||||
|
do all of the work.
|
||||||
|
|
||||||
|
Writing a PHY driver
|
||||||
|
|
||||||
|
If you do need to write a PHY driver, the first thing to do is
|
||||||
|
make sure it can be matched with an appropriate PHY device.
|
||||||
|
This is done during bus initialization by reading the device's
|
||||||
|
UID (stored in registers 2 and 3), then comparing it to each
|
||||||
|
driver's phy_id field by ANDing it with each driver's
|
||||||
|
phy_id_mask field. Also, it needs a name. Here's an example:
|
||||||
|
|
||||||
|
static struct phy_driver dm9161_driver = {
|
||||||
|
.phy_id = 0x0181b880,
|
||||||
|
.name = "Davicom DM9161E",
|
||||||
|
.phy_id_mask = 0x0ffffff0,
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
Next, you need to specify what features (speed, duplex, autoneg,
|
||||||
|
etc) your PHY device and driver support. Most PHYs support
|
||||||
|
PHY_BASIC_FEATURES, but you can look in include/mii.h for other
|
||||||
|
features.
|
||||||
|
|
||||||
|
Each driver consists of a number of function pointers:
|
||||||
|
|
||||||
|
config_init: configures PHY into a sane state after a reset.
|
||||||
|
For instance, a Davicom PHY requires descrambling disabled.
|
||||||
|
probe: Does any setup needed by the driver
|
||||||
|
suspend/resume: power management
|
||||||
|
config_aneg: Changes the speed/duplex/negotiation settings
|
||||||
|
read_status: Reads the current speed/duplex/negotiation settings
|
||||||
|
ack_interrupt: Clear a pending interrupt
|
||||||
|
config_intr: Enable or disable interrupts
|
||||||
|
remove: Does any driver take-down
|
||||||
|
|
||||||
|
Of these, only config_aneg and read_status are required to be
|
||||||
|
assigned by the driver code. The rest are optional. Also, it is
|
||||||
|
preferred to use the generic phy driver's versions of these two
|
||||||
|
functions if at all possible: genphy_read_status and
|
||||||
|
genphy_config_aneg. If this is not possible, it is likely that
|
||||||
|
you only need to perform some actions before and after invoking
|
||||||
|
these functions, and so your functions will wrap the generic
|
||||||
|
ones.
|
||||||
|
|
||||||
|
Feel free to look at the Marvell, Cicada, and Davicom drivers in
|
||||||
|
drivers/net/phy/ for examples (the lxt and qsemi drivers have
|
||||||
|
not been tested as of this writing)
|
||||||
+2
-2
@@ -1739,7 +1739,7 @@ S: Maintained
|
|||||||
|
|
||||||
OPL3-SA2, SA3, and SAx DRIVER
|
OPL3-SA2, SA3, and SAx DRIVER
|
||||||
P: Zwane Mwaikambo
|
P: Zwane Mwaikambo
|
||||||
M: zwane@commfireservices.com
|
M: zwane@arm.linux.org.uk
|
||||||
L: linux-sound@vger.kernel.org
|
L: linux-sound@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
@@ -1995,7 +1995,7 @@ S: Maintained
|
|||||||
|
|
||||||
SC1200 WDT DRIVER
|
SC1200 WDT DRIVER
|
||||||
P: Zwane Mwaikambo
|
P: Zwane Mwaikambo
|
||||||
M: zwane@commfireservices.com
|
M: zwane@arm.linux.org.uk
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
SCHEDULER
|
SCHEDULER
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
VERSION = 2
|
VERSION = 2
|
||||||
PATCHLEVEL = 6
|
PATCHLEVEL = 6
|
||||||
SUBLEVEL = 13
|
SUBLEVEL = 13
|
||||||
EXTRAVERSION =-rc6
|
EXTRAVERSION =
|
||||||
NAME=Woozy Numbat
|
NAME=Affluent Albatross
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
# To see a list of typical targets execute "make help"
|
# To see a list of typical targets execute "make help"
|
||||||
|
|||||||
+1
-1
@@ -522,7 +522,7 @@ source "mm/Kconfig"
|
|||||||
|
|
||||||
config NUMA
|
config NUMA
|
||||||
bool "NUMA Support (EXPERIMENTAL)"
|
bool "NUMA Support (EXPERIMENTAL)"
|
||||||
depends on DISCONTIGMEM
|
depends on DISCONTIGMEM && BROKEN
|
||||||
help
|
help
|
||||||
Say Y to compile the kernel to support NUMA (Non-Uniform Memory
|
Say Y to compile the kernel to support NUMA (Non-Uniform Memory
|
||||||
Access). This option is for configuring high-end multiprocessor
|
Access). This option is for configuring high-end multiprocessor
|
||||||
|
|||||||
@@ -566,13 +566,12 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||||||
if (ka->sa.sa_flags & SA_RESETHAND)
|
if (ka->sa.sa_flags & SA_RESETHAND)
|
||||||
ka->sa.sa_handler = SIG_DFL;
|
ka->sa.sa_handler = SIG_DFL;
|
||||||
|
|
||||||
if (!(ka->sa.sa_flags & SA_NODEFER)) {
|
spin_lock_irq(¤t->sighand->siglock);
|
||||||
spin_lock_irq(¤t->sighand->siglock);
|
sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
|
||||||
sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
|
if (!(ka->sa.sa_flags & SA_NODEFER))
|
||||||
sigaddset(¤t->blocked,sig);
|
sigaddset(¤t->blocked,sig);
|
||||||
recalc_sigpending();
|
recalc_sigpending();
|
||||||
spin_unlock_irq(¤t->sighand->siglock);
|
spin_unlock_irq(¤t->sighand->siglock);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|||||||
@@ -1036,7 +1036,7 @@ debug_spin_lock(spinlock_t * lock, const char *base_file, int line_no)
|
|||||||
" br 1b\n"
|
" br 1b\n"
|
||||||
".previous"
|
".previous"
|
||||||
: "=r" (tmp), "=m" (lock->lock), "=r" (stuck)
|
: "=r" (tmp), "=m" (lock->lock), "=r" (stuck)
|
||||||
: "1" (lock->lock), "2" (stuck) : "memory");
|
: "m" (lock->lock), "2" (stuck) : "memory");
|
||||||
|
|
||||||
if (stuck < 0) {
|
if (stuck < 0) {
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
@@ -1115,7 +1115,7 @@ void _raw_write_lock(rwlock_t * lock)
|
|||||||
".previous"
|
".previous"
|
||||||
: "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (regy),
|
: "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (regy),
|
||||||
"=&r" (stuck_lock), "=&r" (stuck_reader)
|
"=&r" (stuck_lock), "=&r" (stuck_reader)
|
||||||
: "0" (*(volatile int *)lock), "3" (stuck_lock), "4" (stuck_reader) : "memory");
|
: "m" (*(volatile int *)lock), "3" (stuck_lock), "4" (stuck_reader) : "memory");
|
||||||
|
|
||||||
if (stuck_lock < 0) {
|
if (stuck_lock < 0) {
|
||||||
printk(KERN_WARNING "write_lock stuck at %p\n", inline_pc);
|
printk(KERN_WARNING "write_lock stuck at %p\n", inline_pc);
|
||||||
@@ -1153,7 +1153,7 @@ void _raw_read_lock(rwlock_t * lock)
|
|||||||
" br 1b\n"
|
" br 1b\n"
|
||||||
".previous"
|
".previous"
|
||||||
: "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (stuck_lock)
|
: "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (stuck_lock)
|
||||||
: "0" (*(volatile int *)lock), "2" (stuck_lock) : "memory");
|
: "m" (*(volatile int *)lock), "2" (stuck_lock) : "memory");
|
||||||
|
|
||||||
if (stuck_lock < 0) {
|
if (stuck_lock < 0) {
|
||||||
printk(KERN_WARNING "read_lock stuck at %p\n", inline_pc);
|
printk(KERN_WARNING "read_lock stuck at %p\n", inline_pc);
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ op_axp_setup(void)
|
|||||||
model->reg_setup(®, ctr, &sys);
|
model->reg_setup(®, ctr, &sys);
|
||||||
|
|
||||||
/* Configure the registers on all cpus. */
|
/* Configure the registers on all cpus. */
|
||||||
smp_call_function(model->cpu_setup, ®, 0, 1);
|
(void)smp_call_function(model->cpu_setup, ®, 0, 1);
|
||||||
model->cpu_setup(®);
|
model->cpu_setup(®);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ op_axp_cpu_start(void *dummy)
|
|||||||
static int
|
static int
|
||||||
op_axp_start(void)
|
op_axp_start(void)
|
||||||
{
|
{
|
||||||
smp_call_function(op_axp_cpu_start, NULL, 0, 1);
|
(void)smp_call_function(op_axp_cpu_start, NULL, 0, 1);
|
||||||
op_axp_cpu_start(NULL);
|
op_axp_cpu_start(NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ op_axp_cpu_stop(void *dummy)
|
|||||||
static void
|
static void
|
||||||
op_axp_stop(void)
|
op_axp_stop(void)
|
||||||
{
|
{
|
||||||
smp_call_function(op_axp_cpu_stop, NULL, 0, 1);
|
(void)smp_call_function(op_axp_cpu_stop, NULL, 0, 1);
|
||||||
op_axp_cpu_stop(NULL);
|
op_axp_cpu_stop(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-38
@@ -310,7 +310,7 @@ menu "Kernel Features"
|
|||||||
|
|
||||||
config SMP
|
config SMP
|
||||||
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
|
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
|
||||||
depends on EXPERIMENTAL #&& n
|
depends on EXPERIMENTAL && BROKEN #&& n
|
||||||
help
|
help
|
||||||
This enables support for systems with more than one CPU. If you have
|
This enables support for systems with more than one CPU. If you have
|
||||||
a system with only one CPU, like most personal computers, say N. If
|
a system with only one CPU, like most personal computers, say N. If
|
||||||
@@ -635,10 +635,6 @@ config PM
|
|||||||
and the Battery Powered Linux mini-HOWTO, available from
|
and the Battery Powered Linux mini-HOWTO, available from
|
||||||
<http://www.tldp.org/docs.html#howto>.
|
<http://www.tldp.org/docs.html#howto>.
|
||||||
|
|
||||||
Note that, even if you say N here, Linux on the x86 architecture
|
|
||||||
will issue the hlt instruction if nothing is to be done, thereby
|
|
||||||
sending the processor to sleep and saving power.
|
|
||||||
|
|
||||||
config APM
|
config APM
|
||||||
tristate "Advanced Power Management Emulation"
|
tristate "Advanced Power Management Emulation"
|
||||||
depends on PM
|
depends on PM
|
||||||
@@ -650,12 +646,6 @@ config APM
|
|||||||
battery status information, and user-space programs will receive
|
battery status information, and user-space programs will receive
|
||||||
notification of APM "events" (e.g. battery status change).
|
notification of APM "events" (e.g. battery status change).
|
||||||
|
|
||||||
If you select "Y" here, you can disable actual use of the APM
|
|
||||||
BIOS by passing the "apm=off" option to the kernel at boot time.
|
|
||||||
|
|
||||||
Note that the APM support is almost completely disabled for
|
|
||||||
machines with more than one CPU.
|
|
||||||
|
|
||||||
In order to use APM, you will need supporting software. For location
|
In order to use APM, you will need supporting software. For location
|
||||||
and more information, read <file:Documentation/pm.txt> and the
|
and more information, read <file:Documentation/pm.txt> and the
|
||||||
Battery Powered Linux mini-HOWTO, available from
|
Battery Powered Linux mini-HOWTO, available from
|
||||||
@@ -665,39 +655,12 @@ config APM
|
|||||||
manpage ("man 8 hdparm") for that), and it doesn't turn off
|
manpage ("man 8 hdparm") for that), and it doesn't turn off
|
||||||
VESA-compliant "green" monitors.
|
VESA-compliant "green" monitors.
|
||||||
|
|
||||||
This driver does not support the TI 4000M TravelMate and the ACER
|
|
||||||
486/DX4/75 because they don't have compliant BIOSes. Many "green"
|
|
||||||
desktop machines also don't have compliant BIOSes, and this driver
|
|
||||||
may cause those machines to panic during the boot phase.
|
|
||||||
|
|
||||||
Generally, if you don't have a battery in your machine, there isn't
|
Generally, if you don't have a battery in your machine, there isn't
|
||||||
much point in using this driver and you should say N. If you get
|
much point in using this driver and you should say N. If you get
|
||||||
random kernel OOPSes or reboots that don't seem to be related to
|
random kernel OOPSes or reboots that don't seem to be related to
|
||||||
anything, try disabling/enabling this option (or disabling/enabling
|
anything, try disabling/enabling this option (or disabling/enabling
|
||||||
APM in your BIOS).
|
APM in your BIOS).
|
||||||
|
|
||||||
Some other things you should try when experiencing seemingly random,
|
|
||||||
"weird" problems:
|
|
||||||
|
|
||||||
1) make sure that you have enough swap space and that it is
|
|
||||||
enabled.
|
|
||||||
2) pass the "no-hlt" option to the kernel
|
|
||||||
3) switch on floating point emulation in the kernel and pass
|
|
||||||
the "no387" option to the kernel
|
|
||||||
4) pass the "floppy=nodma" option to the kernel
|
|
||||||
5) pass the "mem=4M" option to the kernel (thereby disabling
|
|
||||||
all but the first 4 MB of RAM)
|
|
||||||
6) make sure that the CPU is not over clocked.
|
|
||||||
7) read the sig11 FAQ at <http://www.bitwizard.nl/sig11/>
|
|
||||||
8) disable the cache from your BIOS settings
|
|
||||||
9) install a fan for the video card or exchange video RAM
|
|
||||||
10) install a better fan for the CPU
|
|
||||||
11) exchange RAM chips
|
|
||||||
12) exchange the motherboard.
|
|
||||||
|
|
||||||
To compile this driver as a module, choose M here: the
|
|
||||||
module will be called apm.
|
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
source "net/Kconfig"
|
source "net/Kconfig"
|
||||||
@@ -752,6 +715,8 @@ source "drivers/hwmon/Kconfig"
|
|||||||
|
|
||||||
source "drivers/misc/Kconfig"
|
source "drivers/misc/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/mfd/Kconfig"
|
||||||
|
|
||||||
source "drivers/media/Kconfig"
|
source "drivers/media/Kconfig"
|
||||||
|
|
||||||
source "drivers/video/Kconfig"
|
source "drivers/video/Kconfig"
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
config ICST525
|
config ICST525
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config ARM_GIC
|
||||||
|
bool
|
||||||
|
|
||||||
config ICST307
|
config ICST307
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
obj-y += rtctime.o
|
obj-y += rtctime.o
|
||||||
obj-$(CONFIG_ARM_AMBA) += amba.o
|
obj-$(CONFIG_ARM_AMBA) += amba.o
|
||||||
|
obj-$(CONFIG_ARM_GIC) += gic.o
|
||||||
obj-$(CONFIG_ICST525) += icst525.o
|
obj-$(CONFIG_ICST525) += icst525.o
|
||||||
obj-$(CONFIG_ICST307) += icst307.o
|
obj-$(CONFIG_ICST307) += icst307.o
|
||||||
obj-$(CONFIG_SA1111) += sa1111.o
|
obj-$(CONFIG_SA1111) += sa1111.o
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
* linux/arch/arm/common/gic.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2002 ARM Limited, All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Interrupt architecture for the GIC:
|
||||||
|
*
|
||||||
|
* o There is one Interrupt Distributor, which receives interrupts
|
||||||
|
* from system devices and sends them to the Interrupt Controllers.
|
||||||
|
*
|
||||||
|
* o There is one CPU Interface per CPU, which sends interrupts sent
|
||||||
|
* by the Distributor, and interrupts generated locally, to the
|
||||||
|
* associated CPU.
|
||||||
|
*
|
||||||
|
* Note that IRQs 0-31 are special - they are local to each CPU.
|
||||||
|
* As such, the enable set/clear, pending set/clear and active bit
|
||||||
|
* registers are banked per-cpu for these sources.
|
||||||
|
*/
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
#include <linux/smp.h>
|
||||||
|
|
||||||
|
#include <asm/irq.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <asm/mach/irq.h>
|
||||||
|
#include <asm/hardware/gic.h>
|
||||||
|
|
||||||
|
static void __iomem *gic_dist_base;
|
||||||
|
static void __iomem *gic_cpu_base;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Routines to acknowledge, disable and enable interrupts
|
||||||
|
*
|
||||||
|
* Linux assumes that when we're done with an interrupt we need to
|
||||||
|
* unmask it, in the same way we need to unmask an interrupt when
|
||||||
|
* we first enable it.
|
||||||
|
*
|
||||||
|
* The GIC has a seperate notion of "end of interrupt" to re-enable
|
||||||
|
* an interrupt after handling, in order to support hardware
|
||||||
|
* prioritisation.
|
||||||
|
*
|
||||||
|
* We can make the GIC behave in the way that Linux expects by making
|
||||||
|
* our "acknowledge" routine disable the interrupt, then mark it as
|
||||||
|
* complete.
|
||||||
|
*/
|
||||||
|
static void gic_ack_irq(unsigned int irq)
|
||||||
|
{
|
||||||
|
u32 mask = 1 << (irq % 32);
|
||||||
|
writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4);
|
||||||
|
writel(irq, gic_cpu_base + GIC_CPU_EOI);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gic_mask_irq(unsigned int irq)
|
||||||
|
{
|
||||||
|
u32 mask = 1 << (irq % 32);
|
||||||
|
writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gic_unmask_irq(unsigned int irq)
|
||||||
|
{
|
||||||
|
u32 mask = 1 << (irq % 32);
|
||||||
|
writel(mask, gic_dist_base + GIC_DIST_ENABLE_SET + (irq / 32) * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gic_set_cpu(struct irqdesc *desc, unsigned int irq, unsigned int cpu)
|
||||||
|
{
|
||||||
|
void __iomem *reg = gic_dist_base + GIC_DIST_TARGET + (irq & ~3);
|
||||||
|
unsigned int shift = (irq % 4) * 8;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
val = readl(reg) & ~(0xff << shift);
|
||||||
|
val |= 1 << (cpu + shift);
|
||||||
|
writel(val, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irqchip gic_chip = {
|
||||||
|
.ack = gic_ack_irq,
|
||||||
|
.mask = gic_mask_irq,
|
||||||
|
.unmask = gic_unmask_irq,
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
.set_cpu = gic_set_cpu,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init gic_dist_init(void __iomem *base)
|
||||||
|
{
|
||||||
|
unsigned int max_irq, i;
|
||||||
|
u32 cpumask = 1 << smp_processor_id();
|
||||||
|
|
||||||
|
cpumask |= cpumask << 8;
|
||||||
|
cpumask |= cpumask << 16;
|
||||||
|
|
||||||
|
gic_dist_base = base;
|
||||||
|
|
||||||
|
writel(0, base + GIC_DIST_CTRL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find out how many interrupts are supported.
|
||||||
|
*/
|
||||||
|
max_irq = readl(base + GIC_DIST_CTR) & 0x1f;
|
||||||
|
max_irq = (max_irq + 1) * 32;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The GIC only supports up to 1020 interrupt sources.
|
||||||
|
* Limit this to either the architected maximum, or the
|
||||||
|
* platform maximum.
|
||||||
|
*/
|
||||||
|
if (max_irq > max(1020, NR_IRQS))
|
||||||
|
max_irq = max(1020, NR_IRQS);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set all global interrupts to be level triggered, active low.
|
||||||
|
*/
|
||||||
|
for (i = 32; i < max_irq; i += 16)
|
||||||
|
writel(0, base + GIC_DIST_CONFIG + i * 4 / 16);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set all global interrupts to this CPU only.
|
||||||
|
*/
|
||||||
|
for (i = 32; i < max_irq; i += 4)
|
||||||
|
writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set priority on all interrupts.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < max_irq; i += 4)
|
||||||
|
writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable all interrupts.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < max_irq; i += 32)
|
||||||
|
writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the Linux IRQ subsystem.
|
||||||
|
*/
|
||||||
|
for (i = 29; i < max_irq; i++) {
|
||||||
|
set_irq_chip(i, &gic_chip);
|
||||||
|
set_irq_handler(i, do_level_IRQ);
|
||||||
|
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(1, base + GIC_DIST_CTRL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cpuinit gic_cpu_init(void __iomem *base)
|
||||||
|
{
|
||||||
|
gic_cpu_base = base;
|
||||||
|
writel(0xf0, base + GIC_CPU_PRIMASK);
|
||||||
|
writel(1, base + GIC_CPU_CTRL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
void gic_raise_softirq(cpumask_t cpumask, unsigned int irq)
|
||||||
|
{
|
||||||
|
unsigned long map = *cpus_addr(cpumask);
|
||||||
|
|
||||||
|
writel(map << 16 | irq, gic_dist_base + GIC_DIST_SOFTINT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -327,6 +327,12 @@ __syscall_start:
|
|||||||
/* 310 */ .long sys_request_key
|
/* 310 */ .long sys_request_key
|
||||||
.long sys_keyctl
|
.long sys_keyctl
|
||||||
.long sys_semtimedop
|
.long sys_semtimedop
|
||||||
|
/* vserver */ .long sys_ni_syscall
|
||||||
|
.long sys_ioprio_set
|
||||||
|
/* 315 */ .long sys_ioprio_get
|
||||||
|
.long sys_inotify_init
|
||||||
|
.long sys_inotify_add_watch
|
||||||
|
.long sys_inotify_rm_watch
|
||||||
__syscall_end:
|
__syscall_end:
|
||||||
|
|
||||||
.rept NR_syscalls - (__syscall_end - __syscall_start) / 4
|
.rept NR_syscalls - (__syscall_end - __syscall_start) / 4
|
||||||
|
|||||||
@@ -658,11 +658,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
|
|||||||
/*
|
/*
|
||||||
* Block the signal if we were unsuccessful.
|
* Block the signal if we were unsuccessful.
|
||||||
*/
|
*/
|
||||||
if (ret != 0 || !(ka->sa.sa_flags & SA_NODEFER)) {
|
if (ret != 0) {
|
||||||
spin_lock_irq(&tsk->sighand->siglock);
|
spin_lock_irq(&tsk->sighand->siglock);
|
||||||
sigorsets(&tsk->blocked, &tsk->blocked,
|
sigorsets(&tsk->blocked, &tsk->blocked,
|
||||||
&ka->sa.sa_mask);
|
&ka->sa.sa_mask);
|
||||||
sigaddset(&tsk->blocked, sig);
|
if (!(ka->sa.sa_flags & SA_NODEFER))
|
||||||
|
sigaddset(&tsk->blocked, sig);
|
||||||
recalc_sigpending();
|
recalc_sigpending();
|
||||||
spin_unlock_irq(&tsk->sighand->siglock);
|
spin_unlock_irq(&tsk->sighand->siglock);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -617,7 +617,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
|
|||||||
notify_die("unknown data abort code", regs, &info, instr, 0);
|
notify_die("unknown data abort code", regs, &info, instr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile void __bug(const char *file, int line, void *data)
|
void __attribute__((noreturn)) __bug(const char *file, int line, void *data)
|
||||||
{
|
{
|
||||||
printk(KERN_CRIT"kernel BUG at %s:%d!", file, line);
|
printk(KERN_CRIT"kernel BUG at %s:%d!", file, line);
|
||||||
if (data)
|
if (data)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ static struct flash_platform_data coyote_flash_data = {
|
|||||||
|
|
||||||
static struct resource coyote_flash_resource = {
|
static struct resource coyote_flash_resource = {
|
||||||
.start = COYOTE_FLASH_BASE,
|
.start = COYOTE_FLASH_BASE,
|
||||||
.end = COYOTE_FLASH_BASE + COYOTE_FLASH_SIZE,
|
.end = COYOTE_FLASH_BASE + COYOTE_FLASH_SIZE - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ static struct flash_platform_data gtwx5715_flash_data = {
|
|||||||
|
|
||||||
static struct resource gtwx5715_flash_resource = {
|
static struct resource gtwx5715_flash_resource = {
|
||||||
.start = GTWX5715_FLASH_BASE,
|
.start = GTWX5715_FLASH_BASE,
|
||||||
.end = GTWX5715_FLASH_BASE + GTWX5715_FLASH_SIZE,
|
.end = GTWX5715_FLASH_BASE + GTWX5715_FLASH_SIZE - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ static struct flash_platform_data ixdp425_flash_data = {
|
|||||||
|
|
||||||
static struct resource ixdp425_flash_resource = {
|
static struct resource ixdp425_flash_resource = {
|
||||||
.start = IXDP425_FLASH_BASE,
|
.start = IXDP425_FLASH_BASE,
|
||||||
.end = IXDP425_FLASH_BASE + IXDP425_FLASH_SIZE,
|
.end = IXDP425_FLASH_BASE + IXDP425_FLASH_SIZE - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
* 28-Sep-2004 BJD Updates for new serial port bits
|
* 28-Sep-2004 BJD Updates for new serial port bits
|
||||||
* 04-Nov-2004 BJD Updated UART configuration process
|
* 04-Nov-2004 BJD Updated UART configuration process
|
||||||
* 10-Jan-2005 BJD Removed s3c2410_clock_tick_rate
|
* 10-Jan-2005 BJD Removed s3c2410_clock_tick_rate
|
||||||
|
* 13-Aug-2005 DA Removed UART from initial I/O mappings
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
@@ -49,10 +50,9 @@ static struct map_desc s3c2410_iodesc[] __initdata = {
|
|||||||
IODESC_ENT(USBHOST),
|
IODESC_ENT(USBHOST),
|
||||||
IODESC_ENT(CLKPWR),
|
IODESC_ENT(CLKPWR),
|
||||||
IODESC_ENT(LCD),
|
IODESC_ENT(LCD),
|
||||||
IODESC_ENT(UART),
|
|
||||||
IODESC_ENT(TIMER),
|
IODESC_ENT(TIMER),
|
||||||
IODESC_ENT(ADC),
|
IODESC_ENT(ADC),
|
||||||
IODESC_ENT(WATCHDOG)
|
IODESC_ENT(WATCHDOG),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct resource s3c_uart0_resource[] = {
|
static struct resource s3c_uart0_resource[] = {
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <asm/mach/map.h>
|
#include <asm/mach/map.h>
|
||||||
#include <asm/mach/serial_sa1100.h>
|
#include <asm/mach/serial_sa1100.h>
|
||||||
#include <asm/arch/assabet.h>
|
#include <asm/arch/assabet.h>
|
||||||
|
#include <asm/arch/mcp.h>
|
||||||
|
|
||||||
#include "generic.h"
|
#include "generic.h"
|
||||||
|
|
||||||
@@ -198,6 +199,11 @@ static struct irda_platform_data assabet_irda_data = {
|
|||||||
.set_speed = assabet_irda_set_speed,
|
.set_speed = assabet_irda_set_speed,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct mcp_plat_data assabet_mcp_data = {
|
||||||
|
.mccr0 = MCCR0_ADM,
|
||||||
|
.sclk_rate = 11981000,
|
||||||
|
};
|
||||||
|
|
||||||
static void __init assabet_init(void)
|
static void __init assabet_init(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -246,6 +252,7 @@ static void __init assabet_init(void)
|
|||||||
sa11x0_set_flash_data(&assabet_flash_data, assabet_flash_resources,
|
sa11x0_set_flash_data(&assabet_flash_data, assabet_flash_resources,
|
||||||
ARRAY_SIZE(assabet_flash_resources));
|
ARRAY_SIZE(assabet_flash_resources));
|
||||||
sa11x0_set_irda_data(&assabet_irda_data);
|
sa11x0_set_irda_data(&assabet_irda_data);
|
||||||
|
sa11x0_set_mcp_data(&assabet_mcp_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user