You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge ../bleed-2.6
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -906,9 +906,20 @@ Aside:
|
||||
|
||||
|
||||
4. The I/O scheduler
|
||||
I/O schedulers are now per queue. They should be runtime switchable and modular
|
||||
but aren't yet. Jens has most bits to do this, but the sysfs implementation is
|
||||
missing.
|
||||
I/O scheduler, a.k.a. elevator, is implemented in two layers. Generic dispatch
|
||||
queue and specific I/O schedulers. Unless stated otherwise, elevator is used
|
||||
to refer to both parts and I/O scheduler to specific I/O schedulers.
|
||||
|
||||
Block layer implements generic dispatch queue in ll_rw_blk.c and elevator.c.
|
||||
The generic dispatch queue is responsible for properly ordering barrier
|
||||
requests, requeueing, handling non-fs requests and all other subtleties.
|
||||
|
||||
Specific I/O schedulers are responsible for ordering normal filesystem
|
||||
requests. They can also choose to delay certain requests to improve
|
||||
throughput or whatever purpose. As the plural form indicates, there are
|
||||
multiple I/O schedulers. They can be built as modules but at least one should
|
||||
be built inside the kernel. Each queue can choose different one and can also
|
||||
change to another one dynamically.
|
||||
|
||||
A block layer call to the i/o scheduler follows the convention elv_xxx(). This
|
||||
calls elevator_xxx_fn in the elevator switch (drivers/block/elevator.c). Oh,
|
||||
@@ -921,44 +932,36 @@ keeping work.
|
||||
The functions an elevator may implement are: (* are mandatory)
|
||||
elevator_merge_fn called to query requests for merge with a bio
|
||||
|
||||
elevator_merge_req_fn " " " with another request
|
||||
elevator_merge_req_fn called when two requests get merged. the one
|
||||
which gets merged into the other one will be
|
||||
never seen by I/O scheduler again. IOW, after
|
||||
being merged, the request is gone.
|
||||
|
||||
elevator_merged_fn called when a request in the scheduler has been
|
||||
involved in a merge. It is used in the deadline
|
||||
scheduler for example, to reposition the request
|
||||
if its sorting order has changed.
|
||||
|
||||
*elevator_next_req_fn returns the next scheduled request, or NULL
|
||||
if there are none (or none are ready).
|
||||
elevator_dispatch_fn fills the dispatch queue with ready requests.
|
||||
I/O schedulers are free to postpone requests by
|
||||
not filling the dispatch queue unless @force
|
||||
is non-zero. Once dispatched, I/O schedulers
|
||||
are not allowed to manipulate the requests -
|
||||
they belong to generic dispatch queue.
|
||||
|
||||
*elevator_add_req_fn called to add a new request into the scheduler
|
||||
elevator_add_req_fn called to add a new request into the scheduler
|
||||
|
||||
elevator_queue_empty_fn returns true if the merge queue is empty.
|
||||
Drivers shouldn't use this, but rather check
|
||||
if elv_next_request is NULL (without losing the
|
||||
request if one exists!)
|
||||
|
||||
elevator_remove_req_fn This is called when a driver claims ownership of
|
||||
the target request - it now belongs to the
|
||||
driver. It must not be modified or merged.
|
||||
Drivers must not lose the request! A subsequent
|
||||
call of elevator_next_req_fn must return the
|
||||
_next_ request.
|
||||
|
||||
elevator_requeue_req_fn called to add a request to the scheduler. This
|
||||
is used when the request has alrnadebeen
|
||||
returned by elv_next_request, but hasn't
|
||||
completed. If this is not implemented then
|
||||
elevator_add_req_fn is called instead.
|
||||
|
||||
elevator_former_req_fn
|
||||
elevator_latter_req_fn These return the request before or after the
|
||||
one specified in disk sort order. Used by the
|
||||
block layer to find merge possibilities.
|
||||
|
||||
elevator_completed_req_fn called when a request is completed. This might
|
||||
come about due to being merged with another or
|
||||
when the device completes the request.
|
||||
elevator_completed_req_fn called when a request is completed.
|
||||
|
||||
elevator_may_queue_fn returns true if the scheduler wants to allow the
|
||||
current context to queue a new request even if
|
||||
@@ -967,13 +970,33 @@ elevator_may_queue_fn returns true if the scheduler wants to allow the
|
||||
|
||||
elevator_set_req_fn
|
||||
elevator_put_req_fn Must be used to allocate and free any elevator
|
||||
specific storate for a request.
|
||||
specific storage for a request.
|
||||
|
||||
elevator_activate_req_fn Called when device driver first sees a request.
|
||||
I/O schedulers can use this callback to
|
||||
determine when actual execution of a request
|
||||
starts.
|
||||
elevator_deactivate_req_fn Called when device driver decides to delay
|
||||
a request by requeueing it.
|
||||
|
||||
elevator_init_fn
|
||||
elevator_exit_fn Allocate and free any elevator specific storage
|
||||
for a queue.
|
||||
|
||||
4.2 I/O scheduler implementation
|
||||
4.2 Request flows seen by I/O schedulers
|
||||
All requests seens by I/O schedulers strictly follow one of the following three
|
||||
flows.
|
||||
|
||||
set_req_fn ->
|
||||
|
||||
i. add_req_fn -> (merged_fn ->)* -> dispatch_fn -> activate_req_fn ->
|
||||
(deactivate_req_fn -> activate_req_fn ->)* -> completed_req_fn
|
||||
ii. add_req_fn -> (merged_fn ->)* -> merge_req_fn
|
||||
iii. [none]
|
||||
|
||||
-> put_req_fn
|
||||
|
||||
4.3 I/O scheduler implementation
|
||||
The generic i/o scheduler algorithm attempts to sort/merge/batch requests for
|
||||
optimal disk scan and request servicing performance (based on generic
|
||||
principles and device capabilities), optimized for:
|
||||
@@ -993,18 +1016,7 @@ request in sort order to prevent binary tree lookups.
|
||||
This arrangement is not a generic block layer characteristic however, so
|
||||
elevators may implement queues as they please.
|
||||
|
||||
ii. Last merge hint
|
||||
The last merge hint is part of the generic queue layer. I/O schedulers must do
|
||||
some management on it. For the most part, the most important thing is to make
|
||||
sure q->last_merge is cleared (set to NULL) when the request on it is no longer
|
||||
a candidate for merging (for example if it has been sent to the driver).
|
||||
|
||||
The last merge performed is cached as a hint for the subsequent request. If
|
||||
sequential data is being submitted, the hint is used to perform merges without
|
||||
any scanning. This is not sufficient when there are multiple processes doing
|
||||
I/O though, so a "merge hash" is used by some schedulers.
|
||||
|
||||
iii. Merge hash
|
||||
ii. Merge hash
|
||||
AS and deadline use a hash table indexed by the last sector of a request. This
|
||||
enables merging code to quickly look up "back merge" candidates, even when
|
||||
multiple I/O streams are being performed at once on one disk.
|
||||
@@ -1013,29 +1025,8 @@ multiple I/O streams are being performed at once on one disk.
|
||||
are far less common than "back merges" due to the nature of most I/O patterns.
|
||||
Front merges are handled by the binary trees in AS and deadline schedulers.
|
||||
|
||||
iv. Handling barrier cases
|
||||
A request with flags REQ_HARDBARRIER or REQ_SOFTBARRIER must not be ordered
|
||||
around. That is, they must be processed after all older requests, and before
|
||||
any newer ones. This includes merges!
|
||||
|
||||
In AS and deadline schedulers, barriers have the effect of flushing the reorder
|
||||
queue. The performance cost of this will vary from nothing to a lot depending
|
||||
on i/o patterns and device characteristics. Obviously they won't improve
|
||||
performance, so their use should be kept to a minimum.
|
||||
|
||||
v. Handling insertion position directives
|
||||
A request may be inserted with a position directive. The directives are one of
|
||||
ELEVATOR_INSERT_BACK, ELEVATOR_INSERT_FRONT, ELEVATOR_INSERT_SORT.
|
||||
|
||||
ELEVATOR_INSERT_SORT is a general directive for non-barrier requests.
|
||||
ELEVATOR_INSERT_BACK is used to insert a barrier to the back of the queue.
|
||||
ELEVATOR_INSERT_FRONT is used to insert a barrier to the front of the queue, and
|
||||
overrides the ordering requested by any previous barriers. In practice this is
|
||||
harmless and required, because it is used for SCSI requeueing. This does not
|
||||
require flushing the reorder queue, so does not impose a performance penalty.
|
||||
|
||||
vi. Plugging the queue to batch requests in anticipation of opportunities for
|
||||
merge/sort optimizations
|
||||
iii. Plugging the queue to batch requests in anticipation of opportunities for
|
||||
merge/sort optimizations
|
||||
|
||||
This is just the same as in 2.4 so far, though per-device unplugging
|
||||
support is anticipated for 2.5. Also with a priority-based i/o scheduler,
|
||||
@@ -1069,7 +1060,7 @@ Aside:
|
||||
blk_kick_queue() to unplug a specific queue (right away ?)
|
||||
or optionally, all queues, is in the plan.
|
||||
|
||||
4.3 I/O contexts
|
||||
4.4 I/O contexts
|
||||
I/O contexts provide a dynamically allocated per process data area. They may
|
||||
be used in I/O schedulers, and in the block layer (could be used for IO statis,
|
||||
priorities for example). See *io_context in drivers/block/ll_rw_blk.c, and
|
||||
|
||||
@@ -777,7 +777,7 @@ doing so is the same as described in the "Configuring Multiple Bonds
|
||||
Manually" section, below.
|
||||
|
||||
NOTE: It has been observed that some Red Hat supplied kernels
|
||||
are apparently unable to rename modules at load time (the "-obonding1"
|
||||
are apparently unable to rename modules at load time (the "-o bond1"
|
||||
part). Attempts to pass that option to modprobe will produce an
|
||||
"Operation not permitted" error. This has been reported on some
|
||||
Fedora Core kernels, and has been seen on RHEL 4 as well. On kernels
|
||||
@@ -883,7 +883,8 @@ the above does not work, and the second bonding instance never sees
|
||||
its options. In that case, the second options line can be substituted
|
||||
as follows:
|
||||
|
||||
install bonding1 /sbin/modprobe bonding -obond1 mode=balance-alb miimon=50
|
||||
install bond1 /sbin/modprobe --ignore-install bonding -o bond1 \
|
||||
mode=balance-alb miimon=50
|
||||
|
||||
This may be repeated any number of times, specifying a new and
|
||||
unique name in place of bond1 for each subsequent instance.
|
||||
|
||||
@@ -334,7 +334,7 @@ KALLSYMS = scripts/kallsyms
|
||||
PERL = perl
|
||||
CHECK = sparse
|
||||
|
||||
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ $(CF)
|
||||
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise $(CF)
|
||||
MODFLAGS = -DMODULE
|
||||
CFLAGS_MODULE = $(MODFLAGS)
|
||||
AFLAGS_MODULE = $(MODFLAGS)
|
||||
|
||||
@@ -154,7 +154,7 @@ pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
|
||||
|
||||
void *
|
||||
dma_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, int gfp)
|
||||
dma_addr_t *dma_handle, gfp_t gfp)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
|
||||
@@ -397,7 +397,7 @@ pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
|
||||
{
|
||||
void *cpu_addr;
|
||||
long order = get_order(size);
|
||||
int gfp = GFP_ATOMIC;
|
||||
gfp_t gfp = GFP_ATOMIC;
|
||||
|
||||
try_again:
|
||||
cpu_addr = (void *)__get_free_pages(gfp, order);
|
||||
|
||||
+3
-1
@@ -204,6 +204,7 @@ config ARCH_H720X
|
||||
|
||||
config ARCH_AAEC2000
|
||||
bool "Agilent AAEC-2000 based"
|
||||
select ARM_AMBA
|
||||
help
|
||||
This enables support for systems based on the Agilent AAEC-2000
|
||||
|
||||
@@ -687,7 +688,8 @@ source "drivers/acorn/block/Kconfig"
|
||||
|
||||
if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \
|
||||
|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
|
||||
|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE
|
||||
|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
|
||||
|| MACH_MP1000
|
||||
source "drivers/ide/Kconfig"
|
||||
endif
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@
|
||||
defined(CONFIG_ARCH_IXP4XX) || \
|
||||
defined(CONFIG_ARCH_IXP2000) || \
|
||||
defined(CONFIG_ARCH_LH7A40X) || \
|
||||
defined(CONFIG_ARCH_OMAP)
|
||||
defined(CONFIG_ARCH_OMAP) || \
|
||||
defined(CONFIG_MACH_MP1000)
|
||||
.macro loadsp, rb
|
||||
addruart \rb
|
||||
.endm
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleloader.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
@@ -345,7 +345,9 @@ static int bad_syscall(int n, struct pt_regs *regs)
|
||||
struct thread_info *thread = current_thread_info();
|
||||
siginfo_t info;
|
||||
|
||||
if (current->personality != PER_LINUX && thread->exec_domain->handler) {
|
||||
if (current->personality != PER_LINUX &&
|
||||
current->personality != PER_LINUX_32BIT &&
|
||||
thread->exec_domain->handler) {
|
||||
thread->exec_domain->handler(n, regs);
|
||||
return regs->ARM_r0;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
|
||||
strnlen_user.o strchr.o strrchr.o testchangebit.o \
|
||||
testclearbit.o testsetbit.o uaccess.o getuser.o \
|
||||
putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
|
||||
ucmpdi2.o lib1funcs.o div64.o \
|
||||
ucmpdi2.o lib1funcs.o div64.o sha1.o \
|
||||
io-readsb.o io-writesb.o io-readsl.o io-writesl.o
|
||||
|
||||
ifeq ($(CONFIG_CPU_32v3),y)
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* linux/arch/arm/lib/sha1.S
|
||||
*
|
||||
* SHA transform optimized for ARM
|
||||
*
|
||||
* Copyright: (C) 2005 by Nicolas Pitre <nico@cam.org>
|
||||
* Created: September 17, 2005
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* The reference implementation for this code is linux/lib/sha1.c
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
.text
|
||||
|
||||
|
||||
/*
|
||||
* void sha_transform(__u32 *digest, const char *in, __u32 *W)
|
||||
*
|
||||
* Note: the "in" ptr may be unaligned.
|
||||
*/
|
||||
|
||||
ENTRY(sha_transform)
|
||||
|
||||
stmfd sp!, {r4 - r8, lr}
|
||||
|
||||
@ for (i = 0; i < 16; i++)
|
||||
@ W[i] = be32_to_cpu(in[i]); */
|
||||
|
||||
#ifdef __ARMEB__
|
||||
mov r4, r0
|
||||
mov r0, r2
|
||||
mov r2, #64
|
||||
bl memcpy
|
||||
mov r2, r0
|
||||
mov r0, r4
|
||||
#else
|
||||
mov r3, r2
|
||||
mov lr, #16
|
||||
1: ldrb r4, [r1], #1
|
||||
ldrb r5, [r1], #1
|
||||
ldrb r6, [r1], #1
|
||||
ldrb r7, [r1], #1
|
||||
subs lr, lr, #1
|
||||
orr r5, r5, r4, lsl #8
|
||||
orr r6, r6, r5, lsl #8
|
||||
orr r7, r7, r6, lsl #8
|
||||
str r7, [r3], #4
|
||||
bne 1b
|
||||
#endif
|
||||
|
||||
@ for (i = 0; i < 64; i++)
|
||||
@ W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31);
|
||||
|
||||
sub r3, r2, #4
|
||||
mov lr, #64
|
||||
2: ldr r4, [r3, #4]!
|
||||
subs lr, lr, #1
|
||||
ldr r5, [r3, #8]
|
||||
ldr r6, [r3, #32]
|
||||
ldr r7, [r3, #52]
|
||||
eor r4, r4, r5
|
||||
eor r4, r4, r6
|
||||
eor r4, r4, r7
|
||||
mov r4, r4, ror #31
|
||||
str r4, [r3, #64]
|
||||
bne 2b
|
||||
|
||||
/*
|
||||
* The SHA functions are:
|
||||
*
|
||||
* f1(B,C,D) = (D ^ (B & (C ^ D)))
|
||||
* f2(B,C,D) = (B ^ C ^ D)
|
||||
* f3(B,C,D) = ((B & C) | (D & (B | C)))
|
||||
*
|
||||
* Then the sub-blocks are processed as follows:
|
||||
*
|
||||
* A' = ror(A, 27) + f(B,C,D) + E + K + *W++
|
||||
* B' = A
|
||||
* C' = ror(B, 2)
|
||||
* D' = C
|
||||
* E' = D
|
||||
*
|
||||
* We therefore unroll each loop 5 times to avoid register shuffling.
|
||||
* Also the ror for C (and also D and E which are successivelyderived
|
||||
* from it) is applied in place to cut on an additional mov insn for
|
||||
* each round.
|
||||
*/
|
||||
|
||||
.macro sha_f1, A, B, C, D, E
|
||||
ldr r3, [r2], #4
|
||||
eor ip, \C, \D
|
||||
add \E, r1, \E, ror #2
|
||||
and ip, \B, ip, ror #2
|
||||
add \E, \E, \A, ror #27
|
||||
eor ip, ip, \D, ror #2
|
||||
add \E, \E, r3
|
||||
add \E, \E, ip
|
||||
.endm
|
||||
|
||||
.macro sha_f2, A, B, C, D, E
|
||||
ldr r3, [r2], #4
|
||||
add \E, r1, \E, ror #2
|
||||
eor ip, \B, \C, ror #2
|
||||
add \E, \E, \A, ror #27
|
||||
eor ip, ip, \D, ror #2
|
||||
add \E, \E, r3
|
||||
add \E, \E, ip
|
||||
.endm
|
||||
|
||||
.macro sha_f3, A, B, C, D, E
|
||||
ldr r3, [r2], #4
|
||||
add \E, r1, \E, ror #2
|
||||
orr ip, \B, \C, ror #2
|
||||
add \E, \E, \A, ror #27
|
||||
and ip, ip, \D, ror #2
|
||||
add \E, \E, r3
|
||||
and r3, \B, \C, ror #2
|
||||
orr ip, ip, r3
|
||||
add \E, \E, ip
|
||||
.endm
|
||||
|
||||
ldmia r0, {r4 - r8}
|
||||
|
||||
mov lr, #4
|
||||
ldr r1, .L_sha_K + 0
|
||||
|
||||
/* adjust initial values */
|
||||
mov r6, r6, ror #30
|
||||
mov r7, r7, ror #30
|
||||
mov r8, r8, ror #30
|
||||
|
||||
3: subs lr, lr, #1
|
||||
sha_f1 r4, r5, r6, r7, r8
|
||||
sha_f1 r8, r4, r5, r6, r7
|
||||
sha_f1 r7, r8, r4, r5, r6
|
||||
sha_f1 r6, r7, r8, r4, r5
|
||||
sha_f1 r5, r6, r7, r8, r4
|
||||
bne 3b
|
||||
|
||||
ldr r1, .L_sha_K + 4
|
||||
mov lr, #4
|
||||
|
||||
4: subs lr, lr, #1
|
||||
sha_f2 r4, r5, r6, r7, r8
|
||||
sha_f2 r8, r4, r5, r6, r7
|
||||
sha_f2 r7, r8, r4, r5, r6
|
||||
sha_f2 r6, r7, r8, r4, r5
|
||||
sha_f2 r5, r6, r7, r8, r4
|
||||
bne 4b
|
||||
|
||||
ldr r1, .L_sha_K + 8
|
||||
mov lr, #4
|
||||
|
||||
5: subs lr, lr, #1
|
||||
sha_f3 r4, r5, r6, r7, r8
|
||||
sha_f3 r8, r4, r5, r6, r7
|
||||
sha_f3 r7, r8, r4, r5, r6
|
||||
sha_f3 r6, r7, r8, r4, r5
|
||||
sha_f3 r5, r6, r7, r8, r4
|
||||
bne 5b
|
||||
|
||||
ldr r1, .L_sha_K + 12
|
||||
mov lr, #4
|
||||
|
||||
6: subs lr, lr, #1
|
||||
sha_f2 r4, r5, r6, r7, r8
|
||||
sha_f2 r8, r4, r5, r6, r7
|
||||
sha_f2 r7, r8, r4, r5, r6
|
||||
sha_f2 r6, r7, r8, r4, r5
|
||||
sha_f2 r5, r6, r7, r8, r4
|
||||
bne 6b
|
||||
|
||||
ldmia r0, {r1, r2, r3, ip, lr}
|
||||
add r4, r1, r4
|
||||
add r5, r2, r5
|
||||
add r6, r3, r6, ror #2
|
||||
add r7, ip, r7, ror #2
|
||||
add r8, lr, r8, ror #2
|
||||
stmia r0, {r4 - r8}
|
||||
|
||||
ldmfd sp!, {r4 - r8, pc}
|
||||
|
||||
.L_sha_K:
|
||||
.word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
|
||||
|
||||
|
||||
/*
|
||||
* void sha_init(__u32 *buf)
|
||||
*/
|
||||
|
||||
.L_sha_initial_digest:
|
||||
.word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
|
||||
|
||||
ENTRY(sha_init)
|
||||
|
||||
str lr, [sp, #-4]!
|
||||
adr r1, .L_sha_initial_digest
|
||||
ldmia r1, {r1, r2, r3, ip, lr}
|
||||
stmia r0, {r1, r2, r3, ip, lr}
|
||||
ldr pc, [sp], #4
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
# Common support (must be linked before board specific support)
|
||||
obj-y += core.o
|
||||
obj-y += core.o clock.o
|
||||
|
||||
# Specific board support
|
||||
obj-$(CONFIG_MACH_AAED2000) += aaed2000.o
|
||||
|
||||
@@ -27,16 +27,65 @@
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include <asm/arch/aaed2000.h>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
static void aaed2000_clcd_disable(struct clcd_fb *fb)
|
||||
{
|
||||
AAED_EXT_GPIO &= ~AAED_EGPIO_LCD_PWR_EN;
|
||||
}
|
||||
|
||||
static void aaed2000_clcd_enable(struct clcd_fb *fb)
|
||||
{
|
||||
AAED_EXT_GPIO |= AAED_EGPIO_LCD_PWR_EN;
|
||||
}
|
||||
|
||||
struct aaec2000_clcd_info clcd_info = {
|
||||
.enable = aaed2000_clcd_enable,
|
||||
.disable = aaed2000_clcd_disable,
|
||||
.panel = {
|
||||
.mode = {
|
||||
.name = "Sharp",
|
||||
.refresh = 60,
|
||||
.xres = 640,
|
||||
.yres = 480,
|
||||
.pixclock = 39721,
|
||||
.left_margin = 20,
|
||||
.right_margin = 44,
|
||||
.upper_margin = 21,
|
||||
.lower_margin = 34,
|
||||
.hsync_len = 96,
|
||||
.vsync_len = 2,
|
||||
.sync = 0,
|
||||
.vmode = FB_VMODE_NONINTERLACED,
|
||||
},
|
||||
.width = -1,
|
||||
.height = -1,
|
||||
.tim2 = TIM2_IVS | TIM2_IHS,
|
||||
.cntl = CNTL_LCDTFT,
|
||||
.bpp = 16,
|
||||
},
|
||||
};
|
||||
|
||||
static void __init aaed2000_init_irq(void)
|
||||
{
|
||||
aaec2000_init_irq();
|
||||
}
|
||||
|
||||
static void __init aaed2000_init(void)
|
||||
{
|
||||
aaec2000_set_clcd_plat_data(&clcd_info);
|
||||
}
|
||||
|
||||
static struct map_desc aaed2000_io_desc[] __initdata = {
|
||||
{ EXT_GPIO_VBASE, EXT_GPIO_PBASE, EXT_GPIO_LENGTH, MT_DEVICE }, /* Ext GPIO */
|
||||
};
|
||||
|
||||
static void __init aaed2000_map_io(void)
|
||||
{
|
||||
aaec2000_map_io();
|
||||
iotable_init(aaed2000_io_desc, ARRAY_SIZE(aaed2000_io_desc));
|
||||
}
|
||||
|
||||
MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
|
||||
@@ -47,4 +96,5 @@ MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
|
||||
.map_io = aaed2000_map_io,
|
||||
.init_irq = aaed2000_init_irq,
|
||||
.timer = &aaec2000_timer,
|
||||
.init_machine = aaed2000_init,
|
||||
MACHINE_END
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-aaec2000/clock.c
|
||||
*
|
||||
* Copyright (C) 2005 Nicolas Bellido Y Ortega
|
||||
*
|
||||
* Based on linux/arch/arm/mach-integrator/clock.c
|
||||
*
|
||||
* 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/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <asm/semaphore.h>
|
||||
#include <asm/hardware/clock.h>
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
static LIST_HEAD(clocks);
|
||||
static DECLARE_MUTEX(clocks_sem);
|
||||
|
||||
struct clk *clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
struct clk *p, *clk = ERR_PTR(-ENOENT);
|
||||
|
||||
down(&clocks_sem);
|
||||
list_for_each_entry(p, &clocks, node) {
|
||||
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
|
||||
clk = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
up(&clocks_sem);
|
||||
|
||||
return clk;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get);
|
||||
|
||||
void clk_put(struct clk *clk)
|
||||
{
|
||||
module_put(clk->owner);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_put);
|
||||
|
||||
int clk_enable(struct clk *clk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_enable);
|
||||
|
||||
void clk_disable(struct clk *clk)
|
||||
{
|
||||
}
|
||||
EXPORT_SYMBOL(clk_disable);
|
||||
|
||||
int clk_use(struct clk *clk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_use);
|
||||
|
||||
void clk_unuse(struct clk *clk)
|
||||
{
|
||||
}
|
||||
EXPORT_SYMBOL(clk_unuse);
|
||||
|
||||
unsigned long clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return clk->rate;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get_rate);
|
||||
|
||||
long clk_round_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
return rate;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_round_rate);
|
||||
|
||||
int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_set_rate);
|
||||
|
||||
int clk_register(struct clk *clk)
|
||||
{
|
||||
down(&clocks_sem);
|
||||
list_add(&clk->node, &clocks);
|
||||
up(&clocks_sem);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_register);
|
||||
|
||||
void clk_unregister(struct clk *clk)
|
||||
{
|
||||
down(&clocks_sem);
|
||||
list_del(&clk->node);
|
||||
up(&clocks_sem);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_unregister);
|
||||
|
||||
static int __init clk_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(clk_init);
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-aaec2000/clock.h
|
||||
*
|
||||
* Copyright (C) 2005 Nicolas Bellido Y Ortega
|
||||
*
|
||||
* Based on linux/arch/arm/mach-integrator/clock.h
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
struct module;
|
||||
|
||||
struct clk {
|
||||
struct list_head node;
|
||||
unsigned long rate;
|
||||
struct module *owner;
|
||||
const char *name;
|
||||
void *data;
|
||||
};
|
||||
|
||||
int clk_register(struct clk *clk);
|
||||
void clk_unregister(struct clk *clk);
|
||||
@@ -13,19 +13,27 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/signal.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/sizes.h>
|
||||
#include <asm/hardware/amba.h>
|
||||
|
||||
#include <asm/mach/flash.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "clock.h"
|
||||
|
||||
/*
|
||||
* Common I/O mapping:
|
||||
*
|
||||
@@ -40,9 +48,17 @@
|
||||
* default mapping provided here.
|
||||
*/
|
||||
static struct map_desc standard_io_desc[] __initdata = {
|
||||
/* virtual physical length type */
|
||||
{ VIO_APB_BASE, PIO_APB_BASE, IO_APB_LENGTH, MT_DEVICE },
|
||||
{ VIO_AHB_BASE, PIO_AHB_BASE, IO_AHB_LENGTH, MT_DEVICE }
|
||||
{
|
||||
.virtual = VIO_APB_BASE,
|
||||
.physical = __phys_to_pfn(PIO_APB_BASE),
|
||||
.length = IO_APB_LENGTH,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = VIO_AHB_BASE,
|
||||
.physical = __phys_to_pfn(PIO_AHB_BASE),
|
||||
.length = IO_AHB_LENGTH,
|
||||
.type = MT_DEVICE
|
||||
}
|
||||
};
|
||||
|
||||
void __init aaec2000_map_io(void)
|
||||
@@ -155,3 +171,116 @@ struct sys_timer aaec2000_timer = {
|
||||
.offset = aaec2000_gettimeoffset,
|
||||
};
|
||||
|
||||
static struct clcd_panel mach_clcd_panel;
|
||||
|
||||
static int aaec2000_clcd_setup(struct clcd_fb *fb)
|
||||
{
|
||||
dma_addr_t dma;
|
||||
|
||||
fb->panel = &mach_clcd_panel;
|
||||
|
||||
fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, SZ_1M,
|
||||
&dma, GFP_KERNEL);
|
||||
|
||||
if (!fb->fb.screen_base) {
|
||||
printk(KERN_ERR "CLCD: unable to map framebuffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fb->fb.fix.smem_start = dma;
|
||||
fb->fb.fix.smem_len = SZ_1M;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aaec2000_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
|
||||
{
|
||||
return dma_mmap_writecombine(&fb->dev->dev, vma,
|
||||
fb->fb.screen_base,
|
||||
fb->fb.fix.smem_start,
|
||||
fb->fb.fix.smem_len);
|
||||
}
|
||||
|
||||
static void aaec2000_clcd_remove(struct clcd_fb *fb)
|
||||
{
|
||||
dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
|
||||
fb->fb.screen_base, fb->fb.fix.smem_start);
|
||||
}
|
||||
|
||||
static struct clcd_board clcd_plat_data = {
|
||||
.name = "AAEC-2000",
|
||||
.check = clcdfb_check,
|
||||
.decode = clcdfb_decode,
|
||||
.setup = aaec2000_clcd_setup,
|
||||
.mmap = aaec2000_clcd_mmap,
|
||||
.remove = aaec2000_clcd_remove,
|
||||
};
|
||||
|
||||
static struct amba_device clcd_device = {
|
||||
.dev = {
|
||||
.bus_id = "mb:16",
|
||||
.coherent_dma_mask = ~0,
|
||||
.platform_data = &clcd_plat_data,
|
||||
},
|
||||
.res = {
|
||||
.start = AAEC_CLCD_PHYS,
|
||||
.end = AAEC_CLCD_PHYS + SZ_4K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
.irq = { INT_LCD, NO_IRQ },
|
||||
.periphid = 0x41110,
|
||||
};
|
||||
|
||||
static struct amba_device *amba_devs[] __initdata = {
|
||||
&clcd_device,
|
||||
};
|
||||
|
||||
static struct clk aaec2000_clcd_clk = {
|
||||
.name = "CLCDCLK",
|
||||
};
|
||||
|
||||
void __init aaec2000_set_clcd_plat_data(struct aaec2000_clcd_info *clcd)
|
||||
{
|
||||
clcd_plat_data.enable = clcd->enable;
|
||||
clcd_plat_data.disable = clcd->disable;
|
||||
memcpy(&mach_clcd_panel, &clcd->panel, sizeof(struct clcd_panel));
|
||||
}
|
||||
|
||||
static struct flash_platform_data aaec2000_flash_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 4,
|
||||
};
|
||||
|
||||
static struct resource aaec2000_flash_resource = {
|
||||
.start = AAEC_FLASH_BASE,
|
||||
.end = AAEC_FLASH_BASE + AAEC_FLASH_SIZE,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device aaec2000_flash_device = {
|
||||
.name = "armflash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &aaec2000_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &aaec2000_flash_resource,
|
||||
};
|
||||
|
||||
static int __init aaec2000_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
clk_register(&aaec2000_clcd_clk);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
||||
struct amba_device *d = amba_devs[i];
|
||||
amba_device_register(d, &iomem_resource);
|
||||
}
|
||||
|
||||
platform_device_register(&aaec2000_flash_device);
|
||||
|
||||
return 0;
|
||||
};
|
||||
arch_initcall(aaec2000_init);
|
||||
|
||||
|
||||
@@ -9,8 +9,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asm/hardware/amba_clcd.h>
|
||||
|
||||
struct sys_timer;
|
||||
|
||||
extern struct sys_timer aaec2000_timer;
|
||||
extern void __init aaec2000_map_io(void);
|
||||
extern void __init aaec2000_init_irq(void);
|
||||
|
||||
struct aaec2000_clcd_info {
|
||||
struct clcd_panel panel;
|
||||
void (*disable)(struct clcd_fb *);
|
||||
void (*enable)(struct clcd_fb *);
|
||||
};
|
||||
|
||||
extern void __init aaec2000_set_clcd_plat_data(struct aaec2000_clcd_info *);
|
||||
|
||||
|
||||
@@ -69,6 +69,17 @@ config EP72XX_ROM_BOOT
|
||||
|
||||
You almost surely want to say N here.
|
||||
|
||||
config MACH_MP1000
|
||||
bool "MACH_MP1000"
|
||||
help
|
||||
Say Y if you intend to run the kernel on the Comdial MP1000 platform.
|
||||
|
||||
config MP1000_90MHZ
|
||||
bool "MP1000_90MHZ"
|
||||
depends on MACH_MP1000
|
||||
help
|
||||
Say Y if you have the MP1000 configured to be set at 90MHZ rather than 74MHZ
|
||||
|
||||
endmenu
|
||||
|
||||
endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user