1
0
Fork 0

Merge branch 'master' of /home/trondmy/kernel/linux-2.6/

Conflicts:

	net/sunrpc/auth_gss/gss_krb5_crypto.c
	net/sunrpc/auth_gss/gss_spkm3_token.c
	net/sunrpc/clnt.c

Merge with mainline and fix conflicts.
hifive-unleashed-5.1
Trond Myklebust 2007-02-12 22:43:25 -08:00
commit d9bc125caf
3871 changed files with 178716 additions and 91647 deletions

10
CREDITS
View File

@ -2571,6 +2571,16 @@ S: Subiaco, 6008
S: Perth, Western Australia
S: Australia
N: Miguel Ojeda Sandonis
E: maxextreme@gmail.com
D: Author: Auxiliary LCD Controller driver (ks0108)
D: Author: Auxiliary LCD driver (cfag12864b)
D: Author: Auxiliary LCD framebuffer driver (cfag12864bfb)
D: Maintainer: Auxiliary display drivers tree (drivers/auxdisplay/*)
S: C/ Mieses 20, 9-B
S: Valladolid 47009
S: Spain
N: Greg Page
E: gpage@sovereign.org
D: IPX development and support

View File

@ -1,6 +1,6 @@
What: /debug/pktcdvd/pktcdvd[0-7]
Date: Oct. 2006
KernelVersion: 2.6.19
KernelVersion: 2.6.20
Contact: Thomas Maier <balagi@justmail.de>
Description:
@ -11,8 +11,7 @@ The pktcdvd module (packet writing driver) creates
these files in debugfs:
/debug/pktcdvd/pktcdvd[0-7]/
info (0444) Lots of human readable driver
statistics and infos. Multiple lines!
info (0444) Lots of driver statistics and infos.
Example:
-------

View File

@ -1,6 +1,6 @@
What: /sys/class/pktcdvd/
Date: Oct. 2006
KernelVersion: 2.6.19
KernelVersion: 2.6.20
Contact: Thomas Maier <balagi@justmail.de>
Description:

View File

@ -482,13 +482,13 @@ slightly.
<para>Gadget drivers
rely on common USB structures and constants
defined in the
<filename>&lt;linux/usb_ch9.h&gt;</filename>
<filename>&lt;linux/usb/ch9.h&gt;</filename>
header file, which is standard in Linux 2.6 kernels.
These are the same types and constants used by host
side drivers (and usbcore).
</para>
!Iinclude/linux/usb_ch9.h
!Iinclude/linux/usb/ch9.h
</sect1>
<sect1 id="core"><title>Core Objects and Methods</title>

View File

@ -316,6 +316,9 @@ X!Earch/i386/kernel/mca.c
<sect1><title>DMI Interfaces</title>
!Edrivers/firmware/dmi_scan.c
</sect1>
<sect1><title>EDD Interfaces</title>
!Idrivers/firmware/edd.c
</sect1>
</chapter>
<chapter id="security">

View File

@ -4,4 +4,5 @@
<param name="funcsynopsis.style">ansi</param>
<param name="funcsynopsis.tabular.threshold">80</param>
<!-- <param name="paper.type">A4</param> -->
<param name="generate.section.toc.level">2</param>
</stylesheet>

View File

@ -187,13 +187,13 @@
<chapter><title>USB-Standard Types</title>
<para>In <filename>&lt;linux/usb_ch9.h&gt;</filename> you will find
<para>In <filename>&lt;linux/usb/ch9.h&gt;</filename> you will find
the USB data types defined in chapter 9 of the USB specification.
These data types are used throughout USB, and in APIs including
this host side API, gadget APIs, and usbfs.
</para>
!Iinclude/linux/usb_ch9.h
!Iinclude/linux/usb/ch9.h
</chapter>
@ -574,7 +574,7 @@ for (;;) {
#include &lt;asm/byteorder.h&gt;</programlisting>
The standard USB device model requests, from "Chapter 9" of
the USB 2.0 specification, are automatically included from
the <filename>&lt;linux/usb_ch9.h&gt;</filename> header.
the <filename>&lt;linux/usb/ch9.h&gt;</filename> header.
</para>
<para>Unless noted otherwise, the ioctl requests

View File

@ -30,6 +30,7 @@ are not a good substitute for a solid C education and/or years of
experience, the following books are good for, if anything, reference:
- "The C Programming Language" by Kernighan and Ritchie [Prentice Hall]
- "Practical C Programming" by Steve Oualline [O'Reilly]
- "C: A Reference Manual" by Harbison and Steele [Prentice Hall]
The kernel is written using GNU C and the GNU toolchain. While it
adheres to the ISO C89 standard, it uses a number of extensions that are

View File

@ -0,0 +1,105 @@
===================================
cfag12864b LCD Driver Documentation
===================================
License: GPLv2
Author & Maintainer: Miguel Ojeda Sandonis <maxextreme@gmail.com>
Date: 2006-10-27
--------
0. INDEX
--------
1. DRIVER INFORMATION
2. DEVICE INFORMATION
3. WIRING
4. USERSPACE PROGRAMMING
---------------------
1. DRIVER INFORMATION
---------------------
This driver support one cfag12864b display at time.
---------------------
2. DEVICE INFORMATION
---------------------
Manufacturer: Crystalfontz
Device Name: Crystalfontz 12864b LCD Series
Device Code: cfag12864b
Webpage: http://www.crystalfontz.com
Device Webpage: http://www.crystalfontz.com/products/12864b/
Type: LCD (Liquid Crystal Display)
Width: 128
Height: 64
Colors: 2 (B/N)
Controller: ks0108
Controllers: 2
Pages: 8 each controller
Addresses: 64 each page
Data size: 1 byte each address
Memory size: 2 * 8 * 64 * 1 = 1024 bytes = 1 Kbyte
---------
3. WIRING
---------
The cfag12864b LCD Series don't have official wiring.
The common wiring is done to the parallel port as shown:
Parallel Port cfag12864b
Name Pin# Pin# Name
Strobe ( 1)------------------------------(17) Enable
Data 0 ( 2)------------------------------( 4) Data 0
Data 1 ( 3)------------------------------( 5) Data 1
Data 2 ( 4)------------------------------( 6) Data 2
Data 3 ( 5)------------------------------( 7) Data 3
Data 4 ( 6)------------------------------( 8) Data 4
Data 5 ( 7)------------------------------( 9) Data 5
Data 6 ( 8)------------------------------(10) Data 6
Data 7 ( 9)------------------------------(11) Data 7
(10) [+5v]---( 1) Vdd
(11) [GND]---( 2) Ground
(12) [+5v]---(14) Reset
(13) [GND]---(15) Read / Write
Line (14)------------------------------(13) Controller Select 1
(15)
Init (16)------------------------------(12) Controller Select 2
Select (17)------------------------------(16) Data / Instruction
Ground (18)---[GND] [+5v]---(19) LED +
Ground (19)---[GND]
Ground (20)---[GND] E A Values:
Ground (21)---[GND] [GND]---[P1]---(18) Vee · R = Resistor = 22 ohm
Ground (22)---[GND] | · P1 = Preset = 10 Kohm
Ground (23)---[GND] ---- S ------( 3) V0 · P2 = Preset = 1 Kohm
Ground (24)---[GND] | |
Ground (25)---[GND] [GND]---[P2]---[R]---(20) LED -
------------------------
4. USERSPACE PROGRAMMING
------------------------
The cfag12864bfb describes a framebuffer device (/dev/fbX).
It has a size of 1024 bytes = 1 Kbyte.
Each bit represents one pixel. If the bit is high, the pixel will
turn on. If the pixel is low, the pixel will turn off.
You can use the framebuffer as a file: fopen, fwrite, fclose...
Although the LCD won't get updated until the next refresh time arrives.
Also, you can mmap the framebuffer: open & mmap, munmap & close...
which is the best option for most uses.
Check Documentation/auxdisplay/cfag12864b-example.c
for a real working userspace complete program with usage examples.

View File

@ -0,0 +1,282 @@
/*
* Filename: cfag12864b-example.c
* Version: 0.1.0
* Description: cfag12864b LCD userspace example program
* License: GPLv2
*
* Author: Copyright (C) Miguel Ojeda Sandonis <maxextreme@gmail.com>
* Date: 2006-10-31
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/*
* ------------------------
* start of cfag12864b code
* ------------------------
*/
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#define CFAG12864B_WIDTH (128)
#define CFAG12864B_HEIGHT (64)
#define CFAG12864B_SIZE (128 * 64 / 8)
#define CFAG12864B_BPB (8)
#define CFAG12864B_ADDRESS(x, y) ((y) * CFAG12864B_WIDTH / \
CFAG12864B_BPB + (x) / CFAG12864B_BPB)
#define CFAG12864B_BIT(n) (((unsigned char) 1) << (n))
#undef CFAG12864B_DOCHECK
#ifdef CFAG12864B_DOCHECK
#define CFAG12864B_CHECK(x, y) ((x) < CFAG12864B_WIDTH && \
(y) < CFAG12864B_HEIGHT)
#else
#define CFAG12864B_CHECK(x, y) (1)
#endif
int cfag12864b_fd;
unsigned char * cfag12864b_mem;
unsigned char cfag12864b_buffer[CFAG12864B_SIZE];
/*
* init a cfag12864b framebuffer device
*
* No error: return = 0
* Unable to open: return = -1
* Unable to mmap: return = -2
*/
int cfag12864b_init(char *path)
{
cfag12864b_fd = open(path, O_RDWR);
if (cfag12864b_fd == -1)
return -1;
cfag12864b_mem = mmap(0, CFAG12864B_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, cfag12864b_fd, 0);
if (cfag12864b_mem == MAP_FAILED) {
close(cfag12864b_fd);
return -2;
}
return 0;
}
/*
* exit a cfag12864b framebuffer device
*/
void cfag12864b_exit(void)
{
munmap(cfag12864b_mem, CFAG12864B_SIZE);
close(cfag12864b_fd);
}
/*
* set (x, y) pixel
*/
void cfag12864b_set(unsigned char x, unsigned char y)
{
if (CFAG12864B_CHECK(x, y))
cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] |=
CFAG12864B_BIT(x % CFAG12864B_BPB);
}
/*
* unset (x, y) pixel
*/
void cfag12864b_unset(unsigned char x, unsigned char y)
{
if (CFAG12864B_CHECK(x, y))
cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] &=
~CFAG12864B_BIT(x % CFAG12864B_BPB);
}
/*
* is set (x, y) pixel?
*
* Pixel off: return = 0
* Pixel on: return = 1
*/
unsigned char cfag12864b_isset(unsigned char x, unsigned char y)
{
if (CFAG12864B_CHECK(x, y))
if (cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] &
CFAG12864B_BIT(x % CFAG12864B_BPB))
return 1;
return 0;
}
/*
* not (x, y) pixel
*/
void cfag12864b_not(unsigned char x, unsigned char y)
{
if (cfag12864b_isset(x, y))
cfag12864b_unset(x, y);
else
cfag12864b_set(x, y);
}
/*
* fill (set all pixels)
*/
void cfag12864b_fill(void)
{
unsigned short i;
for (i = 0; i < CFAG12864B_SIZE; i++)
cfag12864b_buffer[i] = 0xFF;
}
/*
* clear (unset all pixels)
*/
void cfag12864b_clear(void)
{
unsigned short i;
for (i = 0; i < CFAG12864B_SIZE; i++)
cfag12864b_buffer[i] = 0;
}
/*
* format a [128*64] matrix
*
* Pixel off: src[i] = 0
* Pixel on: src[i] > 0
*/
void cfag12864b_format(unsigned char * matrix)
{
unsigned char i, j, n;
for (i = 0; i < CFAG12864B_HEIGHT; i++)
for (j = 0; j < CFAG12864B_WIDTH / CFAG12864B_BPB; j++) {
cfag12864b_buffer[i * CFAG12864B_WIDTH / CFAG12864B_BPB +
j] = 0;
for (n = 0; n < CFAG12864B_BPB; n++)
if (matrix[i * CFAG12864B_WIDTH +
j * CFAG12864B_BPB + n])
cfag12864b_buffer[i * CFAG12864B_WIDTH /
CFAG12864B_BPB + j] |=
CFAG12864B_BIT(n);
}
}
/*
* blit buffer to lcd
*/
void cfag12864b_blit(void)
{
memcpy(cfag12864b_mem, cfag12864b_buffer, CFAG12864B_SIZE);
}
/*
* ----------------------
* end of cfag12864b code
* ----------------------
*/
#include <stdio.h>
#include <string.h>
#define EXAMPLES 6
void example(unsigned char n)
{
unsigned short i, j;
unsigned char matrix[CFAG12864B_WIDTH * CFAG12864B_HEIGHT];
if (n > EXAMPLES)
return;
printf("Example %i/%i - ", n, EXAMPLES);
switch (n) {
case 1:
printf("Draw points setting bits");
cfag12864b_clear();
for (i = 0; i < CFAG12864B_WIDTH; i += 2)
for (j = 0; j < CFAG12864B_HEIGHT; j += 2)
cfag12864b_set(i, j);
break;
case 2:
printf("Clear the LCD");
cfag12864b_clear();
break;
case 3:
printf("Draw rows formatting a [128*64] matrix");
memset(matrix, 0, CFAG12864B_WIDTH * CFAG12864B_HEIGHT);
for (i = 0; i < CFAG12864B_WIDTH; i++)
for (j = 0; j < CFAG12864B_HEIGHT; j += 2)
matrix[j * CFAG12864B_WIDTH + i] = 1;
cfag12864b_format(matrix);
break;
case 4:
printf("Fill the lcd");
cfag12864b_fill();
break;
case 5:
printf("Draw columns unsetting bits");
for (i = 0; i < CFAG12864B_WIDTH; i += 2)
for (j = 0; j < CFAG12864B_HEIGHT; j++)
cfag12864b_unset(i, j);
break;
case 6:
printf("Do negative not-ing all bits");
for (i = 0; i < CFAG12864B_WIDTH; i++)
for (j = 0; j < CFAG12864B_HEIGHT; j ++)
cfag12864b_not(i, j);
break;
}
puts(" - [Press Enter]");
}
int main(int argc, char *argv[])
{
unsigned char n;
if (argc != 2) {
printf(
"Sintax: %s fbdev\n"
"Usually: /dev/fb0, /dev/fb1...\n", argv[0]);
return -1;
}
if (cfag12864b_init(argv[1])) {
printf("Can't init %s fbdev\n", argv[1]);
return -2;
}
for (n = 1; n <= EXAMPLES; n++) {
example(n);
cfag12864b_blit();
while (getchar() != '\n');
}
cfag12864b_exit();
return 0;
}

View File

@ -0,0 +1,55 @@
==========================================
ks0108 LCD Controller Driver Documentation
==========================================
License: GPLv2
Author & Maintainer: Miguel Ojeda Sandonis <maxextreme@gmail.com>
Date: 2006-10-27
--------
0. INDEX
--------
1. DRIVER INFORMATION
2. DEVICE INFORMATION
3. WIRING
---------------------
1. DRIVER INFORMATION
---------------------
This driver support the ks0108 LCD controller.
---------------------
2. DEVICE INFORMATION
---------------------
Manufacturer: Samsung
Device Name: KS0108 LCD Controller
Device Code: ks0108
Webpage: -
Device Webpage: -
Type: LCD Controller (Liquid Crystal Display Controller)
Width: 64
Height: 64
Colors: 2 (B/N)
Pages: 8
Addresses: 64 each page
Data size: 1 byte each address
Memory size: 8 * 64 * 1 = 512 bytes
---------
3. WIRING
---------
The driver supports data parallel port wiring.
If you aren't building LCD related hardware, you should check
your LCD specific wiring information in the same folder.
For example, check Documentation/auxdisplay/cfag12864b.

View File

@ -93,7 +93,7 @@ Notes
Using the pktcdvd sysfs interface
---------------------------------
Since Linux 2.6.19, the pktcdvd module has a sysfs interface
Since Linux 2.6.20, the pktcdvd module has a sysfs interface
and can be controlled by it. For example the "pktcdvd" tool uses
this interface. (see http://people.freenet.de/BalaGi#pktcdvd )

View File

@ -193,6 +193,7 @@ Original developers of the crypto algorithms:
Kartikey Mahendra Bhatt (CAST6)
Jon Oberheide (ARC4)
Jouni Malinen (Michael MIC)
NTT(Nippon Telegraph and Telephone Corporation) (Camellia)
SHA1 algorithm contributors:
Jean-Francois Dive
@ -246,6 +247,9 @@ Tiger algorithm contributors:
VIA PadLock contributors:
Michal Ludvig
Camellia algorithm contributors:
NTT(Nippon Telegraph and Telephone Corporation) (Camellia)
Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>
Please send any credits updates or corrections to:

View File

@ -0,0 +1,268 @@
Devres - Managed Device Resource
================================
Tejun Heo <teheo@suse.de>
First draft 10 January 2007
1. Intro : Huh? Devres?
2. Devres : Devres in a nutshell
3. Devres Group : Group devres'es and release them together
4. Details : Life time rules, calling context, ...
5. Overhead : How much do we have to pay for this?
6. List of managed interfaces : Currently implemented managed interfaces
1. Intro
--------
devres came up while trying to convert libata to use iomap. Each
iomapped address should be kept and unmapped on driver detach. For
example, a plain SFF ATA controller (that is, good old PCI IDE) in
native mode makes use of 5 PCI BARs and all of them should be
maintained.
As with many other device drivers, libata low level drivers have
sufficient bugs in ->remove and ->probe failure path. Well, yes,
that's probably because libata low level driver developers are lazy
bunch, but aren't all low level driver developers? After spending a
day fiddling with braindamaged hardware with no document or
braindamaged document, if it's finally working, well, it's working.
For one reason or another, low level drivers don't receive as much
attention or testing as core code, and bugs on driver detach or
initilaization failure doesn't happen often enough to be noticeable.
Init failure path is worse because it's much less travelled while
needs to handle multiple entry points.
So, many low level drivers end up leaking resources on driver detach
and having half broken failure path implementation in ->probe() which
would leak resources or even cause oops when failure occurs. iomap
adds more to this mix. So do msi and msix.
2. Devres
---------
devres is basically linked list of arbitrarily sized memory areas
associated with a struct device. Each devres entry is associated with
a release function. A devres can be released in several ways. No
matter what, all devres entries are released on driver detach. On
release, the associated release function is invoked and then the
devres entry is freed.
Managed interface is created for resources commonly used by device
drivers using devres. For example, coherent DMA memory is acquired
using dma_alloc_coherent(). The managed version is called
dmam_alloc_coherent(). It is identical to dma_alloc_coherent() except
for the DMA memory allocated using it is managed and will be
automatically released on driver detach. Implementation looks like
the following.
struct dma_devres {
size_t size;
void *vaddr;
dma_addr_t dma_handle;
};
static void dmam_coherent_release(struct device *dev, void *res)
{
struct dma_devres *this = res;
dma_free_coherent(dev, this->size, this->vaddr, this->dma_handle);
}
dmam_alloc_coherent(dev, size, dma_handle, gfp)
{
struct dma_devres *dr;
void *vaddr;
dr = devres_alloc(dmam_coherent_release, sizeof(*dr), gfp);
...
/* alloc DMA memory as usual */
vaddr = dma_alloc_coherent(...);
...
/* record size, vaddr, dma_handle in dr */
dr->vaddr = vaddr;
...
devres_add(dev, dr);
return vaddr;
}
If a driver uses dmam_alloc_coherent(), the area is guaranteed to be
freed whether initialization fails half-way or the device gets
detached. If most resources are acquired using managed interface, a
driver can have much simpler init and exit code. Init path basically
looks like the following.
my_init_one()
{
struct mydev *d;
d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL);
if (!d)
return -ENOMEM;
d->ring = dmam_alloc_coherent(...);
if (!d->ring)
return -ENOMEM;
if (check something)
return -EINVAL;
...
return register_to_upper_layer(d);
}
And exit path,
my_remove_one()
{
unregister_from_upper_layer(d);
shutdown_my_hardware();
}
As shown above, low level drivers can be simplified a lot by using
devres. Complexity is shifted from less maintained low level drivers
to better maintained higher layer. Also, as init failure path is
shared with exit path, both can get more testing.
3. Devres group
---------------
Devres entries can be grouped using devres group. When a group is
released, all contained normal devres entries and properly nested
groups are released. One usage is to rollback series of acquired
resources on failure. For example,
if (!devres_open_group(dev, NULL, GFP_KERNEL))
return -ENOMEM;
acquire A;
if (failed)
goto err;
acquire B;
if (failed)
goto err;
...
devres_remove_group(dev, NULL);
return 0;
err:
devres_release_group(dev, NULL);
return err_code;
As resource acquision failure usually means probe failure, constructs
like above are usually useful in midlayer driver (e.g. libata core
layer) where interface function shouldn't have side effect on failure.
For LLDs, just returning error code suffices in most cases.
Each group is identified by void *id. It can either be explicitly
specified by @id argument to devres_open_group() or automatically
created by passing NULL as @id as in the above example. In both
cases, devres_open_group() returns the group's id. The returned id
can be passed to other devres functions to select the target group.
If NULL is given to those functions, the latest open group is
selected.
For example, you can do something like the following.
int my_midlayer_create_something()
{
if (!devres_open_group(dev, my_midlayer_create_something, GFP_KERNEL))
return -ENOMEM;
...
devres_close_group(dev, my_midlayer_something);
return 0;
}
void my_midlayer_destroy_something()
{
devres_release_group(dev, my_midlayer_create_soemthing);
}
4. Details
----------
Lifetime of a devres entry begins on devres allocation and finishes
when it is released or destroyed (removed and freed) - no reference
counting.
devres core guarantees atomicity to all basic devres operations and
has support for single-instance devres types (atomic
lookup-and-add-if-not-found). Other than that, synchronizing
concurrent accesses to allocated devres data is caller's
responsibility. This is usually non-issue because bus ops and
resource allocations already do the job.
For an example of single-instance devres type, read pcim_iomap_table()
in lib/iomap.c.
All devres interface functions can be called without context if the
right gfp mask is given.
5. Overhead
-----------
Each devres bookkeeping info is allocated together with requested data
area. With debug option turned off, bookkeeping info occupies 16
bytes on 32bit machines and 24 bytes on 64bit (three pointers rounded
up to ull alignment). If singly linked list is used, it can be
reduced to two pointers (8 bytes on 32bit, 16 bytes on 64bit).
Each devres group occupies 8 pointers. It can be reduced to 6 if
singly linked list is used.
Memory space overhead on ahci controller with two ports is between 300
and 400 bytes on 32bit machine after naive conversion (we can
certainly invest a bit more effort into libata core layer).
6. List of managed interfaces
-----------------------------
IO region
devm_request_region()
devm_request_mem_region()
devm_release_region()
devm_release_mem_region()
IRQ
devm_request_irq()
devm_free_irq()
DMA
dmam_alloc_coherent()
dmam_free_coherent()
dmam_alloc_noncoherent()
dmam_free_noncoherent()
dmam_declare_coherent_memory()
dmam_pool_create()
dmam_pool_destroy()
PCI
pcim_enable_device() : after success, all PCI ops become managed
pcim_pin_device() : keep PCI device enabled after release
IOMAP
devm_ioport_map()
devm_ioport_unmap()
devm_ioremap()
devm_ioremap_nocache()
devm_iounmap()
pcim_iomap()
pcim_iounmap()
pcim_iomap_table() : array of mapped addresses indexed by BAR
pcim_iomap_regions() : do request_region() and iomap() on multiple BARs

View File

@ -339,7 +339,21 @@ Device Symlink:
'device'
Symlink to the memory controller device
Symlink to the memory controller device.
Sdram memory scrubbing rate:
'sdram_scrub_rate'
Read/Write attribute file that controls memory scrubbing. The scrubbing
rate is set by writing a minimum bandwith in bytes/sec to the attribute
file. The rate will be translated to an internal value that gives at
least the specified rate.
Reading the file will return the actual scrubbing rate employed.
If configuration fails or memory scrubbing is not implemented, the value
of the attribute file will be -1.

View File

@ -0,0 +1,78 @@
s3fb - fbdev driver for S3 Trio/Virge chips
===========================================
Supported Hardware
==================
S3 Trio32
S3 Trio64 (and variants V+, UV+, V2/DX, V2/GX)
S3 Virge (and variants VX, DX, GX and GX2+)
S3 Plato/PX (completely untested)
S3 Aurora64V+ (completely untested)
- only PCI bus supported
- only BIOS initialized VGA devices supported
- probably not working on big endian
I tested s3fb on Trio64 (plain, V+ and V2/DX) and Virge (plain, VX, DX),
all on i386.
Supported Features
==================
* 4 bpp pseudocolor modes (with 18bit palette, two variants)
* 8 bpp pseudocolor mode (with 18bit palette)
* 16 bpp truecolor modes (RGB 555 and RGB 565)
* 24 bpp truecolor mode (RGB 888) on (only on Virge VX)
* 32 bpp truecolor mode (RGB 888) on (not on Virge VX)
* text mode (activated by bpp = 0)
* interlaced mode variant (not available in text mode)
* doublescan mode variant (not available in text mode)
* panning in both directions
* suspend/resume support
* DPMS support
Text mode is supported even in higher resolutions, but there is limitation
to lower pixclocks (maximum between 50-60 MHz, depending on specific hardware).
This limitation is not enforced by driver. Text mode supports 8bit wide fonts
only (hardware limitation) and 16bit tall fonts (driver limitation).
There are two 4 bpp modes. First mode (selected if nonstd == 0) is mode with
packed pixels, high nibble first. Second mode (selected if nonstd == 1) is mode
with interleaved planes (1 byte interleave), MSB first. Both modes support
8bit wide fonts only (driver limitation).
Suspend/resume works on systems that initialize video card during resume and
if device is active (for example used by fbcon).
Missing Features
================
(alias TODO list)
* secondary (not initialized by BIOS) device support
* big endian support
* Zorro bus support
* MMIO support
* 24 bpp mode support on more cards
* support for fontwidths != 8 in 4 bpp modes
* support for fontheight != 16 in text mode
* composite and external sync (is anyone able to test this?)
* hardware cursor
* video overlay support
* vsync synchronization
* feature connector support
* acceleration support (8514-like 2D, Virge 3D, busmaster transfers)
* better values for some magic registers (performance issues)
Known bugs
==========
* cursor disable in text mode doesn't work
--
Ondrej Zajicek <santiago@crfreenet.org>

View File

@ -50,22 +50,6 @@ Who: Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
---------------------------
What: ieee1394 core's unused exports (CONFIG_IEEE1394_EXPORT_FULL_API)
When: January 2007
Why: There are no projects known to use these exported symbols, except
dfg1394 (uses one symbol whose functionality is core-internal now).
Who: Stefan Richter <stefanr@s5r6.in-berlin.de>
---------------------------
What: ieee1394's *_oui sysfs attributes (CONFIG_IEEE1394_OUI_DB)
When: January 2007
Files: drivers/ieee1394/: oui.db, oui2c.sh
Why: big size, little value
Who: Stefan Richter <stefanr@s5r6.in-berlin.de>
---------------------------
What: Video4Linux API 1 ioctls and video_decoder.h from Video devices.
When: December 2006
Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
@ -186,18 +170,6 @@ Who: Greg Kroah-Hartman <gregkh@suse.de>
---------------------------
What: find_trylock_page
When: January 2007
Why: The interface no longer has any callers left in the kernel. It
is an odd interface (compared with other find_*_page functions), in
that it does not take a refcount to the page, only the page lock.
It should be replaced with find_get_page or find_lock_page if possible.
This feature removal can be reevaluated if users of the interface
cannot cleanly use something else.
Who: Nick Piggin <npiggin@suse.de>
---------------------------
What: Interrupt only SA_* flags
When: Januar 2007
Why: The interrupt related SA_* flags are replaced by IRQF_* to move them
@ -243,6 +215,13 @@ Who: Jean Delvare <khali@linux-fr.org>,
---------------------------
What: drivers depending on OBSOLETE_OSS
When: options in 2.6.22, code in 2.6.24
Why: OSS drivers with ALSA replacements
Who: Adrian Bunk <bunk@stusta.de>
---------------------------
What: IPv4 only connection tracking/NAT/helpers
When: 2.6.22
Why: The new layer 3 independant connection tracking replaces the old
@ -274,6 +253,7 @@ Who: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
---------------------------
<<<<<<< test:Documentation/feature-removal-schedule.txt
What: ACPI hotkey driver (CONFIG_ACPI_HOTKEY)
When: 2.6.21
Why: hotkey.c was an attempt to consolidate multiple drivers that use
@ -306,11 +286,18 @@ Why: The ACPI namespace is effectively the symbol list for
the BIOS can be extracted and disassembled with acpidump
and iasl as documented in the pmtools package here:
http://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/utils
Who: Len Brown <len.brown@intel.com>
---------------------------
What: ACPI procfs interface
When: July 2007
Why: After ACPI sysfs conversion, ACPI attributes will be duplicated
in sysfs and the ACPI procfs interface should be removed.
Who: Zhang Rui <rui.zhang@intel.com>
---------------------------
What: /proc/acpi/button
When: August 2007
Why: /proc/acpi/button has been replaced by events to the input layer
@ -325,3 +312,25 @@ Why: Unmaintained for years, superceded by JFFS2 for years.
Who: Jeff Garzik <jeff@garzik.org>
---------------------------
What: sk98lin network driver
When: July 2007
Why: In kernel tree version of driver is unmaintained. Sk98lin driver
replaced by the skge driver.
Who: Stephen Hemminger <shemminger@osdl.org>
---------------------------
What: Compaq touchscreen device emulation
When: Oct 2007
Files: drivers/input/tsdev.c
Why: The code says it was obsolete when it was written in 2001.
tslib is a userspace library which does anything tsdev can do and
much more besides in userspace where this code belongs. There is no
longer any need for tsdev and applications should have converted to
use tslib by now.
The name "tsdev" is also extremely confusing and lots of people have
it loaded when they don't need/use it.
Who: Richard Purdie <rpurdie@rpsys.net>
---------------------------

View File

@ -157,7 +157,7 @@ TBD(curr. line MT:/API/)
channel management functions:
relay_open(base_filename, parent, subbuf_size, n_subbufs,
callbacks)
callbacks, private_data)
relay_close(chan)
relay_flush(chan)
relay_reset(chan)
@ -251,7 +251,7 @@ static struct rchan_callbacks relay_callbacks =
And an example relay_open() invocation using them:
chan = relay_open("cpu", NULL, SUBBUF_SIZE, N_SUBBUFS, &relay_callbacks);
chan = relay_open("cpu", NULL, SUBBUF_SIZE, N_SUBBUFS, &relay_callbacks, NULL);
If the create_buf_file() callback fails, or isn't defined, channel
creation and thus relay_open() will fail.
@ -289,6 +289,11 @@ they use the proper locking for such a buffer, either by wrapping
writes in a spinlock, or by copying a write function from relay.h and
creating a local version that internally does the proper locking.
The private_data passed into relay_open() allows clients to associate
user-defined data with a channel, and is immediately available
(including in create_buf_file()) via chan->private_data or
buf->chan->private_data.
Channel 'modes'
---------------

View File

@ -21,7 +21,7 @@ ufstype=type_of_ufs
supported as read-write
ufs2 used in FreeBSD 5.x
supported as read-only
supported as read-write
5xbsd synonym for ufs2
@ -50,12 +50,11 @@ ufstype=type_of_ufs
POSSIBLE PROBLEMS
=================
There is still bug in reallocation of fragment, in file fs/ufs/balloc.c,
line 364. But it seems working on current buffer cache configuration.
See next section, if you have any.
BUG REPORTS
===========
Any ufs bug report you can send to daniel.pirkl@email.cz (do not send
partition tables bug reports.)
Any ufs bug report you can send to daniel.pirkl@email.cz or
to dushistov@mail.ru (do not send partition tables bug reports).

View File

@ -0,0 +1,271 @@
GPIO Interfaces
This provides an overview of GPIO access conventions on Linux.
What is a GPIO?
===============
A "General Purpose Input/Output" (GPIO) is a flexible software-controlled
digital signal. They are provided from many kinds of chip, and are familiar
to Linux developers working with embedded and custom hardware. Each GPIO
represents a bit connected to a particular pin, or "ball" on Ball Grid Array
(BGA) packages. Board schematics show which external hardware connects to
which GPIOs. Drivers can be written generically, so that board setup code
passes such pin configuration data to drivers.
System-on-Chip (SOC) processors heavily rely on GPIOs. In some cases, every
non-dedicated pin can be configured as a GPIO; and most chips have at least
several dozen of them. Programmable logic devices (like FPGAs) can easily
provide GPIOs; multifunction chips like power managers, and audio codecs
often have a few such pins to help with pin scarcity on SOCs; and there are
also "GPIO Expander" chips that connect using the I2C or SPI serial busses.
Most PC southbridges have a few dozen GPIO-capable pins (with only the BIOS
firmware knowing how they're used).
The exact capabilities of GPIOs vary between systems. Common options:
- Output values are writable (high=1, low=0). Some chips also have
options about how that value is driven, so that for example only one
value might be driven ... supporting "wire-OR" and similar schemes
for the other value.
- Input values are likewise readable (1, 0). Some chips support readback
of pins configured as "output", which is very useful in such "wire-OR"
cases (to support bidirectional signaling). GPIO controllers may have
input de-glitch logic, sometimes with software controls.
- Inputs can often be used as IRQ signals, often edge triggered but
sometimes level triggered. Such IRQs may be configurable as system
wakeup events, to wake the system from a low power state.
- Usually a GPIO will be configurable as either input or output, as needed
by different product boards; single direction ones exist too.
- Most GPIOs can be accessed while holding spinlocks, but those accessed
through a serial bus normally can't. Some systems support both types.
On a given board each GPIO is used for one specific purpose like monitoring
MMC/SD card insertion/removal, detecting card writeprotect status, driving
a LED, configuring a transceiver, bitbanging a serial bus, poking a hardware
watchdog, sensing a switch, and so on.
GPIO conventions
================
Note that this is called a "convention" because you don't need to do it this
way, and it's no crime if you don't. There **are** cases where portability
is not the main issue; GPIOs are often used for the kind of board-specific
glue logic that may even change between board revisions, and can't ever be
used on a board that's wired differently. Only least-common-denominator
functionality can be very portable. Other features are platform-specific,
and that can be critical for glue logic.
Plus, this doesn't define an implementation framework, just an interface.
One platform might implement it as simple inline functions accessing chip
registers; another might implement it by delegating through abstractions
used for several very different kinds of GPIO controller.
That said, if the convention is supported on their platform, drivers should
use it when possible:
#include <asm/gpio.h>
If you stick to this convention then it'll be easier for other developers to
see what your code is doing, and help maintain it.
Identifying GPIOs
-----------------
GPIOs are identified by unsigned integers in the range 0..MAX_INT. That
reserves "negative" numbers for other purposes like marking signals as
"not available on this board", or indicating faults.
Platforms define how they use those integers, and usually #define symbols
for the GPIO lines so that board-specific setup code directly corresponds
to the relevant schematics. In contrast, drivers should only use GPIO
numbers passed to them from that setup code, using platform_data to hold
board-specific pin configuration data (along with other board specific
data they need). That avoids portability problems.
So for example one platform uses numbers 32-159 for GPIOs; while another
uses numbers 0..63 with one set of GPIO controllers, 64-79 with another
type of GPIO controller, and on one particular board 80-95 with an FPGA.
The numbers need not be contiguous; either of those platforms could also
use numbers 2000-2063 to identify GPIOs in a bank of I2C GPIO expanders.
Whether a platform supports multiple GPIO controllers is currently a
platform-specific implementation issue.
Using GPIOs
-----------
One of the first things to do with a GPIO, often in board setup code when
setting up a platform_device using the GPIO, is mark its direction:
/* set as input or output, returning 0 or negative errno */
int gpio_direction_input(unsigned gpio);
int gpio_direction_output(unsigned gpio);
The return value is zero for success, else a negative errno. It should
be checked, since the get/set calls don't have error returns and since
misconfiguration is possible. (These calls could sleep.)
Setting the direction can fail if the GPIO number is invalid, or when
that particular GPIO can't be used in that mode. It's generally a bad
idea to rely on boot firmware to have set the direction correctly, since
it probably wasn't validated to do more than boot Linux. (Similarly,
that board setup code probably needs to multiplex that pin as a GPIO,
and configure pullups/pulldowns appropriately.)
Spinlock-Safe GPIO access
-------------------------
Most GPIO controllers can be accessed with memory read/write instructions.
That doesn't need to sleep, and can safely be done from inside IRQ handlers.
Use these calls to access such GPIOs:
/* GPIO INPUT: return zero or nonzero */
int gpio_get_value(unsigned gpio);
/* GPIO OUTPUT */
void gpio_set_value(unsigned gpio, int value);
The values are boolean, zero for low, nonzero for high. When reading the
value of an output pin, the value returned should be what's seen on the
pin ... that won't always match the specified output value, because of
issues including wire-OR and output latencies.
The get/set calls have no error returns because "invalid GPIO" should have
been reported earlier in gpio_set_direction(). However, note that not all
platforms can read the value of output pins; those that can't should always
return zero. Also, these calls will be ignored for GPIOs that can't safely
be accessed wihtout sleeping (see below).
Platform-specific implementations are encouraged to optimise the two
calls to access the GPIO value in cases where the GPIO number (and for
output, value) are constant. It's normal for them to need only a couple
of instructions in such cases (reading or writing a hardware register),
and not to need spinlocks. Such optimized calls can make bitbanging
applications a lot more efficient (in both space and time) than spending
dozens of instructions on subroutine calls.
GPIO access that may sleep
--------------------------
Some GPIO controllers must be accessed using message based busses like I2C
or SPI. Commands to read or write those GPIO values require waiting to
get to the head of a queue to transmit a command and get its response.
This requires sleeping, which can't be done from inside IRQ handlers.
Platforms that support this type of GPIO distinguish them from other GPIOs
by returning nonzero from this call:
int gpio_cansleep(unsigned gpio);
To access such GPIOs, a different set of accessors is defined:
/* GPIO INPUT: return zero or nonzero, might sleep */
int gpio_get_value_cansleep(unsigned gpio);
/* GPIO OUTPUT, might sleep */
void gpio_set_value_cansleep(unsigned gpio, int value);
Other than the fact that these calls might sleep, and will not be ignored
for GPIOs that can't be accessed from IRQ handlers, these calls act the
same as the spinlock-safe calls.
Claiming and Releasing GPIOs (OPTIONAL)
---------------------------------------
To help catch system configuration errors, two calls are defined.
However, many platforms don't currently support this mechanism.
/* request GPIO, returning 0 or negative errno.
* non-null labels may be useful for diagnostics.
*/
int gpio_request(unsigned gpio, const char *label);
/* release previously-claimed GPIO */
void gpio_free(unsigned gpio);
Passing invalid GPIO numbers to gpio_request() will fail, as will requesting
GPIOs that have already been claimed with that call. The return value of
gpio_request() must be checked. (These calls could sleep.)
These calls serve two basic purposes. One is marking the signals which
are actually in use as GPIOs, for better diagnostics; systems may have
several hundred potential GPIOs, but often only a dozen are used on any
given board. Another is to catch conflicts between drivers, reporting
errors when drivers wrongly think they have exclusive use of that signal.
These two calls are optional because not not all current Linux platforms
offer such functionality in their GPIO support; a valid implementation
could return success for all gpio_request() calls. Unlike the other calls,
the state they represent doesn't normally match anything from a hardware
register; it's just a software bitmap which clearly is not necessary for
correct operation of hardware or (bug free) drivers.
Note that requesting a GPIO does NOT cause it to be configured in any
way; it just marks that GPIO as in use. Separate code must handle any
pin setup (e.g. controlling which pin the GPIO uses, pullup/pulldown).
GPIOs mapped to IRQs
--------------------
GPIO numbers are unsigned integers; so are IRQ numbers. These make up
two logically distinct namespaces (GPIO 0 need not use IRQ 0). You can
map between them using calls like:
/* map GPIO numbers to IRQ numbers */
int gpio_to_irq(unsigned gpio);
/* map IRQ numbers to GPIO numbers */
int irq_to_gpio(unsigned irq);
Those return either the corresponding number in the other namespace, or
else a negative errno code if the mapping can't be done. (For example,
some GPIOs can't used as IRQs.) It is an unchecked error to use a GPIO
number that hasn't been marked as an input using gpio_set_direction(), or
to use an IRQ number that didn't originally come from gpio_to_irq().
These two mapping calls are expected to cost on the order of a single
addition or subtraction. They're not allowed to sleep.
Non-error values returned from gpio_to_irq() can be passed to request_irq()
or free_irq(). They will often be stored into IRQ resources for platform
devices, by the board-specific initialization code. Note that IRQ trigger
options are part of the IRQ interface, e.g. IRQF_TRIGGER_FALLING, as are
system wakeup capabilities.
Non-error values returned from irq_to_gpio() would most commonly be used
with gpio_get_value().
What do these conventions omit?
===============================
One of the biggest things these conventions omit is pin multiplexing, since
this is highly chip-specific and nonportable. One platform might not need
explicit multiplexing; another might have just two options for use of any
given pin; another might have eight options per pin; another might be able
to route a given GPIO to any one of several pins. (Yes, those examples all
come from systems that run Linux today.)
Related to multiplexing is configuration and enabling of the pullups or
pulldowns integrated on some platforms. Not all platforms support them,
or support them in the same way; and any given board might use external
pullups (or pulldowns) so that the on-chip ones should not be used.
There are other system-specific mechanisms that are not specified here,
like the aforementioned options for input de-glitching and wire-OR output.
Hardware may support reading or writing GPIOs in gangs, but that's usually
configuration dependednt: for GPIOs sharing the same bank. (GPIOs are
commonly grouped in banks of 16 or 32, with a given SOC having several such
banks.) Code relying on such mechanisms will necessarily be nonportable.
Dynamic definition of GPIOs is not currently supported; for example, as
a side effect of configuring an add-on board with some GPIO expanders.
These calls are purely for kernel space, but a userspace API could be built
on top of it.

View File

@ -94,8 +94,7 @@ Code Seq# Include File Comments
'L' 00-1F linux/loop.h
'L' E0-FF linux/ppdd.h encrypted disk device driver
<http://linux01.gwdg.de/~alatham/ppdd.html>
'M' all linux/soundcard.h conflict!
'M' 00-1F linux/isicom.h conflict!
'M' all linux/soundcard.h
'N' 00-1F drivers/usb/scanner.h
'P' all linux/soundcard.h
'Q' all linux/soundcard.h

View File

@ -8,29 +8,33 @@ GigaSet 307x Device Driver
This release supports the connection of the Gigaset 307x/417x family of
ISDN DECT bases via Gigaset M101 Data, Gigaset M105 Data or direct USB
connection. The following devices are reported to be compatible:
307x/417x:
Gigaset SX255isdn
Gigaset SX353isdn
Sinus 45 [AB] isdn (Deutsche Telekom)
Sinus 721X/XA
Bases:
Siemens Gigaset 3070/3075 isdn
Siemens Gigaset 4170/4175 isdn
Siemens Gigaset SX205/255
Siemens Gigaset SX353
T-Com Sinus 45 [AB] isdn
T-Com Sinus 721X[A] [SE]
Vox Chicago 390 ISDN (KPN Telecom)
M101:
Sinus 45 Data 1 (Telekom)
M105:
Gigaset USB Adapter DECT
Sinus 45 Data 2 (Telekom)
Sinus 721 data
RS232 data boxes:
Siemens Gigaset M101 Data
T-Com Sinus 45 Data 1
USB data boxes:
Siemens Gigaset M105 Data
Siemens Gigaset USB Adapter DECT
T-Com Sinus 45 Data 2
T-Com Sinus 721 data
Chicago 390 USB (KPN)
See also http://www.erbze.info/sinus_gigaset.htm and
http://gigaset307x.sourceforge.net/
We had also reports from users of Gigaset M105 who could use the drivers
with SX 100 and CX 100 ISDN bases (only in unimodem mode, see section 2.4.)
If you have another device that works with our driver, please let us know.
For example, Gigaset SX205isdn/Sinus 721 X SE and Gigaset SX303isdn bases
are just versions without answering machine of models known to work, so
they should work just as well; but so far we are lacking positive reports
on these.
Chances of getting an USB device to work are good if the output of
lsusb
@ -60,14 +64,28 @@ GigaSet 307x Device Driver
To get the device working, you have to load the proper kernel module. You
can do this using
modprobe modulename
where modulename is usb_gigaset (M105) or bas_gigaset (direct USB
connection to the base).
where modulename is ser_gigaset (M101), usb_gigaset (M105), or
bas_gigaset (direct USB connection to the base).
The module ser_gigaset provides a serial line discipline N_GIGASET_M101
which drives the device through the regular serial line driver. To use it,
run the Gigaset M101 daemon "gigasetm101d" (also available from
http://sourceforge.net/projects/gigaset307x/) with the device file of the
RS232 port to the M101 as an argument, for example:
gigasetm101d /dev/ttyS1
This will open the device file, set its line discipline to N_GIGASET_M101,
and then sleep in the background, keeping the device open so that the
line discipline remains active. To deactivate it, kill the daemon, for
example with
killall gigasetm101d
before disconnecting the device.
2.2. Device nodes for user space programs
------------------------------------
The device can be accessed from user space (eg. by the user space tools
mentioned in 1.2.) through the device nodes:
- /dev/ttyGS0 for M101 (RS232 data boxes)
- /dev/ttyGU0 for M105 (USB data boxes)
- /dev/ttyGB0 for the base driver (direct USB connection)
@ -168,6 +186,19 @@ GigaSet 307x Device Driver
You can also use /sys/class/tty/ttyGxy/cidmode for changing the CID mode
setting (ttyGxy is ttyGU0 or ttyGB0).
2.6. M105 Undocumented USB Requests
------------------------------
The Gigaset M105 USB data box understands a couple of useful, but
undocumented USB commands. These requests are not used in normal
operation (for wireless access to the base), but are needed for access
to the M105's own configuration mode (registration to the base, baudrate
and line format settings, device status queries) via the gigacontr
utility. Their use is disabled in the driver by default for safety
reasons but can be enabled by setting the kernel configuration option
"Support for undocumented USB requests" (GIGASET_UNDOCREQ) to "Y" and
recompiling.
3. Troubleshooting
---------------

View File

@ -311,10 +311,10 @@ Following are the arch specific command line options to be used while
loading dump-capture kernel.
For i386, x86_64 and ia64:
"init 1 irqpoll maxcpus=1"
"1 irqpoll maxcpus=1"
For ppc64:
"init 1 maxcpus=1 noirqdistrib"
"1 maxcpus=1 noirqdistrib"
Notes on loading the dump-capture kernel:
@ -332,8 +332,8 @@ Notes on loading the dump-capture kernel:
* You must specify <root-dev> in the format corresponding to the root
device name in the output of mount command.
* "init 1" boots the dump-capture kernel into single-user mode without
networking. If you want networking, use "init 3."
* Boot parameter "1" boots the dump-capture kernel into single-user
mode without networking. If you want networking, use "3".
* We generally don' have to bring up a SMP kernel just to capture the
dump. Hence generally it is useful either to build a UP dump-capture

View File

@ -101,16 +101,20 @@ The format of the block comment is like this:
/**
* function_name(:)? (- short description)?
(* @parameterx: (description of parameter x)?)*
(* @parameterx(space)*: (description of parameter x)?)*
(* a blank line)?
* (Description:)? (Description of function)?
* (section header: (section description)? )*
(*)?*/
The short function description cannot be multiline, but the other
descriptions can be (and they can contain blank lines). Avoid putting a
spurious blank line after the function name, or else the description will
be repeated!
The short function description ***cannot be multiline***, but the other
descriptions can be (and they can contain blank lines). If you continue
that initial short description onto a second line, that second line will
appear further down at the beginning of the description section, which is
almost certainly not what you had in mind.
Avoid putting a spurious blank line after the function name, or else the
description will be repeated!
All descriptive text is further processed, scanning for the following special
patterns, which are highlighted appropriately.
@ -121,6 +125,31 @@ patterns, which are highlighted appropriately.
'@parameter' - name of a parameter
'%CONST' - name of a constant.
NOTE 1: The multi-line descriptive text you provide does *not* recognize
line breaks, so if you try to format some text nicely, as in:
Return codes
0 - cool
1 - invalid arg
2 - out of memory
this will all run together and produce:
Return codes 0 - cool 1 - invalid arg 2 - out of memory
NOTE 2: If the descriptive text you provide has lines that begin with
some phrase followed by a colon, each of those phrases will be taken as
a new section heading, which means you should similarly try to avoid text
like:
Return codes:
0: cool
1: invalid arg
2: out of memory
every line of which would start a new section. Again, probably not
what you were after.
Take a look around the source tree for examples.

View File

@ -1396,6 +1396,8 @@ and is between 256 and 4096 characters. It is defined in the file
in <PAGE_SIZE> units (needed only for swap files).
See Documentation/power/swsusp-and-swap-files.txt
retain_initrd [RAM] Keep initrd memory after extraction
rhash_entries= [KNL,NET]
Set number of hash buckets for route cache

View File

@ -0,0 +1,163 @@
Semantics and Behavior of Local Atomic Operations
Mathieu Desnoyers
This document explains the purpose of the local atomic operations, how
to implement them for any given architecture and shows how they can be used
properly. It also stresses on the precautions that must be taken when reading
those local variables across CPUs when the order of memory writes matters.
* Purpose of local atomic operations
Local atomic operations are meant to provide fast and highly reentrant per CPU
counters. They minimize the performance cost of standard atomic operations by
removing the LOCK prefix and memory barriers normally required to synchronize
across CPUs.
Having fast per CPU atomic counters is interesting in many cases : it does not
require disabling interrupts to protect from interrupt handlers and it permits
coherent counters in NMI handlers. It is especially useful for tracing purposes
and for various performance monitoring counters.
Local atomic operations only guarantee variable modification atomicity wrt the
CPU which owns the data. Therefore, care must taken to make sure that only one
CPU writes to the local_t data. This is done by using per cpu data and making
sure that we modify it from within a preemption safe context. It is however
permitted to read local_t data from any CPU : it will then appear to be written
out of order wrt other memory writes on the owner CPU.
* Implementation for a given architecture
It can be done by slightly modifying the standard atomic operations : only
their UP variant must be kept. It typically means removing LOCK prefix (on
i386 and x86_64) and any SMP sychronization barrier. If the architecture does
not have a different behavior between SMP and UP, including asm-generic/local.h
in your archtecture's local.h is sufficient.
The local_t type is defined as an opaque signed long by embedding an
atomic_long_t inside a structure. This is made so a cast from this type to a
long fails. The definition looks like :
typedef struct { atomic_long_t a; } local_t;
* How to use local atomic operations
#include <linux/percpu.h>
#include <asm/local.h>
static DEFINE_PER_CPU(local_t, counters) = LOCAL_INIT(0);
* Counting
Counting is done on all the bits of a signed long.
In preemptible context, use get_cpu_var() and put_cpu_var() around local atomic
operations : it makes sure that preemption is disabled around write access to
the per cpu variable. For instance :
local_inc(&get_cpu_var(counters));
put_cpu_var(counters);
If you are already in a preemption-safe context, you can directly use
__get_cpu_var() instead.
local_inc(&__get_cpu_var(counters));
* Reading the counters
Those local counters can be read from foreign CPUs to sum the count. Note that
the data seen by local_read across CPUs must be considered to be out of order
relatively to other memory writes happening on the CPU that owns the data.
long sum = 0;
for_each_online_cpu(cpu)
sum += local_read(&per_cpu(counters, cpu));
If you want to use a remote local_read to synchronize access to a resource
between CPUs, explicit smp_wmb() and smp_rmb() memory barriers must be used
respectively on the writer and the reader CPUs. It would be the case if you use
the local_t variable as a counter of bytes written in a buffer : there should
be a smp_wmb() between the buffer write and the counter increment and also a
smp_rmb() between the counter read and the buffer read.
Here is a sample module which implements a basic per cpu counter using local.h.
--- BEGIN ---
/* test-local.c
*
* Sample module for local.h usage.
*/
#include <asm/local.h>
#include <linux/module.h>
#include <linux/timer.h>
static DEFINE_PER_CPU(local_t, counters) = LOCAL_INIT(0);
static struct timer_list test_timer;
/* IPI called on each CPU. */
static void test_each(void *info)
{
/* Increment the counter from a non preemptible context */
printk("Increment on cpu %d\n", smp_processor_id());
local_inc(&__get_cpu_var(counters));
/* This is what incrementing the variable would look like within a
* preemptible context (it disables preemption) :
*
* local_inc(&get_cpu_var(counters));
* put_cpu_var(counters);
*/
}
static void do_test_timer(unsigned long data)
{
int cpu;
/* Increment the counters */
on_each_cpu(test_each, NULL, 0, 1);
/* Read all the counters */
printk("Counters read from CPU %d\n", smp_processor_id());
for_each_online_cpu(cpu) {
printk("Read : CPU %d, count %ld\n", cpu,
local_read(&per_cpu(counters, cpu)));
}
del_timer(&test_timer);
test_timer.expires = jiffies + 1000;
add_timer(&test_timer);
}
static int __init test_init(void)
{
/* initialize the timer that will increment the counter */
init_timer(&test_timer);
test_timer.function = do_test_timer;
test_timer.expires = jiffies + 1;
add_timer(&test_timer);
return 0;
}
static void __exit test_exit(void)
{
del_timer_sync(&test_timer);
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mathieu Desnoyers");
MODULE_DESCRIPTION("Local Atomic Ops");
--- END ---

View File

@ -67,8 +67,8 @@ nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
<nfs-options> Standard NFS options. All options are separated by commas.
The following defaults are used:
port = as given by server portmap daemon
rsize = 1024
wsize = 1024
rsize = 4096
wsize = 4096
timeo = 7
retrans = 3
acregmin = 3

View File

@ -0,0 +1,192 @@
Red-black Trees (rbtree) in Linux
January 18, 2007
Rob Landley <rob@landley.net>
=============================
What are red-black trees, and what are they for?
------------------------------------------------
Red-black trees are a type of self-balancing binary search tree, used for
storing sortable key/value data pairs. This differs from radix trees (which
are used to efficiently store sparse arrays and thus use long integer indexes
to insert/access/delete nodes) and hash tables (which are not kept sorted to
be easily traversed in order, and must be tuned for a specific size and
hash function where rbtrees scale gracefully storing arbitrary keys).
Red-black trees are similar to AVL trees, but provide faster real-time bounded
worst case performance for insertion and deletion (at most two rotations and
three rotations, respectively, to balance the tree), with slightly slower
(but still O(log n)) lookup time.
To quote Linux Weekly News:
There are a number of red-black trees in use in the kernel.
The anticipatory, deadline, and CFQ I/O schedulers all employ
rbtrees to track requests; the packet CD/DVD driver does the same.
The high-resolution timer code uses an rbtree to organize outstanding
timer requests. The ext3 filesystem tracks directory entries in a
red-black tree. Virtual memory areas (VMAs) are tracked with red-black
trees, as are epoll file descriptors, cryptographic keys, and network
packets in the "hierarchical token bucket" scheduler.
This document covers use of the Linux rbtree implementation. For more
information on the nature and implementation of Red Black Trees, see:
Linux Weekly News article on red-black trees
http://lwn.net/Articles/184495/
Wikipedia entry on red-black trees
http://en.wikipedia.org/wiki/Red-black_tree
Linux implementation of red-black trees
---------------------------------------
Linux's rbtree implementation lives in the file "lib/rbtree.c". To use it,
"#include <linux/rbtree.h>".
The Linux rbtree implementation is optimized for speed, and thus has one
less layer of indirection (and better cache locality) than more traditional
tree implementations. Instead of using pointers to separate rb_node and data
structures, each instance of struct rb_node is embedded in the data structure
it organizes. And instead of using a comparison callback function pointer,
users are expected to write their own tree search and insert functions
which call the provided rbtree functions. Locking is also left up to the
user of the rbtree code.
Creating a new rbtree
---------------------
Data nodes in an rbtree tree are structures containing a struct rb_node member:
struct mytype {
struct rb_node node;
char *keystring;
};
When dealing with a pointer to the embedded struct rb_node, the containing data
structure may be accessed with the standard container_of() macro. In addition,
individual members may be accessed directly via rb_entry(node, type, member).
At the root of each rbtree is an rb_root structure, which is initialized to be
empty via:
struct rb_root mytree = RB_ROOT;
Searching for a value in an rbtree
----------------------------------
Writing a search function for your tree is fairly straightforward: start at the
root, compare each value, and follow the left or right branch as necessary.
Example:
struct mytype *my_search(struct rb_root *root, char *string)
{
struct rb_node *node = root->rb_node;
while (node) {
struct mytype *data = container_of(node, struct mytype, node);
int result;
result = strcmp(string, data->keystring);
if (result < 0)
node = node->rb_left;
else if (result > 0)
node = node->rb_right;
else
return data;
}
return NULL;
}
Inserting data into an rbtree
-----------------------------
Inserting data in the tree involves first searching for the place to insert the
new node, then inserting the node and rebalancing ("recoloring") the tree.
The search for insertion differs from the previous search by finding the
location of the pointer on which to graft the new node. The new node also
needs a link to its parent node for rebalancing purposes.
Example:
int my_insert(struct rb_root *root, struct mytype *data)
{
struct rb_node **new = &(root->rb_node), *parent = NULL;
/* Figure out where to put new node */
while (*new) {
struct mytype *this = container_of(*new, struct mytype, node);
int result = strcmp(data->keystring, this->keystring);
parent = *new;
if (result < 0)
new = &((*new)->rb_left);
else if (result > 0)
new = &((*new)->rb_right);
else
return FALSE;
}
/* Add new node and rebalance tree. */
rb_link_node(data->node, parent, new);
rb_insert_color(data->node, root);
return TRUE;
}
Removing or replacing existing data in an rbtree
------------------------------------------------
To remove an existing node from a tree, call:
void rb_erase(struct rb_node *victim, struct rb_root *tree);
Example:
struct mytype *data = mysearch(mytree, "walrus");
if (data) {
rb_erase(data->node, mytree);
myfree(data);
}
To replace an existing node in a tree with a new one with the same key, call:
void rb_replace_node(struct rb_node *old, struct rb_node *new,
struct rb_root *tree);
Replacing a node this way does not re-sort the tree: If the new node doesn't
have the same key as the old node, the rbtree will probably become corrupted.
Iterating through the elements stored in an rbtree (in sort order)
------------------------------------------------------------------
Four functions are provided for iterating through an rbtree's contents in
sorted order. These work on arbitrary trees, and should not need to be
modified or wrapped (except for locking purposes):
struct rb_node *rb_first(struct rb_root *tree);
struct rb_node *rb_last(struct rb_root *tree);
struct rb_node *rb_next(struct rb_node *node);
struct rb_node *rb_prev(struct rb_node *node);
To start iterating, call rb_first() or rb_last() with a pointer to the root
of the tree, which will return a pointer to the node structure contained in
the first or last element in the tree. To continue, fetch the next or previous
node by calling rb_next() or rb_prev() on the current node. This will return
NULL when there are no more nodes left.
The iterator functions return a pointer to the embedded struct rb_node, from
which the containing data structure may be accessed with the container_of()
macro, and individual members may be accessed directly via
rb_entry(node, type, member).
Example:
struct rb_node *node;
for (node = rb_first(&mytree); node; node = rb_next(node))
printk("key=%s\n", rb_entry(node, int, keystring));

View File

@ -149,7 +149,7 @@ RTC class framework, but can't be supported by the older driver.
is connected to an IRQ line, it can often issue an alarm IRQ up to
24 hours in the future.
* RTC_WKALM_SET, RTC_WKALM_READ ... RTCs that can issue alarms beyond
* RTC_WKALM_SET, RTC_WKALM_RD ... RTCs that can issue alarms beyond
the next 24 hours use a slightly more powerful API, which supports
setting the longer alarm time and enabling its IRQ using a single
request (using the same model as EFI firmware).
@ -167,6 +167,28 @@ Linux out of a low power sleep state (or hibernation) back to a fully
operational state. For example, a system could enter a deep power saving
state until it's time to execute some scheduled tasks.
Note that many of these ioctls need not actually be implemented by your
driver. The common rtc-dev interface handles many of these nicely if your
driver returns ENOIOCTLCMD. Some common examples:
* RTC_RD_TIME, RTC_SET_TIME: the read_time/set_time functions will be
called with appropriate values.
* RTC_ALM_SET, RTC_ALM_READ, RTC_WKALM_SET, RTC_WKALM_RD: the
set_alarm/read_alarm functions will be called. To differentiate
between the ALM and WKALM, check the larger fields of the rtc_wkalrm
struct (like tm_year). These will be set to -1 when using ALM and
will be set to proper values when using WKALM.
* RTC_IRQP_SET, RTC_IRQP_READ: the irq_set_freq function will be called
to set the frequency while the framework will handle the read for you
since the frequency is stored in the irq_freq member of the rtc_device
structure. Also make sure you set the max_user_freq member in your
initialization routines so the framework can sanity check the user
input for you.
If all else fails, check out the rtc-test.c driver!
-------------------- 8< ---------------- 8< -----------------------------
@ -237,7 +259,7 @@ int main(int argc, char **argv)
"\n...Update IRQs not supported.\n");
goto test_READ;
}
perror("ioctl");
perror("RTC_UIE_ON ioctl");
exit(errno);
}
@ -284,7 +306,7 @@ int main(int argc, char **argv)
/* Turn off update interrupts */
retval = ioctl(fd, RTC_UIE_OFF, 0);
if (retval == -1) {
perror("ioctl");
perror("RTC_UIE_OFF ioctl");
exit(errno);
}
@ -292,7 +314,7 @@ test_READ:
/* Read the RTC time/date */
retval = ioctl(fd, RTC_RD_TIME, &rtc_tm);
if (retval == -1) {
perror("ioctl");
perror("RTC_RD_TIME ioctl");
exit(errno);
}
@ -320,14 +342,14 @@ test_READ:
"\n...Alarm IRQs not supported.\n");
goto test_PIE;
}
perror("ioctl");
perror("RTC_ALM_SET ioctl");
exit(errno);
}
/* Read the current alarm settings */
retval = ioctl(fd, RTC_ALM_READ, &rtc_tm);
if (retval == -1) {
perror("ioctl");
perror("RTC_ALM_READ ioctl");
exit(errno);
}
@ -337,7 +359,7 @@ test_READ:
/* Enable alarm interrupts */
retval = ioctl(fd, RTC_AIE_ON, 0);
if (retval == -1) {
perror("ioctl");
perror("RTC_AIE_ON ioctl");
exit(errno);
}
@ -355,7 +377,7 @@ test_READ:
/* Disable alarm interrupts */
retval = ioctl(fd, RTC_AIE_OFF, 0);
if (retval == -1) {
perror("ioctl");
perror("RTC_AIE_OFF ioctl");
exit(errno);
}
@ -368,7 +390,7 @@ test_PIE:
fprintf(stderr, "\nNo periodic IRQ support\n");
return 0;
}
perror("ioctl");
perror("RTC_IRQP_READ ioctl");
exit(errno);
}
fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp);
@ -387,7 +409,7 @@ test_PIE:
"\n...Periodic IRQ rate is fixed\n");
goto done;
}
perror("ioctl");
perror("RTC_IRQP_SET ioctl");
exit(errno);
}
@ -397,7 +419,7 @@ test_PIE:
/* Enable periodic interrupts */
retval = ioctl(fd, RTC_PIE_ON, 0);
if (retval == -1) {
perror("ioctl");
perror("RTC_PIE_ON ioctl");
exit(errno);
}
@ -416,7 +438,7 @@ test_PIE:
/* Disable periodic interrupts */
retval = ioctl(fd, RTC_PIE_OFF, 0);
if (retval == -1) {
perror("ioctl");
perror("RTC_PIE_OFF ioctl");
exit(errno);
}
}

View File

@ -480,7 +480,7 @@ r2 argument 0 / return value 0 call-clobbered
r3 argument 1 / return value 1 (if long long) call-clobbered
r4 argument 2 call-clobbered
r5 argument 3 call-clobbered
r6 argument 5 saved
r6 argument 4 saved
r7 pointer-to arguments 5 to ... saved
r8 this & that saved
r9 this & that saved

View File

@ -1,3 +1,19 @@
Release Date : Thu Nov 16 15:32:35 EST 2006 -
Sumant Patro <sumant.patro@lsi.com>
Current Version : 2.20.5.1 (scsi module), 2.20.2.6 (cmm module)
Older Version : 2.20.4.9 (scsi module), 2.20.2.6 (cmm module)
1. Changes in Initialization to fix kdump failure.
Send SYNC command on loading.
This command clears the pending commands in the adapter
and re-initialize its internal RAID structure.
Without this change, megaraid driver either panics or fails to
initialize the adapter during kdump's second kernel boot
if there are pending commands or interrupts from other devices
sharing the same IRQ.
2. Authors email-id domain name changed from lsil.com to lsi.com.
Also modified the MODULE_AUTHOR to megaraidlinux@lsi.com
Release Date : Fri May 19 09:31:45 EST 2006 - Seokmann Ju <sju@lsil.com>
Current Version : 2.20.4.9 (scsi module), 2.20.2.6 (cmm module)
Older Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module)

View File

@ -242,6 +242,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ac97_clock - AC'97 clock (default = 48000)
ac97_quirk - AC'97 workaround for strange hardware
See "AC97 Quirk Option" section below.
ac97_codec - Workaround to specify which AC'97 codec
instead of probing. If this works for you
file a bug with your `lspci -vn` output.
-2 -- Force probing.
-1 -- Default behavior.
0-2 -- Use the specified codec.
spdif_aclink - S/PDIF transfer over AC-link (default = 1)
This module supports one card and autoprobe.
@ -779,6 +785,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
asus-dig ASUS with SPDIF out
asus-dig2 ASUS with SPDIF out (using GPIO2)
uniwill 3-jack
fujitsu Fujitsu Laptops (Pi1536)
F1734 2-jack
lg LG laptop (m1 express dual)
lg-lw LG LW20/LW25 laptop
@ -800,14 +807,18 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ALC262
fujitsu Fujitsu Laptop
hp-bpc HP xw4400/6400/8400/9400 laptops
hp-bpc-d7000 HP BPC D7000
benq Benq ED8
hippo Hippo (ATI) with jack detection, Sony UX-90s
hippo_1 Hippo (Benq) with jack detection
basic fixed pin assignment w/o SPDIF
auto auto-config reading BIOS (default)
ALC882/885
3stack-dig 3-jack with SPDIF I/O
6stck-dig 6-jack digital with SPDIF I/O
6stack-dig 6-jack digital with SPDIF I/O
arima Arima W820Di1
macpro MacPro support
auto auto-config reading BIOS (default)
ALC883/888
@ -817,6 +828,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
3stack-6ch-dig 3-jack 6-channel with SPDIF I/O
6stack-dig-demo 6-jack digital for Intel demo board
acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc)
medion Medion Laptops
targa-dig Targa/MSI
targa-2ch-dig Targs/MSI with 2-channel
laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE)
auto auto-config reading BIOS (default)
ALC861/660
@ -825,6 +840,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
6stack-dig 6-jack with SPDIF I/O
3stack-660 3-jack (for ALC660)
uniwill-m31 Uniwill M31 laptop
toshiba Toshiba laptop support
asus Asus laptop support
asus-laptop ASUS F2/F3 laptops
auto auto-config reading BIOS (default)
ALC861VD/660VD
3stack 3-jack
3stack-dig 3-jack with SPDIF OUT
6stack-dig 6-jack with SPDIF OUT
3stack-660 3-jack (for ALC660VD)
auto auto-config reading BIOS (default)
CMI9880
@ -845,6 +870,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
3stack 3-stack, shared surrounds
laptop 2-channel only (FSC V2060, Samsung M50)
laptop-eapd 2-channel with EAPD (Samsung R65, ASUS A6J)
ultra 2-channel with EAPD (Samsung Ultra tablet PC)
AD1988
6stack 6-jack
@ -854,12 +880,31 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
laptop 3-jack with hp-jack automute
laptop-dig ditto with SPDIF
auto auto-config reading BIOS (default)
Conexant 5045
laptop Laptop config
test for testing/debugging purpose, almost all controls
can be adjusted. Appearing only when compiled with
$CONFIG_SND_DEBUG=y
Conexant 5047
laptop Basic Laptop config
laptop-hp Laptop config for some HP models (subdevice 30A5)
laptop-eapd Laptop config with EAPD support
test for testing/debugging purpose, almost all controls
can be adjusted. Appearing only when compiled with
$CONFIG_SND_DEBUG=y
STAC9200/9205/9220/9221/9254
ref Reference board
3stack D945 3stack
5stack D945 5stack + SPDIF
STAC9202/9250/9251
ref Reference board, base config
m2-2 Some Gateway MX series laptops
m6 Some Gateway NX series laptops
STAC9227/9228/9229/927x
ref Reference board
3stack D965 3stack
@ -974,6 +1019,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards.
* MidiMan M Audio Revolution 5.1
* MidiMan M Audio Revolution 7.1
* MidiMan M Audio Audiophile 192
* AMP Ltd AUDIO2000
* TerraTec Aureon 5.1 Sky
* TerraTec Aureon 7.1 Space
@ -993,7 +1039,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
model - Use the given board model, one of the following:
revo51, revo71, amp2000, prodigy71, prodigy71lt,
prodigy192, aureon51, aureon71, universe,
prodigy192, aureon51, aureon71, universe, ap192,
k8x800, phase22, phase28, ms300, av710
This module supports multiple cards and autoprobe.
@ -1049,6 +1095,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
buggy_semaphore - Enable workaround for hardwares with buggy
semaphores (e.g. on some ASUS laptops)
(default off)
spdif_aclink - Use S/PDIF over AC-link instead of direct connection
from the controller chip
(0 = off, 1 = on, -1 = default)
This module supports one chip and autoprobe.
@ -1371,6 +1420,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
This module supports multiple cards.
Module snd-portman2x4
---------------------
Module for Midiman Portman 2x4 parallel port MIDI interface
This module supports multiple cards.
Module snd-powermac (on ppc only)
---------------------------------

View File

@ -36,7 +36,7 @@
</bookinfo>
<chapter><title>Management of Cards and Devices</title>
<sect1><title>Card Managment</title>
<sect1><title>Card Management</title>
!Esound/core/init.c
</sect1>
<sect1><title>Device Components</title>
@ -59,7 +59,7 @@
<sect1><title>PCM Format Helpers</title>
!Esound/core/pcm_misc.c
</sect1>
<sect1><title>PCM Memory Managment</title>
<sect1><title>PCM Memory Management</title>
!Esound/core/pcm_memory.c
</sect1>
</chapter>

View File

@ -1360,8 +1360,7 @@
<informalexample>
<programlisting>
<![CDATA[
static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
{
struct mychip *chip = dev_id;
....
@ -2127,7 +2126,7 @@
accessible via <constant>substream-&gt;runtime</constant>.
This runtime pointer holds the various information; it holds
the copy of hw_params and sw_params configurations, the buffer
pointers, mmap records, spinlocks, etc. Almost everyhing you
pointers, mmap records, spinlocks, etc. Almost everything you
need for controlling the PCM can be found there.
</para>
@ -2340,7 +2339,7 @@ struct _snd_pcm_runtime {
<para>
When the PCM substreams can be synchronized (typically,
synchorinized start/stop of a playback and a capture streams),
synchronized start/stop of a playback and a capture streams),
you can give <constant>SNDRV_PCM_INFO_SYNC_START</constant>,
too. In this case, you'll need to check the linked-list of
PCM substreams in the trigger callback. This will be
@ -3062,8 +3061,7 @@ struct _snd_pcm_runtime {
<title>Interrupt Handler Case #1</title>
<programlisting>
<![CDATA[
static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
{
struct mychip *chip = dev_id;
spin_lock(&chip->lock);
@ -3106,8 +3104,7 @@ struct _snd_pcm_runtime {
<title>Interrupt Handler Case #2</title>
<programlisting>
<![CDATA[
static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
{
struct mychip *chip = dev_id;
spin_lock(&chip->lock);
@ -3247,7 +3244,7 @@ struct _snd_pcm_runtime {
You can even define your own constraint rules.
For example, let's suppose my_chip can manage a substream of 1 channel
if and only if the format is S16_LE, otherwise it supports any format
specified in the <structname>snd_pcm_hardware</structname> stucture (or in any
specified in the <structname>snd_pcm_hardware</structname> structure (or in any
other constraint_list). You can build a rule like this:
<example>
@ -3690,16 +3687,6 @@ struct _snd_pcm_runtime {
</example>
</para>
<para>
Here, the chip instance is retrieved via
<function>snd_kcontrol_chip()</function> macro. This macro
just accesses to kcontrol-&gt;private_data. The
kcontrol-&gt;private_data field is
given as the argument of <function>snd_ctl_new()</function>
(see the later subsection
<link linkend="control-interface-constructor"><citetitle>Constructor</citetitle></link>).
</para>
<para>
The <structfield>value</structfield> field is depending on
the type of control as well as on info callback. For example,
@ -3780,7 +3767,7 @@ struct _snd_pcm_runtime {
<para>
Like <structfield>get</structfield> callback,
when the control has more than one elements,
all elemehts must be evaluated in this callback, too.
all elements must be evaluated in this callback, too.
</para>
</section>
@ -5541,12 +5528,12 @@ struct _snd_pcm_runtime {
#ifdef CONFIG_PM
static int snd_my_suspend(struct pci_dev *pci, pm_message_t state)
{
.... /* do things for suspsend */
.... /* do things for suspend */
return 0;
}
static int snd_my_resume(struct pci_dev *pci)
{
.... /* do things for suspsend */
.... /* do things for suspend */
return 0;
}
#endif
@ -6111,7 +6098,7 @@ struct _snd_pcm_runtime {
<!-- ****************************************************** -->
<!-- Acknowledgments -->
<!-- ****************************************************** -->
<chapter id="acknowledments">
<chapter id="acknowledgments">
<title>Acknowledgments</title>
<para>
I would like to thank Phil Kerr for his help for improvement and

View File

@ -277,11 +277,11 @@ Helper Functions
snd_hda_get_codec_name() stores the codec name on the given string.
snd_hda_check_board_config() can be used to obtain the configuration
information matching with the device. Define the table with struct
hda_board_config entries (zero-terminated), and pass it to the
function. The function checks the modelname given as a module
parameter, and PCI subsystem IDs. If the matching entry is found, it
returns the config field value.
information matching with the device. Define the model string table
and the table with struct snd_pci_quirk entries (zero-terminated),
and pass it to the function. The function checks the modelname given
as a module parameter, and PCI subsystem IDs. If the matching entry
is found, it returns the config field value.
snd_hda_add_new_ctls() can be used to create and add control entries.
Pass the zero-terminated array of struct snd_kcontrol_new. The same array

View File

@ -0,0 +1,56 @@
ASoC currently supports the three main Digital Audio Interfaces (DAI) found on
SoC controllers and portable audio CODECS today, namely AC97, I2S and PCM.
AC97
====
AC97 is a five wire interface commonly found on many PC sound cards. It is
now also popular in many portable devices. This DAI has a reset line and time
multiplexes its data on its SDATA_OUT (playback) and SDATA_IN (capture) lines.
The bit clock (BCLK) is always driven by the CODEC (usually 12.288MHz) and the
frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97
frame is 21uS long and is divided into 13 time slots.
The AC97 specification can be found at :-
http://www.intel.com/design/chipsets/audio/ac97_r23.pdf
I2S
===
I2S is a common 4 wire DAI used in HiFi, STB and portable devices. The Tx and
Rx lines are used for audio transmision, whilst the bit clock (BCLK) and
left/right clock (LRC) synchronise the link. I2S is flexible in that either the
controller or CODEC can drive (master) the BCLK and LRC clock lines. Bit clock
usually varies depending on the sample rate and the master system clock
(SYSCLK). LRCLK is the same as the sample rate. A few devices support separate
ADC and DAC LRCLK's, this allows for similtanious capture and playback at
different sample rates.
I2S has several different operating modes:-
o I2S - MSB is transmitted on the falling edge of the first BCLK after LRC
transition.
o Left Justified - MSB is transmitted on transition of LRC.
o Right Justified - MSB is transmitted sample size BCLK's before LRC
transition.
PCM
===
PCM is another 4 wire interface, very similar to I2S, that can support a more
flexible protocol. It has bit clock (BCLK) and sync (SYNC) lines that are used
to synchronise the link whilst the Tx and Rx lines are used to transmit and
receive the audio data. Bit clock usually varies depending on sample rate
whilst sync runs at the sample rate. PCM also supports Time Division
Multiplexing (TDM) in that several devices can use the bus similtaniuosly (This
is sometimes referred to as network mode).
Common PCM operating modes:-
o Mode A - MSB is transmitted on falling edge of first BCLK after FRAME/SYNC.
o Mode B - MSB is transmitted on rising edge of FRAME/SYNC.

View File

@ -0,0 +1,51 @@
Audio Clocking
==============
This text describes the audio clocking terms in ASoC and digital audio in
general. Note: Audio clocking can be complex !
Master Clock
------------
Every audio subsystem is driven by a master clock (sometimes refered to as MCLK
or SYSCLK). This audio master clock can be derived from a number of sources
(e.g. crystal, PLL, CPU clock) and is responsible for producing the correct
audio playback and capture sample rates.
Some master clocks (e.g. PLL's and CPU based clocks) are configuarble in that
their speed can be altered by software (depending on the system use and to save
power). Other master clocks are fixed at at set frequency (i.e. crystals).
DAI Clocks
----------
The Digital Audio Interface is usually driven by a Bit Clock (often referred to
as BCLK). This clock is used to drive the digital audio data across the link
between the codec and CPU.
The DAI also has a frame clock to signal the start of each audio frame. This
clock is sometimes referred to as LRC (left right clock) or FRAME. This clock
runs at exactly the sample rate (LRC = Rate).
Bit Clock can be generated as follows:-
BCLK = MCLK / x
or
BCLK = LRC * x
or
BCLK = LRC * Channels * Word Size
This relationship depends on the codec or SoC CPU in particular. In general
it's best to configure BCLK to the lowest possible speed (depending on your
rate, number of channels and wordsize) to save on power.
It's also desireable to use the codec (if possible) to drive (or master) the
audio clocks as it's usually gives more accurate sample rates than the CPU.

View File

@ -0,0 +1,197 @@
ASoC Codec Driver
=================
The codec driver is generic and hardware independent code that configures the
codec to provide audio capture and playback. It should contain no code that is
specific to the target platform or machine. All platform and machine specific
code should be added to the platform and machine drivers respectively.
Each codec driver *must* provide the following features:-
1) Codec DAI and PCM configuration
2) Codec control IO - using I2C, 3 Wire(SPI) or both API's
3) Mixers and audio controls
4) Codec audio operations
Optionally, codec drivers can also provide:-
5) DAPM description.
6) DAPM event handler.
7) DAC Digital mute control.
It's probably best to use this guide in conjuction with the existing codec
driver code in sound/soc/codecs/
ASoC Codec driver breakdown
===========================
1 - Codec DAI and PCM configuration
-----------------------------------
Each codec driver must have a struct snd_soc_codec_dai to define it's DAI and
PCM's capablities and operations. This struct is exported so that it can be
registered with the core by your machine driver.
e.g.
struct snd_soc_codec_dai wm8731_dai = {
.name = "WM8731",
/* playback capabilities */
.playback = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 2,
.rates = WM8731_RATES,
.formats = WM8731_FORMATS,},
/* capture capabilities */
.capture = {
.stream_name = "Capture",
.channels_min = 1,
.channels_max = 2,
.rates = WM8731_RATES,
.formats = WM8731_FORMATS,},
/* pcm operations - see section 4 below */
.ops = {
.prepare = wm8731_pcm_prepare,
.hw_params = wm8731_hw_params,
.shutdown = wm8731_shutdown,
},
/* DAI operations - see DAI.txt */
.dai_ops = {
.digital_mute = wm8731_mute,
.set_sysclk = wm8731_set_dai_sysclk,
.set_fmt = wm8731_set_dai_fmt,
}
};
EXPORT_SYMBOL_GPL(wm8731_dai);
2 - Codec control IO
--------------------
The codec can ususally be controlled via an I2C or SPI style interface (AC97
combines control with data in the DAI). The codec drivers will have to provide
functions to read and write the codec registers along with supplying a register
cache:-
/* IO control data and register cache */
void *control_data; /* codec control (i2c/3wire) data */
void *reg_cache;
Codec read/write should do any data formatting and call the hardware read write
below to perform the IO. These functions are called by the core and alsa when
performing DAPM or changing the mixer:-
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
Codec hardware IO functions - usually points to either the I2C, SPI or AC97
read/write:-
hw_write_t hw_write;
hw_read_t hw_read;
3 - Mixers and audio controls
-----------------------------
All the codec mixers and audio controls can be defined using the convenience
macros defined in soc.h.
#define SOC_SINGLE(xname, reg, shift, mask, invert)
Defines a single control as follows:-
xname = Control name e.g. "Playback Volume"
reg = codec register
shift = control bit(s) offset in register
mask = control bit size(s) e.g. mask of 7 = 3 bits
invert = the control is inverted
Other macros include:-
#define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert)
A stereo control
#define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert)
A stereo control spanning 2 registers
#define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts)
Defines an single enumerated control as follows:-
xreg = register
xshift = control bit(s) offset in register
xmask = control bit(s) size
xtexts = pointer to array of strings that describe each setting
#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts)
Defines a stereo enumerated control
4 - Codec Audio Operations
--------------------------
The codec driver also supports the following alsa operations:-
/* SoC audio ops */
struct snd_soc_ops {
int (*startup)(struct snd_pcm_substream *);
void (*shutdown)(struct snd_pcm_substream *);
int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *);
int (*hw_free)(struct snd_pcm_substream *);
int (*prepare)(struct snd_pcm_substream *);
};
Please refer to the alsa driver PCM documentation for details.
http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c436.htm
5 - DAPM description.
---------------------
The Dynamic Audio Power Management description describes the codec's power
components, their relationships and registers to the ASoC core. Please read
dapm.txt for details of building the description.
Please also see the examples in other codec drivers.
6 - DAPM event handler
----------------------
This function is a callback that handles codec domain PM calls and system
domain PM calls (e.g. suspend and resume). It's used to put the codec to sleep
when not in use.
Power states:-
SNDRV_CTL_POWER_D0: /* full On */
/* vref/mid, clk and osc on, active */
SNDRV_CTL_POWER_D1: /* partial On */
SNDRV_CTL_POWER_D2: /* partial On */
SNDRV_CTL_POWER_D3hot: /* Off, with power */
/* everything off except vref/vmid, inactive */
SNDRV_CTL_POWER_D3cold: /* Everything Off, without power */
7 - Codec DAC digital mute control.
------------------------------------
Most codecs have a digital mute before the DAC's that can be used to minimise
any system noise. The mute stops any digital data from entering the DAC.
A callback can be created that is called by the core for each codec DAI when the
mute is applied or freed.
i.e.
static int wm8974_mute(struct snd_soc_codec *codec,
struct snd_soc_codec_dai *dai, int mute)
{
u16 mute_reg = wm8974_read_reg_cache(codec, WM8974_DAC) & 0xffbf;
if(mute)
wm8974_write(codec, WM8974_DAC, mute_reg | 0x40);
else
wm8974_write(codec, WM8974_DAC, mute_reg);
return 0;
}

View File

@ -0,0 +1,297 @@
Dynamic Audio Power Management for Portable Devices
===================================================
1. Description
==============
Dynamic Audio Power Management (DAPM) is designed to allow portable Linux devices
to use the minimum amount of power within the audio subsystem at all times. It
is independent of other kernel PM and as such, can easily co-exist with the
other PM systems.
DAPM is also completely transparent to all user space applications as all power
switching is done within the ASoC core. No code changes or recompiling are
required for user space applications. DAPM makes power switching descisions based
upon any audio stream (capture/playback) activity and audio mixer settings
within the device.
DAPM spans the whole machine. It covers power control within the entire audio
subsystem, this includes internal codec power blocks and machine level power
systems.
There are 4 power domains within DAPM
1. Codec domain - VREF, VMID (core codec and audio power)
Usually controlled at codec probe/remove and suspend/resume, although
can be set at stream time if power is not needed for sidetone, etc.
2. Platform/Machine domain - physically connected inputs and outputs
Is platform/machine and user action specific, is configured by the
machine driver and responds to asynchronous events e.g when HP
are inserted
3. Path domain - audio susbsystem signal paths
Automatically set when mixer and mux settings are changed by the user.
e.g. alsamixer, amixer.
4. Stream domain - DAC's and ADC's.
Enabled and disabled when stream playback/capture is started and
stopped respectively. e.g. aplay, arecord.
All DAPM power switching descisons are made automatically by consulting an audio
routing map of the whole machine. This map is specific to each machine and
consists of the interconnections between every audio component (including
internal codec components). All audio components that effect power are called
widgets hereafter.
2. DAPM Widgets
===============
Audio DAPM widgets fall into a number of types:-
o Mixer - Mixes several analog signals into a single analog signal.
o Mux - An analog switch that outputs only 1 of it's inputs.
o PGA - A programmable gain amplifier or attenuation widget.
o ADC - Analog to Digital Converter
o DAC - Digital to Analog Converter
o Switch - An analog switch
o Input - A codec input pin
o Output - A codec output pin
o Headphone - Headphone (and optional Jack)
o Mic - Mic (and optional Jack)
o Line - Line Input/Output (and optional Jack)
o Speaker - Speaker
o Pre - Special PRE widget (exec before all others)
o Post - Special POST widget (exec after all others)
(Widgets are defined in include/sound/soc-dapm.h)
Widgets are usually added in the codec driver and the machine driver. There are
convience macros defined in soc-dapm.h that can be used to quickly build a
list of widgets of the codecs and machines DAPM widgets.
Most widgets have a name, register, shift and invert. Some widgets have extra
parameters for stream name and kcontrols.
2.1 Stream Domain Widgets
-------------------------
Stream Widgets relate to the stream power domain and only consist of ADC's
(analog to digital converters) and DAC's (digital to analog converters).
Stream widgets have the following format:-
SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert),
NOTE: the stream name must match the corresponding stream name in your codecs
snd_soc_codec_dai.
e.g. stream widgets for HiFi playback and capture
SND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1),
SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1),
2.2 Path Domain Widgets
-----------------------
Path domain widgets have a ability to control or effect the audio signal or
audio paths within the audio subsystem. They have the following form:-
SND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls)
Any widget kcontrols can be set using the controls and num_controls members.
e.g. Mixer widget (the kcontrols are declared first)
/* Output Mixer */
static const snd_kcontrol_new_t wm8731_output_mixer_controls[] = {
SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0),
SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0),
SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
};
SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls,
ARRAY_SIZE(wm8731_output_mixer_controls)),
2.3 Platform/Machine domain Widgets
-----------------------------------
Machine widgets are different from codec widgets in that they don't have a
codec register bit associated with them. A machine widget is assigned to each
machine audio component (non codec) that can be independently powered. e.g.
o Speaker Amp
o Microphone Bias
o Jack connectors
A machine widget can have an optional call back.
e.g. Jack connector widget for an external Mic that enables Mic Bias
when the Mic is inserted:-
static int spitz_mic_bias(struct snd_soc_dapm_widget* w, int event)
{
if(SND_SOC_DAPM_EVENT_ON(event))
set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_MIC_BIAS);
else
reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_MIC_BIAS);
return 0;
}
SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias),
2.4 Codec Domain
----------------
The Codec power domain has no widgets and is handled by the codecs DAPM event
handler. This handler is called when the codec powerstate is changed wrt to any
stream event or by kernel PM events.
2.5 Virtual Widgets
-------------------
Sometimes widgets exist in the codec or machine audio map that don't have any
corresponding register bit for power control. In this case it's necessary to
create a virtual widget - a widget with no control bits e.g.
SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0),
This can be used to merge to signal paths together in software.
After all the widgets have been defined, they can then be added to the DAPM
subsystem individually with a call to snd_soc_dapm_new_control().
3. Codec Widget Interconnections
================================
Widgets are connected to each other within the codec and machine by audio
paths (called interconnections). Each interconnection must be defined in order
to create a map of all audio paths between widgets.
This is easiest with a diagram of the codec (and schematic of the machine audio
system), as it requires joining widgets together via their audio signal paths.
i.e. from the WM8731 codec's output mixer (wm8731.c)
The WM8731 output mixer has 3 inputs (sources)
1. Line Bypass Input
2. DAC (HiFi playback)
3. Mic Sidetone Input
Each input in this example has a kcontrol associated with it (defined in example
above) and is connected to the output mixer via it's kcontrol name. We can now
connect the destination widget (wrt audio signal) with it's source widgets.
/* output mixer */
{"Output Mixer", "Line Bypass Switch", "Line Input"},
{"Output Mixer", "HiFi Playback Switch", "DAC"},
{"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
So we have :-
Destination Widget <=== Path Name <=== Source Widget
Or:-
Sink, Path, Source
Or :-
"Output Mixer" is connected to the "DAC" via the "HiFi Playback Switch".
When there is no path name connecting widgets (e.g. a direct connection) we
pass NULL for the path name.
Interconnections are created with a call to:-
snd_soc_dapm_connect_input(codec, sink, path, source);
Finally, snd_soc_dapm_new_widgets(codec) must be called after all widgets and
interconnections have been registered with the core. This causes the core to
scan the codec and machine so that the internal DAPM state matches the
physical state of the machine.
3.1 Machine Widget Interconnections
-----------------------------------
Machine widget interconnections are created in the same way as codec ones and
directly connect the codec pins to machine level widgets.
e.g. connects the speaker out codec pins to the internal speaker.
/* ext speaker connected to codec pins LOUT2, ROUT2 */
{"Ext Spk", NULL , "ROUT2"},
{"Ext Spk", NULL , "LOUT2"},
This allows the DAPM to power on and off pins that are connected (and in use)
and pins that are NC respectively.
4 Endpoint Widgets
===================
An endpoint is a start or end point (widget) of an audio signal within the
machine and includes the codec. e.g.
o Headphone Jack
o Internal Speaker
o Internal Mic
o Mic Jack
o Codec Pins
When a codec pin is NC it can be marked as not used with a call to
snd_soc_dapm_set_endpoint(codec, "Widget Name", 0);
The last argument is 0 for inactive and 1 for active. This way the pin and its
input widget will never be powered up and consume power.
This also applies to machine widgets. e.g. if a headphone is connected to a
jack then the jack can be marked active. If the headphone is removed, then
the headphone jack can be marked inactive.
5 DAPM Widget Events
====================
Some widgets can register their interest with the DAPM core in PM events.
e.g. A Speaker with an amplifier registers a widget so the amplifier can be
powered only when the spk is in use.
/* turn speaker amplifier on/off depending on use */
static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event)
{
if (SND_SOC_DAPM_EVENT_ON(event))
set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
else
reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
return 0;
}
/* corgi machine dapm widgets */
static const struct snd_soc_dapm_widget wm8731_dapm_widgets =
SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event);
Please see soc-dapm.h for all other widgets that support events.
5.1 Event types
---------------
The following event types are supported by event widgets.
/* dapm event types */
#define SND_SOC_DAPM_PRE_PMU 0x1 /* before widget power up */
#define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */
#define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */
#define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */
#define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */
#define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */

View File

@ -0,0 +1,113 @@
ASoC Machine Driver
===================
The ASoC machine (or board) driver is the code that glues together the platform
and codec drivers.
The machine driver can contain codec and platform specific code. It registers
the audio subsystem with the kernel as a platform device and is represented by
the following struct:-
/* SoC machine */
struct snd_soc_machine {
char *name;
int (*probe)(struct platform_device *pdev);
int (*remove)(struct platform_device *pdev);
/* the pre and post PM functions are used to do any PM work before and
* after the codec and DAI's do any PM work. */
int (*suspend_pre)(struct platform_device *pdev, pm_message_t state);
int (*suspend_post)(struct platform_device *pdev, pm_message_t state);
int (*resume_pre)(struct platform_device *pdev);
int (*resume_post)(struct platform_device *pdev);
/* machine stream operations */
struct snd_soc_ops *ops;
/* CPU <--> Codec DAI links */
struct snd_soc_dai_link *dai_link;
int num_links;
};
probe()/remove()
----------------
probe/remove are optional. Do any machine specific probe here.
suspend()/resume()
------------------
The machine driver has pre and post versions of suspend and resume to take care
of any machine audio tasks that have to be done before or after the codec, DAI's
and DMA is suspended and resumed. Optional.
Machine operations
------------------
The machine specific audio operations can be set here. Again this is optional.
Machine DAI Configuration
-------------------------
The machine DAI configuration glues all the codec and CPU DAI's together. It can
also be used to set up the DAI system clock and for any machine related DAI
initialisation e.g. the machine audio map can be connected to the codec audio
map, unconnnected codec pins can be set as such. Please see corgi.c, spitz.c
for examples.
struct snd_soc_dai_link is used to set up each DAI in your machine. e.g.
/* corgi digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link corgi_dai = {
.name = "WM8731",
.stream_name = "WM8731",
.cpu_dai = &pxa_i2s_dai,
.codec_dai = &wm8731_dai,
.init = corgi_wm8731_init,
.ops = &corgi_ops,
};
struct snd_soc_machine then sets up the machine with it's DAI's. e.g.
/* corgi audio machine driver */
static struct snd_soc_machine snd_soc_machine_corgi = {
.name = "Corgi",
.dai_link = &corgi_dai,
.num_links = 1,
};
Machine Audio Subsystem
-----------------------
The machine soc device glues the platform, machine and codec driver together.
Private data can also be set here. e.g.
/* corgi audio private data */
static struct wm8731_setup_data corgi_wm8731_setup = {
.i2c_address = 0x1b,
};
/* corgi audio subsystem */
static struct snd_soc_device corgi_snd_devdata = {
.machine = &snd_soc_machine_corgi,
.platform = &pxa2xx_soc_platform,
.codec_dev = &soc_codec_dev_wm8731,
.codec_data = &corgi_wm8731_setup,
};
Machine Power Map
-----------------
The machine driver can optionally extend the codec power map and to become an
audio power map of the audio subsystem. This allows for automatic power up/down
of speaker/HP amplifiers, etc. Codec pins can be connected to the machines jack
sockets in the machine init function. See soc/pxa/spitz.c and dapm.txt for
details.
Machine Controls
----------------
Machine specific audio mixer controls can be added in the dai init function.

View File

@ -0,0 +1,83 @@
ALSA SoC Layer
==============
The overall project goal of the ALSA System on Chip (ASoC) layer is to provide
better ALSA support for embedded system on chip procesors (e.g. pxa2xx, au1x00,
iMX, etc) and portable audio codecs. Currently there is some support in the
kernel for SoC audio, however it has some limitations:-
* Currently, codec drivers are often tightly coupled to the underlying SoC
cpu. This is not ideal and leads to code duplication i.e. Linux now has 4
different wm8731 drivers for 4 different SoC platforms.
* There is no standard method to signal user initiated audio events.
e.g. Headphone/Mic insertion, Headphone/Mic detection after an insertion
event. These are quite common events on portable devices and ofter require
machine specific code to re route audio, enable amps etc after such an event.
* Current drivers tend to power up the entire codec when playing
(or recording) audio. This is fine for a PC, but tends to waste a lot of
power on portable devices. There is also no support for saving power via
changing codec oversampling rates, bias currents, etc.
ASoC Design
===========
The ASoC layer is designed to address these issues and provide the following
features :-
* Codec independence. Allows reuse of codec drivers on other platforms
and machines.
* Easy I2S/PCM audio interface setup between codec and SoC. Each SoC interface
and codec registers it's audio interface capabilities with the core and are
subsequently matched and configured when the application hw params are known.
* Dynamic Audio Power Management (DAPM). DAPM automatically sets the codec to
it's minimum power state at all times. This includes powering up/down
internal power blocks depending on the internal codec audio routing and any
active streams.
* Pop and click reduction. Pops and clicks can be reduced by powering the
codec up/down in the correct sequence (including using digital mute). ASoC
signals the codec when to change power states.
* Machine specific controls: Allow machines to add controls to the sound card
e.g. volume control for speaker amp.
To achieve all this, ASoC basically splits an embedded audio system into 3
components :-
* Codec driver: The codec driver is platform independent and contains audio
controls, audio interface capabilities, codec dapm definition and codec IO
functions.
* Platform driver: The platform driver contains the audio dma engine and audio
interface drivers (e.g. I2S, AC97, PCM) for that platform.
* Machine driver: The machine driver handles any machine specific controls and
audio events. i.e. turing on an amp at start of playback.
Documentation
=============
The documentation is spilt into the following sections:-
overview.txt: This file.
codec.txt: Codec driver internals.
DAI.txt: Description of Digital Audio Interface standards and how to configure
a DAI within your codec and CPU DAI drivers.
dapm.txt: Dynamic Audio Power Management
platform.txt: Platform audio DMA and DAI.
machine.txt: Machine driver internals.
pop_clicks.txt: How to minimise audio artifacts.
clocking.txt: ASoC clocking for best power performance.

View File

@ -0,0 +1,58 @@
ASoC Platform Driver
====================
An ASoC platform driver can be divided into audio DMA and SoC DAI configuration
and control. The platform drivers only target the SoC CPU and must have no board
specific code.
Audio DMA
=========
The platform DMA driver optionally supports the following alsa operations:-
/* SoC audio ops */
struct snd_soc_ops {
int (*startup)(struct snd_pcm_substream *);
void (*shutdown)(struct snd_pcm_substream *);
int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *);
int (*hw_free)(struct snd_pcm_substream *);
int (*prepare)(struct snd_pcm_substream *);
int (*trigger)(struct snd_pcm_substream *, int);
};
The platform driver exports it's DMA functionailty via struct snd_soc_platform:-
struct snd_soc_platform {
char *name;
int (*probe)(struct platform_device *pdev);
int (*remove)(struct platform_device *pdev);
int (*suspend)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai);
int (*resume)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai);
/* pcm creation and destruction */
int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, struct snd_pcm *);
void (*pcm_free)(struct snd_pcm *);
/* platform stream ops */
struct snd_pcm_ops *pcm_ops;
};
Please refer to the alsa driver documentation for details of audio DMA.
http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c436.htm
An example DMA driver is soc/pxa/pxa2xx-pcm.c
SoC DAI Drivers
===============
Each SoC DAI driver must provide the following features:-
1) Digital audio interface (DAI) description
2) Digital audio interface configuration
3) PCM's description
4) Sysclk configuration
5) Suspend and resume (optional)
Please see codec.txt for a description of items 1 - 4.

View File

@ -0,0 +1,52 @@
Audio Pops and Clicks
=====================
Pops and clicks are unwanted audio artifacts caused by the powering up and down
of components within the audio subsystem. This is noticable on PC's when an
audio module is either loaded or unloaded (at module load time the sound card is
powered up and causes a popping noise on the speakers).
Pops and clicks can be more frequent on portable systems with DAPM. This is
because the components within the subsystem are being dynamically powered
depending on the audio usage and this can subsequently cause a small pop or
click every time a component power state is changed.
Minimising Playback Pops and Clicks
===================================
Playback pops in portable audio subsystems cannot be completely eliminated atm,
however future audio codec hardware will have better pop and click supression.
Pops can be reduced within playback by powering the audio components in a
specific order. This order is different for startup and shutdown and follows
some basic rules:-
Startup Order :- DAC --> Mixers --> Output PGA --> Digital Unmute
Shutdown Order :- Digital Mute --> Output PGA --> Mixers --> DAC
This assumes that the codec PCM output path from the DAC is via a mixer and then
a PGA (programmable gain amplifier) before being output to the speakers.
Minimising Capture Pops and Clicks
==================================
Capture artifacts are somewhat easier to get rid as we can delay activating the
ADC until all the pops have occured. This follows similar power rules to
playback in that components are powered in a sequence depending upon stream
startup or shutdown.
Startup Order - Input PGA --> Mixers --> ADC
Shutdown Order - ADC --> Mixers --> Input PGA
Zipper Noise
============
An unwanted zipper noise can occur within the audio playback or capture stream
when a volume control is changed near its maximum gain value. The zipper noise
is heard when the gain increase or decrease changes the mean audio signal
amplitude too quickly. It can be minimised by enabling the zero cross setting
for each volume control. The ZC forces the gain change to occur when the signal
crosses the zero amplitude line.

View File

@ -284,7 +284,6 @@ SPI protocol drivers somewhat resemble platform device drivers:
static struct spi_driver CHIP_driver = {
.driver = {
.name = "CHIP",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
@ -312,7 +311,7 @@ might look like this unless you're creating a class_device:
chip = kzalloc(sizeof *chip, GFP_KERNEL);
if (!chip)
return -ENOMEM;
dev_set_drvdata(&spi->dev, chip);
spi_set_drvdata(spi, chip);
... etc
return 0;

View File

@ -64,11 +64,6 @@ On all - write a character to /proc/sysrq-trigger. e.g.:
* What are the 'command' keys?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'r' - Turns off keyboard raw mode and sets it to XLATE.
'k' - Secure Access Key (SAK) Kills all programs on the current virtual
console. NOTE: See important comments below in SAK section.
'b' - Will immediately reboot the system without syncing or unmounting
your disks.
@ -76,21 +71,37 @@ On all - write a character to /proc/sysrq-trigger. e.g.:
'd' - Shows all locks that are held.
'o' - Will shut your system off (if configured and supported).
'e' - Send a SIGTERM to all processes, except for init.
's' - Will attempt to sync all mounted filesystems.
'f' - Will call oom_kill to kill a memory hog process.
'u' - Will attempt to remount all mounted filesystems read-only.
'g' - Used by kgdb on ppc platforms.
'p' - Will dump the current registers and flags to your console.
'h' - Will display help (actually any other key than those listed
above will display help. but 'h' is easy to remember :-)
't' - Will dump a list of current tasks and their information to your
console.
'i' - Send a SIGKILL to all processes, except for init.
'k' - Secure Access Key (SAK) Kills all programs on the current virtual
console. NOTE: See important comments below in SAK section.
'm' - Will dump current memory info to your console.
'n' - Used to make RT tasks nice-able
'o' - Will shut your system off (if configured and supported).
'p' - Will dump the current registers and flags to your console.
'r' - Turns off keyboard raw mode and sets it to XLATE.
's' - Will attempt to sync all mounted filesystems.
't' - Will dump a list of current tasks and their information to your
console.
'u' - Will attempt to remount all mounted filesystems read-only.
'v' - Dumps Voyager SMP processor info to your console.
'w' - Dumps tasks that are in uninterruptable (blocked) state.
@ -102,17 +113,6 @@ On all - write a character to /proc/sysrq-trigger. e.g.:
it so that only emergency messages like PANICs or OOPSes would
make it to your console.)
'f' - Will call oom_kill to kill a memory hog process.
'e' - Send a SIGTERM to all processes, except for init.
'g' - Used by kgdb on ppc platforms.
'i' - Send a SIGKILL to all processes, except for init.
'h' - Will display help (actually any other key than those listed
above will display help. but 'h' is easy to remember :-)
* Okay, so what can I use them for?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Well, un'R'aw is very handy when your X server or a svgalib program crashes.

View File

@ -213,15 +213,16 @@ C:* #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA
Interface descriptor info (can be multiple per Config):
I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss
| | | | | | | |__Driver name
| | | | | | | or "(none)"
| | | | | | |__InterfaceProtocol
| | | | | |__InterfaceSubClass
| | | | |__InterfaceClass
| | | |__NumberOfEndpoints
| | |__AlternateSettingNumber
| |__InterfaceNumber
I:* If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss
| | | | | | | | |__Driver name
| | | | | | | | or "(none)"
| | | | | | | |__InterfaceProtocol
| | | | | | |__InterfaceSubClass
| | | | | |__InterfaceClass
| | | | |__NumberOfEndpoints
| | | |__AlternateSettingNumber
| | |__InterfaceNumber
| |__ "*" indicates the active altsetting (others are " ")
|__Interface info tag
A given interface may have one or more "alternate" settings.
@ -277,7 +278,7 @@ of the USB devices on a system's root hub. (See more below
on how to do this.)
The Interface lines can be used to determine what driver is
being used for each device.
being used for each device, and which altsetting it activated.
The Configuration lines could be used to list maximum power
(in milliamps) that a system's USB devices are using.

View File

@ -77,7 +77,7 @@ that the file size is not excessive for your favourite editor.
The '1t' type data consists of a stream of events, such as URB submission,
URB callback, submission error. Every event is a text line, which consists
of whitespace separated words. The number of position of words may depend
of whitespace separated words. The number or position of words may depend
on the event type, but there is a set of words, common for all types.
Here is the list of words, from left to right:
@ -170,4 +170,152 @@ dd65f0e8 4128379808 C Bo:005:02 0 31 >
* Raw binary format and API
TBD
The overall architecture of the API is about the same as the one above,
only the events are delivered in binary format. Each event is sent in
the following structure (its name is made up, so that we can refer to it):
struct usbmon_packet {
u64 id; /* 0: URB ID - from submission to callback */
unsigned char type; /* 8: Same as text; extensible. */
unsigned char xfer_type; /* ISO (0), Intr, Control, Bulk (3) */
unsigned char epnum; /* Endpoint number and transfer direction */
unsigned char devnum; /* Device address */
u16 busnum; /* 12: Bus number */
char flag_setup; /* 14: Same as text */
char flag_data; /* 15: Same as text; Binary zero is OK. */
s64 ts_sec; /* 16: gettimeofday */
s32 ts_usec; /* 24: gettimeofday */
int status; /* 28: */
unsigned int length; /* 32: Length of data (submitted or actual) */
unsigned int len_cap; /* 36: Delivered length */
unsigned char setup[8]; /* 40: Only for Control 'S' */
}; /* 48 bytes total */
These events can be received from a character device by reading with read(2),
with an ioctl(2), or by accessing the buffer with mmap.
The character device is usually called /dev/usbmonN, where N is the USB bus
number. Number zero (/dev/usbmon0) is special and means "all buses".
However, this feature is not implemented yet. Note that specific naming
policy is set by your Linux distribution.
If you create /dev/usbmon0 by hand, make sure that it is owned by root
and has mode 0600. Otherwise, unpriviledged users will be able to snoop
keyboard traffic.
The following ioctl calls are available, with MON_IOC_MAGIC 0x92:
MON_IOCQ_URB_LEN, defined as _IO(MON_IOC_MAGIC, 1)
This call returns the length of data in the next event. Note that majority of
events contain no data, so if this call returns zero, it does not mean that
no events are available.
MON_IOCG_STATS, defined as _IOR(MON_IOC_MAGIC, 3, struct mon_bin_stats)
The argument is a pointer to the following structure:
struct mon_bin_stats {
u32 queued;
u32 dropped;
};
The member "queued" refers to the number of events currently queued in the
buffer (and not to the number of events processed since the last reset).
The member "dropped" is the number of events lost since the last call
to MON_IOCG_STATS.
MON_IOCT_RING_SIZE, defined as _IO(MON_IOC_MAGIC, 4)
This call sets the buffer size. The argument is the size in bytes.
The size may be rounded down to the next chunk (or page). If the requested
size is out of [unspecified] bounds for this kernel, the call fails with
-EINVAL.
MON_IOCQ_RING_SIZE, defined as _IO(MON_IOC_MAGIC, 5)
This call returns the current size of the buffer in bytes.
MON_IOCX_GET, defined as _IOW(MON_IOC_MAGIC, 6, struct mon_get_arg)
This call waits for events to arrive if none were in the kernel buffer,
then returns the first event. Its argument is a pointer to the following
structure:
struct mon_get_arg {
struct usbmon_packet *hdr;
void *data;
size_t alloc; /* Length of data (can be zero) */
};
Before the call, hdr, data, and alloc should be filled. Upon return, the area
pointed by hdr contains the next event structure, and the data buffer contains
the data, if any. The event is removed from the kernel buffer.
MON_IOCX_MFETCH, defined as _IOWR(MON_IOC_MAGIC, 7, struct mon_mfetch_arg)
This ioctl is primarily used when the application accesses the buffer
with mmap(2). Its argument is a pointer to the following structure:
struct mon_mfetch_arg {
uint32_t *offvec; /* Vector of events fetched */
uint32_t nfetch; /* Number of events to fetch (out: fetched) */
uint32_t nflush; /* Number of events to flush */
};
The ioctl operates in 3 stages.
First, it removes and discards up to nflush events from the kernel buffer.
The actual number of events discarded is returned in nflush.
Second, it waits for an event to be present in the buffer, unless the pseudo-
device is open with O_NONBLOCK.
Third, it extracts up to nfetch offsets into the mmap buffer, and stores
them into the offvec. The actual number of event offsets is stored into
the nfetch.
MON_IOCH_MFLUSH, defined as _IO(MON_IOC_MAGIC, 8)
This call removes a number of events from the kernel buffer. Its argument
is the number of events to remove. If the buffer contains fewer events
than requested, all events present are removed, and no error is reported.
This works when no events are available too.
FIONBIO
The ioctl FIONBIO may be implemented in the future, if there's a need.
In addition to ioctl(2) and read(2), the special file of binary API can
be polled with select(2) and poll(2). But lseek(2) does not work.
* Memory-mapped access of the kernel buffer for the binary API
The basic idea is simple:
To prepare, map the buffer by getting the current size, then using mmap(2).
Then, execute a loop similar to the one written in pseudo-code below:
struct mon_mfetch_arg fetch;
struct usbmon_packet *hdr;
int nflush = 0;
for (;;) {
fetch.offvec = vec; // Has N 32-bit words
fetch.nfetch = N; // Or less than N
fetch.nflush = nflush;
ioctl(fd, MON_IOCX_MFETCH, &fetch); // Process errors, too
nflush = fetch.nfetch; // This many packets to flush when done
for (i = 0; i < nflush; i++) {
hdr = (struct ubsmon_packet *) &mmap_area[vec[i]];
if (hdr->type == '@') // Filler packet
continue;
caddr_t data = &mmap_area[vec[i]] + 64;
process_packet(hdr, data);
}
}
Thus, the main idea is to execute only one ioctl per N events.
Although the buffer is circular, the returned headers and data do not cross
the end of the buffer, so the above pseudo-code does not need any gathering.

View File

@ -0,0 +1,34 @@
Video Output Switcher Control
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2006 luming.yu@intel.com
The output sysfs class driver provides an abstract video output layer that
can be used to hook platform specific methods to enable/disable video output
device through common sysfs interface. For example, on my IBM ThinkPad T42
laptop, The ACPI video driver registered its output devices and read/write
method for 'state' with output sysfs class. The user interface under sysfs is:
linux:/sys/class/video_output # tree .
.
|-- CRT0
| |-- device -> ../../../devices/pci0000:00/0000:00:01.0
| |-- state
| |-- subsystem -> ../../../class/video_output
| `-- uevent
|-- DVI0
| |-- device -> ../../../devices/pci0000:00/0000:00:01.0
| |-- state
| |-- subsystem -> ../../../class/video_output
| `-- uevent
|-- LCD0
| |-- device -> ../../../devices/pci0000:00/0000:00:01.0
| |-- state
| |-- subsystem -> ../../../class/video_output
| `-- uevent
`-- TV0
|-- device -> ../../../devices/pci0000:00/0000:00:01.0
|-- state
|-- subsystem -> ../../../class/video_output
`-- uevent

View File

@ -584,12 +584,30 @@ W: http://sourceforge.net/projects/acpi4asus
W: http://xf.iksaif.net/acpi4asus
S: Maintained
ASUS LAPTOP EXTRAS DRIVER
P: Corentin Chary
M: corentincj@iksaif.net
L: acpi4asus-user@lists.sourceforge.net
W: http://sourceforge.net/projects/acpi4asus
W: http://xf.iksaif.net/acpi4asus
S: Maintained
ATA OVER ETHERNET DRIVER
P: Ed L. Cashin
M: ecashin@coraid.com
W: http://www.coraid.com/support/linux
S: Supported
ATL1 ETHERNET DRIVER
P: Jay Cliburn
M: jcliburn@gmail.com
P: Chris Snook
M: csnook@redhat.com
L: atl1-devel@lists.sourceforge.net
W: http://sourceforge.net/projects/atl1
W: http://atl1.sourceforge.net
S: Maintained
ATM
P: Chas Williams
M: chas@cmf.nrl.navy.mil
@ -617,6 +635,12 @@ W: http://people.redhat.com/sgrubb/audit/
T: git kernel.org:/pub/scm/linux/kernel/git/dwmw2/audit-2.6.git
S: Maintained
AUXILIARY DISPLAY DRIVERS
P: Miguel Ojeda Sandonis
M: maxextreme@gmail.com
L: linux-kernel@vger.kernel.org
S: Maintained
AVR32 ARCHITECTURE
P: Haavard Skinnemoen
M: hskinnemoen@atmel.com
@ -818,6 +842,18 @@ L: linux-kernel@vger.kernel.org
L: discuss@x86-64.org
S: Maintained
CFAG12864B LCD DRIVER
P: Miguel Ojeda Sandonis
M: maxextreme@gmail.com
L: linux-kernel@vger.kernel.org
S: Maintained
CFAG12864BFB LCD FRAMEBUFFER DRIVER
P: Miguel Ojeda Sandonis
M: maxextreme@gmail.com
L: linux-kernel@vger.kernel.org
S: Maintained
COMMON INTERNET FILE SYSTEM (CIFS)
P: Steve French
M: sfrench@samba.org
@ -966,14 +1002,12 @@ L: cycsyn-devel@bazar.conectiva.com.br
S: Maintained
CYCLADES ASYNC MUX DRIVER
M: async@cyclades.com
W: http://www.cyclades.com/
S: Supported
S: Orphan
CYCLADES PC300 DRIVER
M: pc300@cyclades.com
W: http://www.cyclades.com/
S: Supported
S: Orphan
DAMA SLAVE for AX.25
P: Joerg Reuter
@ -1096,7 +1130,7 @@ S: Supported
DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER
P: Tobias Ringstrom
M: tori@unhappy.mine.nu
L: linux-kernel@vger.kernel.org
L: netdev@vger.kernel.org
S: Maintained
DOCBOOK FOR DOCUMENTATION
@ -1953,6 +1987,12 @@ M: davem@davemloft.net
L: linux-kernel@vger.kernel.org
S: Maintained
KS0108 LCD CONTROLLER DRIVER
P: Miguel Ojeda Sandonis
M: maxextreme@gmail.com
L: linux-kernel@vger.kernel.org
S: Maintained
LAPB module
L: linux-x25@vger.kernel.org
S: Orphan
@ -2343,7 +2383,7 @@ S: Maintained
NETWORKING [WIRELESS]
P: John W. Linville
M: linville@tuxdriver.com
L: netdev@vger.kernel.org
L: linux-wireless@vger.kernel.org
T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git
S: Maintained
@ -2477,6 +2517,12 @@ L: orinoco-devel@lists.sourceforge.net
W: http://www.nongnu.org/orinoco/
S: Maintained
PA SEMI ETHERNET DRIVER
P: Olof Johansson
M: olof@lixom.net
L: netdev@vger.kernel.org
S: Maintained
PARALLEL PORT SUPPORT
P: Phil Blundell
M: philb@gnu.org
@ -2646,7 +2692,7 @@ S: Supported
PRISM54 WIRELESS DRIVER
P: Prism54 Development Team
M: prism54-private@prism54.org
M: developers@islsm.org
L: netdev@vger.kernel.org
W: http://prism54.org
S: Maintained
@ -2791,7 +2837,7 @@ M: schwidefsky@de.ibm.com
P: Heiko Carstens
M: heiko.carstens@de.ibm.com
M: linux390@de.ibm.com
L: linux-390@vm.marist.edu
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
@ -2799,7 +2845,7 @@ S390 NETWORK DRIVERS
P: Frank Pavlic
M: fpavlic@de.ibm.com
M: linux390@de.ibm.com
L: linux-390@vm.marist.edu
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
@ -2807,7 +2853,7 @@ S390 ZFCP DRIVER
P: Swen Schillig
M: swen@vnet.ibm.com
M: linux390@de.ibm.com
L: linux-390@vm.marist.edu
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
@ -3013,6 +3059,12 @@ M: perex@suse.cz
L: alsa-devel@alsa-project.org
S: Maintained
SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT
P: Liam Girdwood
M: liam.girdwood@wolfsonmicro.com
L: alsa-devel@alsa-project.org
S: Supported
SPI SUBSYSTEM
P: David Brownell
M: dbrownell@users.sourceforge.net
@ -3263,6 +3315,11 @@ L: vtun@office.satix.net
W: http://vtun.sourceforge.net/tun
S: Maintained
TURBOCHANNEL SUBSYSTEM
P: Maciej W. Rozycki
M: macro@linux-mips.org
S: Maintained
U14-34F SCSI DRIVER
P: Dario Ballabio
M: ballabio_dario@emc.com
@ -3647,7 +3704,7 @@ S: Maintained
W83L51xD SD/MMC CARD INTERFACE DRIVER
P: Pierre Ossman
M: drzeus-wbsd@drzeus.cx
L: wbsd-devel@list.drzeus.cx
L: linux-kernel@vger.kernel.org
W: http://projects.drzeus.cx/wbsd
S: Maintained

View File

@ -776,7 +776,7 @@ $(vmlinux-dirs): prepare scripts
# $(EXTRAVERSION) eg, -rc6
# $(localver-full)
# $(localver)
# localversion* (all localversion* files)
# localversion* (files without backups, containing '~')
# $(CONFIG_LOCALVERSION) (from kernel config setting)
# $(localver-auto) (only if CONFIG_LOCALVERSION_AUTO is set)
# ./scripts/setlocalversion (SCM tag, if one exists)
@ -787,17 +787,12 @@ $(vmlinux-dirs): prepare scripts
# moment, only git is supported but other SCMs can edit the script
# scripts/setlocalversion and add the appropriate checks as needed.
nullstring :=
space := $(nullstring) # end of line
pattern = ".*/localversion[^~]*"
string = $(shell cat /dev/null \
`find $(objtree) $(srctree) -maxdepth 1 -regex $(pattern) | sort -u`)
___localver = $(objtree)/localversion* $(srctree)/localversion*
__localver = $(sort $(wildcard $(___localver)))
# skip backup files (containing '~')
_localver = $(foreach f, $(__localver), $(if $(findstring ~, $(f)),,$(f)))
localver = $(subst $(space),, \
$(shell cat /dev/null $(_localver)) \
$(patsubst "%",%,$(CONFIG_LOCALVERSION)))
localver = $(subst $(space),, $(string) \
$(patsubst "%",%,$(CONFIG_LOCALVERSION)))
# If CONFIG_LOCALVERSION_AUTO is set scripts/setlocalversion is called
# and if the SCM is know a tag from the SCM is appended.

View File

@ -41,6 +41,10 @@ config GENERIC_CALIBRATE_DELAY
bool
default y
config ZONE_DMA
bool
default y
config GENERIC_ISA_DMA
bool
default y

View File

@ -575,3 +575,7 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
EXPORT_SYMBOL(pci_iomap);
EXPORT_SYMBOL(pci_iounmap);
/* FIXME: Some boxes have multiple ISA bridges! */
struct pci_dev *isa_bridge;
EXPORT_SYMBOL(isa_bridge);

View File

@ -122,7 +122,7 @@ static void get_sysnames(unsigned long, unsigned long, unsigned long,
char **, char **);
static void determine_cpu_caches (unsigned int);
static char command_line[COMMAND_LINE_SIZE];
static char __initdata command_line[COMMAND_LINE_SIZE];
/*
* The format of "screen_info" is strange, and due to early
@ -547,7 +547,7 @@ setup_arch(char **cmdline_p)
} else {
strlcpy(command_line, COMMAND_LINE, sizeof command_line);
}
strcpy(saved_command_line, command_line);
strcpy(boot_command_line, command_line);
*cmdline_p = command_line;
/*
@ -589,7 +589,7 @@ setup_arch(char **cmdline_p)
}
/* Replace the command line, now that we've killed it with strsep. */
strcpy(command_line, saved_command_line);
strcpy(command_line, boot_command_line);
/* If we want SRM console printk echoing early, do it now. */
if (alpha_using_srm && srmcons_output) {

View File

@ -90,17 +90,6 @@ static inline __u32 rpcc(void)
return result;
}
/*
* Scheduler clock - returns current time in nanosec units.
*
* Copied from ARM code for expediency... ;-}
*/
unsigned long long sched_clock(void)
{
return (unsigned long long)jiffies * (1000000000 / HZ);
}
/*
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick

View File

@ -52,10 +52,12 @@ SECTIONS
}
__initcall_end = .;
#ifdef CONFIG_BLK_DEV_INITRD
. = ALIGN(8192);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
__initramfs_end = .;
#endif
. = ALIGN(8);
.con_initcall.init : {

View File

@ -9,6 +9,7 @@ config ARM
bool
default y
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
@ -17,6 +18,9 @@ config ARM
Europe. There is an ARM Linux project with a web page at
<http://www.arm.linux.org.uk/>.
config SYS_SUPPORTS_APM_EMULATION
bool
config GENERIC_TIME
bool
default n
@ -25,6 +29,10 @@ config MMU
bool
default y
config NO_IOPORT
bool
default n
config EISA
bool
---help---
@ -96,6 +104,10 @@ config GENERIC_BUST_SPINLOCK
config ARCH_MAY_HAVE_PC_FDC
bool
config ZONE_DMA
bool
default y
config GENERIC_ISA_DMA
bool
@ -290,6 +302,7 @@ config ARCH_RPC
select TIMER_ACORN
select ARCH_MAY_HAVE_PC_FDC
select ISA_DMA_API
select NO_IOPORT
help
On the Acorn Risc-PC, Linux can support the internal IDE disk and
CD-ROM interface, serial and parallel port, and the floppy drive.
@ -856,31 +869,6 @@ menu "Power management options"
source "kernel/power/Kconfig"
config APM
tristate "Advanced Power Management Emulation"
---help---
APM is a BIOS specification for saving power using several different
techniques. This is mostly useful for battery powered laptops with
APM compliant BIOSes. If you say Y here, the system time will be
reset after a RESUME operation, the /proc/apm device will provide
battery status information, and user-space programs will receive
notification of APM "events" (e.g. battery status change).
In order to use APM, you will need supporting software. For location
and more information, read <file:Documentation/pm.txt> and the
Battery Powered Linux mini-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.
This driver does not spin down disk drives (see the hdparm(8)
manpage ("man 8 hdparm") for that), and it doesn't turn off
VESA-compliant "green" monitors.
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
random kernel OOPSes or reboots that don't seem to be related to
anything, try disabling/enabling this option (or disabling/enabling
APM in your BIOS).
endmenu
source "net/Kconfig"

View File

@ -329,7 +329,7 @@ static int rtc_fasync(int fd, struct file *file, int on)
return fasync_helper(fd, file, on, &rtc_async_queue);
}
static struct file_operations rtc_fops = {
static const struct file_operations rtc_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = rtc_read,

View File

@ -27,7 +27,7 @@
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/apm.h>
#include <asm/apm-emulation.h>
#include <asm/arch/pm.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/sharpsl.h>

View File

@ -10,7 +10,6 @@ obj-y := compat.o entry-armv.o entry-common.o irq.o \
process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
time.o traps.o
obj-$(CONFIG_APM) += apm.o
obj-$(CONFIG_ISA_DMA_API) += dma.o
obj-$(CONFIG_ARCH_ACORN) += ecard.o
obj-$(CONFIG_FIQ) += fiq.o

View File

@ -106,7 +106,7 @@ unsigned long phys_initrd_size __initdata = 0;
static struct meminfo meminfo __initdata = { 0, };
static const char *cpu_name;
static const char *machine_name;
static char command_line[COMMAND_LINE_SIZE];
static char __initdata command_line[COMMAND_LINE_SIZE];
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
@ -803,8 +803,8 @@ void __init setup_arch(char **cmdline_p)
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;
memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
parse_cmdline(cmdline_p, from);
paging_init(&meminfo, mdesc);
request_standard_resources(&meminfo, mdesc);

View File

@ -77,16 +77,6 @@ static unsigned long dummy_gettimeoffset(void)
}
#endif
/*
* Scheduler clock - returns current time in nanosec units.
* This is the default implementation. Sub-architecture
* implementations can override this.
*/
unsigned long long __attribute__((weak)) sched_clock(void)
{
return (unsigned long long)jiffies * (1000000000 / HZ);
}
/*
* An implementation of printk_clock() independent from
* sched_clock(). This avoids non-bootable kernels when

View File

@ -53,10 +53,12 @@ SECTIONS
__security_initcall_start = .;
*(.security_initcall.init)
__security_initcall_end = .;
#ifdef CONFIG_BLK_DEV_INITRD
. = ALIGN(32);
__initramfs_start = .;
usr/built-in.o(.init.ramfs)
__initramfs_end = .;
#endif
. = ALIGN(64);
__per_cpu_start = .;
*(.data.percpu)

View File

@ -407,7 +407,7 @@ static int at91_clk_open(struct inode *inode, struct file *file)
return single_open(file, at91_clk_show, NULL);
}
static struct file_operations at91_clk_operations = {
static const struct file_operations at91_clk_operations = {
.open = at91_clk_open,
.read = seq_read,
.llseek = seq_lseek,

View File

@ -64,6 +64,24 @@ static inline unsigned pin_to_mask(unsigned pin)
*/
/*
* mux the pin to the "GPIO" peripheral role.
*/
int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup)
{
void __iomem *pio = pin_to_controller(pin);
unsigned mask = pin_to_mask(pin);
if (!pio)
return -EINVAL;
__raw_writel(mask, pio + PIO_IDR);
__raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
__raw_writel(mask, pio + PIO_PER);
return 0;
}
EXPORT_SYMBOL(at91_set_GPIO_periph);
/*
* mux the pin to the "A" internal peripheral role.
*/
@ -181,6 +199,36 @@ EXPORT_SYMBOL(at91_set_multi_drive);
/*--------------------------------------------------------------------------*/
/* new-style GPIO calls; these expect at91_set_GPIO_periph to have been
* called, and maybe at91_set_multi_drive() for putout pins.
*/
int gpio_direction_input(unsigned pin)
{
void __iomem *pio = pin_to_controller(pin);
unsigned mask = pin_to_mask(pin);
if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
return -EINVAL;
__raw_writel(mask, pio + PIO_OER);
return 0;
}
EXPORT_SYMBOL(gpio_direction_input);
int gpio_direction_output(unsigned pin)
{
void __iomem *pio = pin_to_controller(pin);
unsigned mask = pin_to_mask(pin);
if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
return -EINVAL;
__raw_writel(mask, pio + PIO_OER);
return 0;
}
EXPORT_SYMBOL(gpio_direction_output);
/*--------------------------------------------------------------------------*/
/*
* assuming the pin is muxed as a gpio output, set its value.
*/

View File

@ -16,7 +16,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <asm/apm.h>
#include <asm/apm-emulation.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>

View File

@ -23,7 +23,7 @@
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/apm.h>
#include <asm/apm-emulation.h>
#include <asm/arch/pm.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/sharpsl.h>

View File

@ -16,7 +16,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <asm/apm.h>
#include <asm/apm-emulation.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>

View File

@ -60,6 +60,10 @@ config GENERIC_CALIBRATE_DELAY
config GENERIC_BUST_SPINLOCK
bool
config ZONE_DMA
bool
default y
config GENERIC_ISA_DMA
bool

View File

@ -665,7 +665,7 @@ ecard_probe(int slot, card_type_t type)
ec->fiqmask = 4;
}
for (i = 0; i < sizeof(blacklist) / sizeof(*blacklist); i++)
for (i = 0; i < ARRAY_SIZE(blacklist); i++)
if (blacklist[i].manufacturer == ec->cid.manufacturer &&
blacklist[i].product == ec->cid.product) {
ec->card_desc = blacklist[i].type;

View File

@ -80,7 +80,7 @@ unsigned long phys_initrd_size __initdata = 0;
static struct meminfo meminfo __initdata = { 0, };
static struct proc_info_item proc_info;
static const char *machine_name;
static char command_line[COMMAND_LINE_SIZE];
static char __initdata command_line[COMMAND_LINE_SIZE];
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
@ -492,8 +492,8 @@ void __init setup_arch(char **cmdline_p)
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;
memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
parse_cmdline(&meminfo, cmdline_p, from);
bootmem_init(&meminfo);
paging_init(&meminfo);

View File

@ -89,14 +89,6 @@ static unsigned long gettimeoffset(void)
return (offset + LATCH/2) / LATCH;
}
/*
* Scheduler clock - returns current time in nanosec units.
*/
unsigned long long sched_clock(void)
{
return (unsigned long long)jiffies * (1000000000 / HZ);
}
static unsigned long next_rtc_update;
/*

View File

@ -46,10 +46,12 @@ SECTIONS
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
#ifdef CONFIG_BLK_DEV_INITRD
. = ALIGN(32);
__initramfs_start = .;
usr/built-in.o(.init.ramfs)
__initramfs_end = .;
#endif
. = ALIGN(32768);
__init_end = .;
}

View File

@ -47,10 +47,12 @@ SECTIONS
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
#ifdef CONFIG_BLK_DEV_INITRD
. = ALIGN(32);
__initramfs_start = .;
usr/built-in.o(.init.ramfs)
__initramfs_end = .;
#endif
. = ALIGN(32768);
__init_end = .;
}

View File

@ -1,2 +1,2 @@
obj-y += setup.o spi.o flash.o
obj-y += setup.o flash.o
obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o

View File

@ -8,17 +8,24 @@
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/spi/spi.h>
#include <asm/io.h>
#include <asm/setup.h>
#include <asm/arch/at32ap7000.h>
#include <asm/arch/board.h>
#include <asm/arch/init.h>
#include <asm/arch/portmux.h>
#define SW2_DEFAULT /* MMCI and UART_A available */
struct eth_addr {
u8 addr[6];
@ -29,6 +36,16 @@ static struct eth_addr __initdata hw_addr[2];
static struct eth_platform_data __initdata eth_data[2];
extern struct lcdc_platform_data atstk1000_fb0_data;
static struct spi_board_info spi_board_info[] __initdata = {
{
.modalias = "ltv350qv",
.controller_data = (void *)GPIO_PIN_PA(4),
.max_speed_hz = 16000000,
.bus_num = 0,
.chip_select = 1,
},
};
/*
* The next two functions should go away as the boot loader is
* supposed to initialize the macb address registers with a valid
@ -86,23 +103,53 @@ static void __init set_hw_addr(struct platform_device *pdev)
void __init setup_board(void)
{
at32_map_usart(1, 0); /* /dev/ttyS0 */
at32_map_usart(2, 1); /* /dev/ttyS1 */
at32_map_usart(3, 2); /* /dev/ttyS2 */
#ifdef SW2_DEFAULT
at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */
#else
at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */
#endif
/* USART 2/unused: expansion connector */
at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */
at32_setup_serial_console(0);
}
static int __init atstk1002_init(void)
{
/*
* ATSTK1000 uses 32-bit SDRAM interface. Reserve the
* SDRAM-specific pins so that nobody messes with them.
*/
at32_reserve_pin(GPIO_PIN_PE(0)); /* DATA[16] */
at32_reserve_pin(GPIO_PIN_PE(1)); /* DATA[17] */
at32_reserve_pin(GPIO_PIN_PE(2)); /* DATA[18] */
at32_reserve_pin(GPIO_PIN_PE(3)); /* DATA[19] */
at32_reserve_pin(GPIO_PIN_PE(4)); /* DATA[20] */
at32_reserve_pin(GPIO_PIN_PE(5)); /* DATA[21] */
at32_reserve_pin(GPIO_PIN_PE(6)); /* DATA[22] */
at32_reserve_pin(GPIO_PIN_PE(7)); /* DATA[23] */
at32_reserve_pin(GPIO_PIN_PE(8)); /* DATA[24] */
at32_reserve_pin(GPIO_PIN_PE(9)); /* DATA[25] */
at32_reserve_pin(GPIO_PIN_PE(10)); /* DATA[26] */
at32_reserve_pin(GPIO_PIN_PE(11)); /* DATA[27] */
at32_reserve_pin(GPIO_PIN_PE(12)); /* DATA[28] */
at32_reserve_pin(GPIO_PIN_PE(13)); /* DATA[29] */
at32_reserve_pin(GPIO_PIN_PE(14)); /* DATA[30] */
at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */
at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */
at32_add_system_devices();
#ifdef SW2_DEFAULT
at32_add_device_usart(0);
#else
at32_add_device_usart(1);
#endif
at32_add_device_usart(2);
set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
at32_add_device_spi(0);
at32_add_device_lcdc(0, &atstk1000_fb0_data);

View File

@ -1,27 +0,0 @@
/*
* ATSTK1000 SPI devices
*
* Copyright (C) 2005 Atmel Norway
*
* 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.
*/
#include <linux/device.h>
#include <linux/spi/spi.h>
static struct spi_board_info spi_board_info[] __initdata = {
{
.modalias = "ltv350qv",
.max_speed_hz = 16000000,
.bus_num = 0,
.chip_select = 1,
},
};
static int board_init_spi(void)
{
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
return 0;
}
arch_initcall(board_init_spi);

View File

@ -9,6 +9,7 @@
#include <linux/sysdev.h>
#include <linux/seq_file.h>
#include <linux/cpu.h>
#include <linux/module.h>
#include <linux/percpu.h>
#include <linux/param.h>
#include <linux/errno.h>

View File

@ -57,6 +57,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%3d: ", i);
for_each_online_cpu(cpu)
seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-");
seq_printf(p, " %s", action->name);
for (action = action->next; action; action = action->next)
seq_printf(p, ", %s", action->name);

View File

@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/root_dev.h>
#include <linux/cpu.h>
#include <linux/kernel.h>
#include <asm/sections.h>
#include <asm/processor.h>
@ -44,7 +45,7 @@ struct avr32_cpuinfo boot_cpu_data = {
};
EXPORT_SYMBOL(boot_cpu_data);
static char command_line[COMMAND_LINE_SIZE];
static char __initdata command_line[COMMAND_LINE_SIZE];
/*
* Should be more than enough, but if you have a _really_ complex
@ -174,8 +175,7 @@ static int __init parse_tag_mem_range(struct tag *tag,
* Copy the data so the bootmem init code doesn't need to care
* about it.
*/
if (mem_range_next_free >=
(sizeof(mem_range_cache) / sizeof(mem_range_cache[0])))
if (mem_range_next_free >= ARRAY_SIZE(mem_range_cache))
panic("Physical memory map too complex!\n");
new = &mem_range_cache[mem_range_next_free++];
@ -202,7 +202,7 @@ __tagtable(ATAG_MEM, parse_tag_mem);
static int __init parse_tag_cmdline(struct tag *tag)
{
strlcpy(saved_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
strlcpy(boot_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
return 0;
}
__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
@ -294,7 +294,7 @@ void __init setup_arch (char **cmdline_p)
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;
strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE);
strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
*cmdline_p = command_line;
parse_early_param();

View File

@ -109,15 +109,6 @@ static void avr32_hpt_init(unsigned int count)
sysreg_write(COUNT, count);
}
/*
* Scheduler clock - returns current time in nanosec units.
*/
unsigned long long sched_clock(void)
{
/* There must be better ways...? */
return (unsigned long long)jiffies * (1000000000 / HZ);
}
/*
* local_timer_interrupt() does profiling and process accounting on a
* per-CPU basis.

View File

@ -46,10 +46,12 @@ SECTIONS
__security_initcall_start = .;
*(.security_initcall.init)
__security_initcall_end = .;
#ifdef CONFIG_BLK_DEV_INITRD
. = ALIGN(32);
__initramfs_start = .;
*(.init.ramfs)
__initramfs_end = .;
#endif
. = ALIGN(4096);
__init_end = .;
}

View File

@ -1,33 +0,0 @@
/* Definitions for various functions 'borrowed' from gcc-3.4.3 */
#define BITS_PER_UNIT 8
typedef int QItype __attribute__ ((mode (QI)));
typedef unsigned int UQItype __attribute__ ((mode (QI)));
typedef int HItype __attribute__ ((mode (HI)));
typedef unsigned int UHItype __attribute__ ((mode (HI)));
typedef int SItype __attribute__ ((mode (SI)));
typedef unsigned int USItype __attribute__ ((mode (SI)));
typedef int DItype __attribute__ ((mode (DI)));
typedef unsigned int UDItype __attribute__ ((mode (DI)));
typedef float SFtype __attribute__ ((mode (SF)));
typedef float DFtype __attribute__ ((mode (DF)));
typedef int word_type __attribute__ ((mode (__word__)));
#define W_TYPE_SIZE (4 * BITS_PER_UNIT)
#define Wtype SItype
#define UWtype USItype
#define HWtype SItype
#define UHWtype USItype
#define DWtype DItype
#define UDWtype UDItype
#define __NW(a,b) __ ## a ## si ## b
#define __NDW(a,b) __ ## a ## di ## b
struct DWstruct {Wtype high, low;};
typedef union
{
struct DWstruct s;
DWtype ll;
} DWunion;

View File

@ -1,98 +0,0 @@
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000
Free Software Foundation, Inc.
This definition file is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2, or (at your option) any later version.
This definition file is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Borrowed from gcc-3.4.3 */
#define __BITS4 (W_TYPE_SIZE / 4)
#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
#define count_leading_zeros(count, x) ((count) = __builtin_clz(x))
#define __udiv_qrnnd_c(q, r, n1, n0, d) \
do { \
UWtype __d1, __d0, __q1, __q0; \
UWtype __r1, __r0, __m; \
__d1 = __ll_highpart (d); \
__d0 = __ll_lowpart (d); \
\
__r1 = (n1) % __d1; \
__q1 = (n1) / __d1; \
__m = (UWtype) __q1 * __d0; \
__r1 = __r1 * __ll_B | __ll_highpart (n0); \
if (__r1 < __m) \
{ \
__q1--, __r1 += (d); \
if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
if (__r1 < __m) \
__q1--, __r1 += (d); \
} \
__r1 -= __m; \
\
__r0 = __r1 % __d1; \
__q0 = __r1 / __d1; \
__m = (UWtype) __q0 * __d0; \
__r0 = __r0 * __ll_B | __ll_lowpart (n0); \
if (__r0 < __m) \
{ \
__q0--, __r0 += (d); \
if (__r0 >= (d)) \
if (__r0 < __m) \
__q0--, __r0 += (d); \
} \
__r0 -= __m; \
\
(q) = (UWtype) __q1 * __ll_B | __q0; \
(r) = __r0; \
} while (0)
#define udiv_qrnnd __udiv_qrnnd_c
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
do { \
UWtype __x; \
__x = (al) - (bl); \
(sh) = (ah) - (bh) - (__x > (al)); \
(sl) = __x; \
} while (0)
#define umul_ppmm(w1, w0, u, v) \
do { \
UWtype __x0, __x1, __x2, __x3; \
UHWtype __ul, __vl, __uh, __vh; \
\
__ul = __ll_lowpart (u); \
__uh = __ll_highpart (u); \
__vl = __ll_lowpart (v); \
__vh = __ll_highpart (v); \
\
__x0 = (UWtype) __ul * __vl; \
__x1 = (UWtype) __ul * __vh; \
__x2 = (UWtype) __uh * __vl; \
__x3 = (UWtype) __uh * __vh; \
\
__x1 += __ll_highpart (__x0);/* this can't give carry */ \
__x1 += __x2; /* but this indeed can */ \
if (__x1 < __x2) /* did we get it? */ \
__x3 += __ll_B; /* yes, add it in the proper pos. */ \
\
(w1) = __x3 + __ll_highpart (__x1); \
(w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
} while (0)

View File

@ -1,2 +1,2 @@
obj-y += at32ap.o clock.o pio.o intc.o extint.o hsmc.o
obj-y += at32ap.o clock.o intc.o extint.o pio.o hsmc.o
obj-$(CONFIG_CPU_AT32AP7000) += at32ap7000.o

View File

@ -496,9 +496,16 @@ static struct resource pio3_resource[] = {
DEFINE_DEV(pio, 3);
DEV_CLK(mck, pio3, pba, 13);
static struct resource pio4_resource[] = {
PBMEM(0xffe03800),
IRQ(17),
};
DEFINE_DEV(pio, 4);
DEV_CLK(mck, pio4, pba, 14);
void __init at32_add_system_devices(void)
{
system_manager.eim_first_irq = NR_INTERNAL_IRQS;
system_manager.eim_first_irq = EIM_IRQ_BASE;
platform_device_register(&at32_sm_device);
platform_device_register(&at32_intc0_device);
@ -509,6 +516,7 @@ void __init at32_add_system_devices(void)
platform_device_register(&pio1_device);
platform_device_register(&pio2_device);
platform_device_register(&pio3_device);
platform_device_register(&pio4_device);
}
/* --------------------------------------------------------------------
@ -521,7 +529,7 @@ static struct atmel_uart_data atmel_usart0_data = {
};
static struct resource atmel_usart0_resource[] = {
PBMEM(0xffe00c00),
IRQ(7),
IRQ(6),
};
DEFINE_DEV_DATA(atmel_usart, 0);
DEV_CLK(usart, atmel_usart0, pba, 4);
@ -583,7 +591,7 @@ static inline void configure_usart3_pins(void)
select_peripheral(PB(17), PERIPH_B, 0); /* TXD */
}
static struct platform_device *at32_usarts[4];
static struct platform_device *__initdata at32_usarts[4];
void __init at32_map_usart(unsigned int hw_id, unsigned int line)
{
@ -728,12 +736,19 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data)
/* --------------------------------------------------------------------
* SPI
* -------------------------------------------------------------------- */
static struct resource spi0_resource[] = {
static struct resource atmel_spi0_resource[] = {
PBMEM(0xffe00000),
IRQ(3),
};
DEFINE_DEV(spi, 0);
DEV_CLK(mck, spi0, pba, 0);
DEFINE_DEV(atmel_spi, 0);
DEV_CLK(spi_clk, atmel_spi0, pba, 0);
static struct resource atmel_spi1_resource[] = {
PBMEM(0xffe00400),
IRQ(4),
};
DEFINE_DEV(atmel_spi, 1);
DEV_CLK(spi_clk, atmel_spi1, pba, 1);
struct platform_device *__init at32_add_device_spi(unsigned int id)
{
@ -741,13 +756,33 @@ struct platform_device *__init at32_add_device_spi(unsigned int id)
switch (id) {
case 0:
pdev = &spi0_device;
pdev = &atmel_spi0_device;
select_peripheral(PA(0), PERIPH_A, 0); /* MISO */
select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */
select_peripheral(PA(2), PERIPH_A, 0); /* SCK */
select_peripheral(PA(3), PERIPH_A, 0); /* NPCS0 */
select_peripheral(PA(4), PERIPH_A, 0); /* NPCS1 */
select_peripheral(PA(5), PERIPH_A, 0); /* NPCS2 */
/* NPCS[2:0] */
at32_select_gpio(GPIO_PIN_PA(3),
AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
at32_select_gpio(GPIO_PIN_PA(4),
AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
at32_select_gpio(GPIO_PIN_PA(5),
AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
break;
case 1:
pdev = &atmel_spi1_device;
select_peripheral(PB(0), PERIPH_B, 0); /* MISO */
select_peripheral(PB(1), PERIPH_B, 0); /* MOSI */
select_peripheral(PB(5), PERIPH_B, 0); /* SCK */
/* NPCS[2:0] */
at32_select_gpio(GPIO_PIN_PB(2),
AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
at32_select_gpio(GPIO_PIN_PB(3),
AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
at32_select_gpio(GPIO_PIN_PB(4),
AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
break;
default:
@ -860,6 +895,7 @@ struct clk *at32_clock_list[] = {
&pio1_mck,
&pio2_mck,
&pio3_mck,
&pio4_mck,
&atmel_usart0_usart,
&atmel_usart1_usart,
&atmel_usart2_usart,
@ -868,7 +904,8 @@ struct clk *at32_clock_list[] = {
&macb0_pclk,
&macb1_hclk,
&macb1_pclk,
&spi0_mck,
&atmel_spi0_spi_clk,
&atmel_spi1_spi_clk,
&lcdc0_hclk,
&lcdc0_pixclk,
};
@ -880,6 +917,7 @@ void __init at32_portmux_init(void)
at32_init_pio(&pio1_device);
at32_init_pio(&pio2_device);
at32_init_pio(&pio3_device);
at32_init_pio(&pio4_device);
}
void __init at32_clock_init(void)

View File

@ -55,20 +55,11 @@ static int eim_set_irq_type(unsigned int irq, unsigned int flow_type)
unsigned long flags;
int ret = 0;
flow_type &= IRQ_TYPE_SENSE_MASK;
if (flow_type == IRQ_TYPE_NONE)
flow_type = IRQ_TYPE_LEVEL_LOW;
desc = &irq_desc[irq];
desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) {
desc->status |= IRQ_LEVEL;
set_irq_handler(irq, handle_level_irq);
} else {
set_irq_handler(irq, handle_edge_irq);
}
spin_lock_irqsave(&sm->lock, flags);
mode = sm_readl(sm, EIM_MODE);
@ -97,9 +88,16 @@ static int eim_set_irq_type(unsigned int irq, unsigned int flow_type)
break;
}
sm_writel(sm, EIM_MODE, mode);
sm_writel(sm, EIM_EDGE, edge);
sm_writel(sm, EIM_LEVEL, level);
if (ret == 0) {
sm_writel(sm, EIM_MODE, mode);
sm_writel(sm, EIM_EDGE, edge);
sm_writel(sm, EIM_LEVEL, level);
if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
flow_type |= IRQ_LEVEL;
desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
desc->status |= flow_type;
}
spin_unlock_irqrestore(&sm->lock, flags);
@ -122,8 +120,6 @@ static void demux_eim_irq(unsigned int irq, struct irq_desc *desc)
unsigned long status, pending;
unsigned int i, ext_irq;
spin_lock(&sm->lock);
status = sm_readl(sm, EIM_ISR);
pending = status & sm_readl(sm, EIM_IMR);
@ -133,10 +129,11 @@ static void demux_eim_irq(unsigned int irq, struct irq_desc *desc)
ext_irq = i + sm->eim_first_irq;
ext_desc = irq_desc + ext_irq;
ext_desc->handle_irq(ext_irq, ext_desc);
if (ext_desc->status & IRQ_LEVEL)
handle_level_irq(ext_irq, ext_desc);
else
handle_edge_irq(ext_irq, ext_desc);
}
spin_unlock(&sm->lock);
}
static int __init eim_init(void)
@ -168,8 +165,9 @@ static int __init eim_init(void)
sm->eim_chip = &eim_chip;
for (i = 0; i < nr_irqs; i++) {
/* NOTE the handler we set here is ignored by the demux */
set_irq_chip_and_handler(sm->eim_first_irq + i, &eim_chip,
handle_edge_irq);
handle_level_irq);
set_irq_chip_data(sm->eim_first_irq + i, sm);
}

View File

@ -12,7 +12,9 @@
#include <linux/debugfs.h>
#include <linux/fs.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/portmux.h>
@ -26,7 +28,8 @@ struct pio_device {
const struct platform_device *pdev;
struct clk *clk;
u32 pinmux_mask;
char name[32];
u32 gpio_mask;
char name[8];
};
static struct pio_device pio_dev[MAX_NR_PIO_DEVICES];
@ -76,6 +79,9 @@ void __init at32_select_periph(unsigned int pin, unsigned int periph,
if (!(flags & AT32_GPIOF_PULLUP))
pio_writel(pio, PUDR, mask);
/* gpio_request NOT allowed */
set_bit(pin_index, &pio->gpio_mask);
return;
fail:
@ -99,19 +105,29 @@ void __init at32_select_gpio(unsigned int pin, unsigned long flags)
goto fail;
}
pio_writel(pio, PUER, mask);
if (flags & AT32_GPIOF_HIGH)
pio_writel(pio, SODR, mask);
else
pio_writel(pio, CODR, mask);
if (flags & AT32_GPIOF_OUTPUT)
if (flags & AT32_GPIOF_OUTPUT) {
if (flags & AT32_GPIOF_HIGH)
pio_writel(pio, SODR, mask);
else
pio_writel(pio, CODR, mask);
pio_writel(pio, PUDR, mask);
pio_writel(pio, OER, mask);
else
} else {
if (flags & AT32_GPIOF_PULLUP)
pio_writel(pio, PUER, mask);
else
pio_writel(pio, PUDR, mask);
if (flags & AT32_GPIOF_DEGLITCH)
pio_writel(pio, IFER, mask);
else
pio_writel(pio, IFDR, mask);
pio_writel(pio, ODR, mask);
}
pio_writel(pio, PER, mask);
if (!(flags & AT32_GPIOF_PULLUP))
pio_writel(pio, PUDR, mask);
/* gpio_request now allowed */
clear_bit(pin_index, &pio->gpio_mask);
return;
@ -119,20 +135,220 @@ fail:
dump_stack();
}
/* Reserve a pin, preventing anyone else from changing its configuration. */
void __init at32_reserve_pin(unsigned int pin)
{
struct pio_device *pio;
unsigned int pin_index = pin & 0x1f;
pio = gpio_to_pio(pin);
if (unlikely(!pio)) {
printk("pio: invalid pin %u\n", pin);
goto fail;
}
if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) {
printk("%s: pin %u is busy\n", pio->name, pin_index);
goto fail;
}
return;
fail:
dump_stack();
}
/*--------------------------------------------------------------------------*/
/* GPIO API */
int gpio_request(unsigned int gpio, const char *label)
{
struct pio_device *pio;
unsigned int pin;
pio = gpio_to_pio(gpio);
if (!pio)
return -ENODEV;
pin = gpio & 0x1f;
if (test_and_set_bit(pin, &pio->gpio_mask))
return -EBUSY;
return 0;
}
EXPORT_SYMBOL(gpio_request);
void gpio_free(unsigned int gpio)
{
struct pio_device *pio;
unsigned int pin;
pio = gpio_to_pio(gpio);
if (!pio) {
printk(KERN_ERR
"gpio: attempted to free invalid pin %u\n", gpio);
return;
}
pin = gpio & 0x1f;
if (!test_and_clear_bit(pin, &pio->gpio_mask))
printk(KERN_ERR "gpio: freeing free or non-gpio pin %s-%u\n",
pio->name, pin);
}
EXPORT_SYMBOL(gpio_free);
int gpio_direction_input(unsigned int gpio)
{
struct pio_device *pio;
unsigned int pin;
pio = gpio_to_pio(gpio);
if (!pio)
return -ENODEV;
pin = gpio & 0x1f;
pio_writel(pio, ODR, 1 << pin);
return 0;
}
EXPORT_SYMBOL(gpio_direction_input);
int gpio_direction_output(unsigned int gpio)
{
struct pio_device *pio;
unsigned int pin;
pio = gpio_to_pio(gpio);
if (!pio)
return -ENODEV;
pin = gpio & 0x1f;
pio_writel(pio, OER, 1 << pin);
return 0;
}
EXPORT_SYMBOL(gpio_direction_output);
int gpio_get_value(unsigned int gpio)
{
struct pio_device *pio = &pio_dev[gpio >> 5];
return (pio_readl(pio, PDSR) >> (gpio & 0x1f)) & 1;
}
EXPORT_SYMBOL(gpio_get_value);
void gpio_set_value(unsigned int gpio, int value)
{
struct pio_device *pio = &pio_dev[gpio >> 5];
u32 mask;
mask = 1 << (gpio & 0x1f);
if (value)
pio_writel(pio, SODR, mask);
else
pio_writel(pio, CODR, mask);
}
EXPORT_SYMBOL(gpio_set_value);
/*--------------------------------------------------------------------------*/
/* GPIO IRQ support */
static void gpio_irq_mask(unsigned irq)
{
unsigned gpio = irq_to_gpio(irq);
struct pio_device *pio = &pio_dev[gpio >> 5];
pio_writel(pio, IDR, 1 << (gpio & 0x1f));
}
static void gpio_irq_unmask(unsigned irq)
{
unsigned gpio = irq_to_gpio(irq);
struct pio_device *pio = &pio_dev[gpio >> 5];
pio_writel(pio, IER, 1 << (gpio & 0x1f));
}
static int gpio_irq_type(unsigned irq, unsigned type)
{
if (type != IRQ_TYPE_EDGE_BOTH && type != IRQ_TYPE_NONE)
return -EINVAL;
return 0;
}
static struct irq_chip gpio_irqchip = {
.name = "gpio",
.mask = gpio_irq_mask,
.unmask = gpio_irq_unmask,
.set_type = gpio_irq_type,
};
static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
struct pio_device *pio = get_irq_chip_data(irq);
unsigned gpio_irq;
gpio_irq = (unsigned) get_irq_data(irq);
for (;;) {
u32 isr;
struct irq_desc *d;
/* ack pending GPIO interrupts */
isr = pio_readl(pio, ISR) & pio_readl(pio, IMR);
if (!isr)
break;
do {
int i;
i = ffs(isr) - 1;
isr &= ~(1 << i);
i += gpio_irq;
d = &irq_desc[i];
d->handle_irq(i, d);
} while (isr);
}
}
static void __init
gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq)
{
unsigned i;
set_irq_chip_data(irq, pio);
set_irq_data(irq, (void *) gpio_irq);
for (i = 0; i < 32; i++, gpio_irq++) {
set_irq_chip_data(gpio_irq, pio);
set_irq_chip_and_handler(gpio_irq, &gpio_irqchip,
handle_simple_irq);
}
set_irq_chained_handler(irq, gpio_irq_handler);
}
/*--------------------------------------------------------------------------*/
static int __init pio_probe(struct platform_device *pdev)
{
struct pio_device *pio = NULL;
int irq = platform_get_irq(pdev, 0);
int gpio_irq_base = GPIO_IRQ_BASE + pdev->id * 32;
BUG_ON(pdev->id >= MAX_NR_PIO_DEVICES);
pio = &pio_dev[pdev->id];
BUG_ON(!pio->regs);
/* TODO: Interrupts */
gpio_irq_setup(pio, irq, gpio_irq_base);
platform_set_drvdata(pdev, pio);
printk(KERN_INFO "%s: Atmel Port Multiplexer at 0x%p (irq %d)\n",
pio->name, pio->regs, platform_get_irq(pdev, 0));
printk(KERN_DEBUG "%s: base 0x%p, irq %d chains %d..%d\n",
pio->name, pio->regs, irq, gpio_irq_base, gpio_irq_base + 31);
return 0;
}
@ -148,7 +364,7 @@ static int __init pio_init(void)
{
return platform_driver_register(&pio_driver);
}
subsys_initcall(pio_init);
postcore_initcall(pio_init);
void __init at32_init_pio(struct platform_device *pdev)
{
@ -184,6 +400,13 @@ void __init at32_init_pio(struct platform_device *pdev)
pio->pdev = pdev;
pio->regs = ioremap(regs->start, regs->end - regs->start + 1);
pio_writel(pio, ODR, ~0UL);
pio_writel(pio, PER, ~0UL);
/*
* request_gpio() is only valid for pins that have been
* explicitly configured as GPIO and not previously requested
*/
pio->gpio_mask = ~0UL;
/* start with irqs disabled and acked */
pio_writel(pio, IDR, ~0UL);
(void) pio_readl(pio, ISR);
}

View File

@ -22,18 +22,34 @@
void invalidate_dcache_region(void *start, size_t size)
{
unsigned long v, begin, end, linesz;
unsigned long v, begin, end, linesz, mask;
int flush = 0;
linesz = boot_cpu_data.dcache.linesz;
mask = linesz - 1;
//printk("invalidate dcache: %p + %u\n", start, size);
/* when first and/or last cachelines are shared, flush them
* instead of invalidating ... never discard valid data!
*/
begin = (unsigned long)start;
end = begin + size - 1;
/* You asked for it, you got it */
begin = (unsigned long)start & ~(linesz - 1);
end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
if (begin & mask) {
flush_dcache_line(start);
begin += linesz;
flush = 1;
}
if ((end & mask) != mask) {
flush_dcache_line((void *)end);
end -= linesz;
flush = 1;
}
for (v = begin; v < end; v += linesz)
/* remaining cachelines only need invalidation */
for (v = begin; v <= end; v += linesz)
invalidate_dcache_line((void *)v);
if (flush)
flush_write_buffer();
}
void clean_dcache_region(void *start, size_t size)

View File

@ -360,7 +360,7 @@ static int tlb_open(struct inode *inode, struct file *file)
return seq_open(file, &tlb_ops);
}
static struct file_operations proc_tlb_operations = {
static const struct file_operations proc_tlb_operations = {
.open = tlb_open,
.read = seq_read,
.llseek = seq_lseek,

View File

@ -9,6 +9,10 @@ config MMU
bool
default y
config ZONE_DMA
bool
default y
config RWSEM_GENERIC_SPINLOCK
bool
default y
@ -40,6 +44,9 @@ config IRQ_PER_CPU
bool
default y
config NO_IOPORT
def_bool y
config CRIS
bool
default y

View File

@ -359,8 +359,7 @@ static struct mtd_info *flash_probe(void)
* So we use the MTD concatenation layer instead of further
* complicating the probing procedure.
*/
mtd_cse = mtd_concat_create(mtds,
sizeof(mtds) / sizeof(mtds[0]),
mtd_cse = mtd_concat_create(mtds, ARRAY_SIZE(mtds),
"cse0+cse1");
#else
printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel "

View File

@ -499,7 +499,7 @@ print_rtc_status(void)
/* The various file operations we support. */
static struct file_operations rtc_fops = {
static const struct file_operations rtc_fops = {
.owner = THIS_MODULE,
.ioctl = rtc_ioctl,
};

View File

@ -172,7 +172,7 @@ static const char eeprom_name[] = "eeprom";
static struct eeprom_type eeprom;
/* This is the exported file-operations structure for this device. */
struct file_operations eeprom_fops =
const struct file_operations eeprom_fops =
{
.llseek = eeprom_lseek,
.read = eeprom_read,

View File

@ -838,7 +838,7 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
return 0;
}
struct file_operations gpio_fops = {
const struct file_operations gpio_fops = {
.owner = THIS_MODULE,
.poll = gpio_poll,
.ioctl = gpio_ioctl,

View File

@ -692,7 +692,7 @@ i2c_ioctl(struct inode *inode, struct file *file,
return 0;
}
static struct file_operations i2c_fops = {
static const struct file_operations i2c_fops = {
.owner = THIS_MODULE,
.ioctl = i2c_ioctl,
.open = i2c_open,

View File

@ -56,7 +56,7 @@ static const unsigned char days_in_month[] =
int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
static struct file_operations pcf8563_fops = {
static const struct file_operations pcf8563_fops = {
.owner = THIS_MODULE,
.ioctl = pcf8563_ioctl,
};

View File

@ -38,7 +38,6 @@ unsigned long get_ns_in_jiffie(void)
unsigned long flags;
local_irq_save(flags);
local_irq_disable();
timer_count = *R_TIMER0_DATA;
presc_count = *R_TIM_PRESC_STATUS;
/* presc_count might be wrapped */

View File

@ -42,8 +42,7 @@ flush_tlb_all(void)
* in the same 4-way entry group. details..
*/
local_save_flags(flags);
local_irq_disable();
local_irq_save(flags);
for(i = 0; i < NUM_TLB_ENTRIES; i++) {
*R_TLB_SELECT = ( IO_FIELD(R_TLB_SELECT, index, i) );
*R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
@ -78,8 +77,7 @@ flush_tlb_mm(struct mm_struct *mm)
* global pages. is it worth the extra I/O ?
*/
local_save_flags(flags);
local_irq_disable();
local_irq_save(flags);
for(i = 0; i < NUM_TLB_ENTRIES; i++) {
*R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i);
if (IO_EXTRACT(R_TLB_HI, page_id, *R_TLB_HI) == page_id) {
@ -118,8 +116,7 @@ flush_tlb_page(struct vm_area_struct *vma,
* and the virtual address requested
*/
local_save_flags(flags);
local_irq_disable();
local_irq_save(flags);
for(i = 0; i < NUM_TLB_ENTRIES; i++) {
unsigned long tlb_hi;
*R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i);

View File

@ -82,7 +82,8 @@ SECTIONS
__con_initcall_end = .;
}
SECURITY_INIT
#ifdef CONFIG_BLK_DEV_INITRD
.init.ramfs : {
__initramfs_start = .;
*(.init.ramfs)
@ -93,6 +94,7 @@ SECTIONS
FILL (0);
. = ALIGN (8192);
}
#endif
__vmlinux_end = .; /* last address of the physical file */
__init_end = .;

View File

@ -266,7 +266,7 @@ static void print_user_dma_lists(struct cryptocop_dma_list_operation *dma_op);
struct file_operations cryptocop_fops = {
const struct file_operations cryptocop_fops = {
owner: THIS_MODULE,
open: cryptocop_open,
release: cryptocop_release,

Some files were not shown because too many files have changed in this diff Show More