Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
251f6b40
Commit
251f6b40
authored
Oct 27, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://bk.arm.linux.org.uk/linux-2.6-mmc
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
6228bab7
93309015
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
65 additions
and
45 deletions
+65
-45
drivers/mmc/mmc_block.c
drivers/mmc/mmc_block.c
+3
-0
drivers/mmc/mmc_queue.c
drivers/mmc/mmc_queue.c
+20
-4
drivers/mmc/mmc_queue.h
drivers/mmc/mmc_queue.h
+1
-0
drivers/mmc/mmci.c
drivers/mmc/mmci.c
+1
-1
drivers/mmc/mmci.h
drivers/mmc/mmci.h
+2
-6
drivers/mmc/pxamci.c
drivers/mmc/pxamci.c
+34
-33
include/linux/mmc/mmc.h
include/linux/mmc/mmc.h
+4
-1
No files found.
drivers/mmc/mmc_block.c
View file @
251f6b40
...
...
@@ -200,6 +200,9 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
}
brq
.
mrq
.
stop
=
brq
.
data
.
blocks
>
1
?
&
brq
.
stop
:
NULL
;
brq
.
data
.
sg
=
mq
->
sg
;
brq
.
data
.
sg_len
=
blk_rq_map_sg
(
req
->
q
,
req
,
brq
.
data
.
sg
);
mmc_wait_for_req
(
card
->
host
,
&
brq
.
mrq
);
if
(
brq
.
cmd
.
error
)
{
printk
(
KERN_ERR
"%s: error %d sending read/write command
\n
"
,
...
...
drivers/mmc/mmc_queue.c
View file @
251f6b40
...
...
@@ -80,7 +80,7 @@ static int mmc_queue_thread(void *d)
set_current_state
(
TASK_INTERRUPTIBLE
);
if
(
!
blk_queue_plugged
(
q
))
mq
->
req
=
req
=
elv_next_request
(
q
);
spin_unlock
(
q
->
queue_lock
);
spin_unlock
_irq
(
q
->
queue_lock
);
if
(
!
req
)
{
if
(
mq
->
flags
&
MMC_QUEUE_EXIT
)
...
...
@@ -147,19 +147,31 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
mq
->
queue
->
queuedata
=
mq
;
mq
->
req
=
NULL
;
mq
->
sg
=
kmalloc
(
sizeof
(
struct
scatterlist
)
*
host
->
max_phys_segs
,
GFP_KERNEL
);
if
(
!
mq
->
sg
)
{
ret
=
-
ENOMEM
;
goto
cleanup
;
}
init_completion
(
&
mq
->
thread_complete
);
init_waitqueue_head
(
&
mq
->
thread_wq
);
init_MUTEX
(
&
mq
->
thread_sem
);
ret
=
kernel_thread
(
mmc_queue_thread
,
mq
,
CLONE_KERNEL
);
if
(
ret
<
0
)
{
blk_cleanup_queue
(
mq
->
queue
);
}
else
{
if
(
ret
>=
0
)
{
wait_for_completion
(
&
mq
->
thread_complete
);
init_completion
(
&
mq
->
thread_complete
);
ret
=
0
;
goto
out
;
}
cleanup:
kfree
(
mq
->
sg
);
mq
->
sg
=
NULL
;
blk_cleanup_queue
(
mq
->
queue
);
out:
return
ret
;
}
EXPORT_SYMBOL
(
mmc_init_queue
);
...
...
@@ -169,6 +181,10 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
mq
->
flags
|=
MMC_QUEUE_EXIT
;
wake_up
(
&
mq
->
thread_wq
);
wait_for_completion
(
&
mq
->
thread_complete
);
kfree
(
mq
->
sg
);
mq
->
sg
=
NULL
;
blk_cleanup_queue
(
mq
->
queue
);
mq
->
card
=
NULL
;
...
...
drivers/mmc/mmc_queue.h
View file @
251f6b40
...
...
@@ -15,6 +15,7 @@ struct mmc_queue {
int
(
*
issue_fn
)(
struct
mmc_queue
*
,
struct
request
*
);
void
*
data
;
struct
request_queue
*
queue
;
struct
scatterlist
*
sg
;
};
struct
mmc_io_request
{
...
...
drivers/mmc/mmci.c
View file @
251f6b40
...
...
@@ -501,7 +501,7 @@ static int mmci_probe(struct amba_device *dev, void *id)
* We can do SGIO
*/
mmc
->
max_hw_segs
=
16
;
mmc
->
max_phys_segs
=
16
;
mmc
->
max_phys_segs
=
NR_SG
;
/*
* Since we only have a 16-bit data length register, we must
...
...
drivers/mmc/mmci.h
View file @
251f6b40
...
...
@@ -139,7 +139,6 @@ struct mmci_host {
struct
timer_list
timer
;
unsigned
int
oldstat
;
struct
scatterlist
sg
[
NR_SG
];
unsigned
int
sg_len
;
/* pio stuff */
...
...
@@ -150,14 +149,11 @@ struct mmci_host {
static
inline
void
mmci_init_sg
(
struct
mmci_host
*
host
,
struct
mmc_data
*
data
)
{
struct
scatterlist
*
sg
=
host
->
sg
;
struct
request
*
req
=
data
->
req
;
/*
* Ideally, we want the higher levels to pass us a scatter list.
*/
host
->
sg_len
=
blk_rq_map_sg
(
req
->
q
,
req
,
sg
)
;
host
->
sg_ptr
=
sg
;
host
->
sg_len
=
data
->
sg_len
;
host
->
sg_ptr
=
data
->
sg
;
host
->
sg_off
=
0
;
}
...
...
drivers/mmc/pxamci.c
View file @
251f6b40
...
...
@@ -44,6 +44,10 @@
#define DBG(x...) do { } while (0)
#endif
#define DRIVER_NAME "pxa2xx-mci"
#define NR_SG 1
struct
pxamci_host
{
struct
mmc_host
*
mmc
;
spinlock_t
lock
;
...
...
@@ -63,9 +67,8 @@ struct pxamci_host {
dma_addr_t
sg_dma
;
struct
pxa_dma_desc
*
sg_cpu
;
unsigned
int
dma_len
;
dma_addr_t
dma_buf
;
unsigned
int
dma_size
;
unsigned
int
dma_dir
;
};
...
...
@@ -122,10 +125,9 @@ static void pxamci_disable_irq(struct pxamci_host *host, unsigned int mask)
static
void
pxamci_setup_data
(
struct
pxamci_host
*
host
,
struct
mmc_data
*
data
)
{
unsigned
int
nob
=
data
->
blocks
;
unsigned
int
timeout
,
size
;
dma_addr_t
dma
;
unsigned
int
timeout
;
u32
dcmd
;
int
i
;
int
i
,
len
;
host
->
data
=
data
;
...
...
@@ -152,35 +154,22 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
dcmd
|=
DCMD_BURST32
|
DCMD_WIDTH1
;
host
->
dma_size
=
data
->
blocks
<<
data
->
blksz_bits
;
host
->
dma_buf
=
dma_map_single
(
mmc_dev
(
host
->
mmc
),
data
->
req
->
buffer
,
host
->
dma_size
,
host
->
dma_dir
);
for
(
i
=
0
,
size
=
host
->
dma_size
,
dma
=
host
->
dma_buf
;
size
;
i
++
)
{
u32
len
=
size
;
if
(
len
>
DCMD_LENGTH
)
len
=
0x1000
;
host
->
dma_len
=
dma_map_sg
(
mmc_dev
(
host
->
mmc
),
data
->
sg
,
data
->
sg_len
,
host
->
dma_dir
);
for
(
i
=
0
;
i
<
host
->
dma_len
;
i
++
)
{
if
(
data
->
flags
&
MMC_DATA_READ
)
{
host
->
sg_cpu
[
i
].
dsadr
=
host
->
res
->
start
+
MMC_RXFIFO
;
host
->
sg_cpu
[
i
].
dtadr
=
dma
;
host
->
sg_cpu
[
i
].
dtadr
=
sg_dma_address
(
&
data
->
sg
[
i
])
;
}
else
{
host
->
sg_cpu
[
i
].
dsadr
=
dma
;
host
->
sg_cpu
[
i
].
dsadr
=
sg_dma_address
(
&
data
->
sg
[
i
])
;
host
->
sg_cpu
[
i
].
dtadr
=
host
->
res
->
start
+
MMC_TXFIFO
;
}
host
->
sg_cpu
[
i
].
dcmd
=
dcmd
|
len
;
dma
+=
len
;
size
-=
len
;
if
(
size
)
{
host
->
sg_cpu
[
i
].
ddadr
=
host
->
sg_dma
+
(
i
+
1
)
*
sizeof
(
struct
pxa_dma_desc
);
}
else
{
host
->
sg_cpu
[
i
].
ddadr
=
DDADR_STOP
;
}
host
->
sg_cpu
[
i
].
dcmd
=
dcmd
|
sg_dma_len
(
&
data
->
sg
[
i
]);
host
->
sg_cpu
[
i
].
ddadr
=
host
->
sg_dma
+
(
i
+
1
)
*
sizeof
(
struct
pxa_dma_desc
);
}
host
->
sg_cpu
[
host
->
dma_len
-
1
].
ddadr
=
DDADR_STOP
;
wmb
();
DDADR
(
host
->
dma
)
=
host
->
sg_dma
;
...
...
@@ -276,8 +265,8 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat)
return
0
;
DCSR
(
host
->
dma
)
=
0
;
dma_unmap_s
ingle
(
mmc_dev
(
host
->
mmc
),
host
->
dma_buf
,
host
->
dma_size
,
host
->
dma_dir
);
dma_unmap_s
g
(
mmc_dev
(
host
->
mmc
),
data
->
sg
,
host
->
dma_len
,
host
->
dma_dir
);
if
(
stat
&
STAT_READ_TIME_OUT
)
data
->
error
=
MMC_ERR_TIMEOUT
;
...
...
@@ -429,7 +418,7 @@ static int pxamci_probe(struct device *dev)
if
(
!
r
||
irq
==
NO_IRQ
)
return
-
ENXIO
;
r
=
request_mem_region
(
r
->
start
,
SZ_4K
,
"PXAMCI"
);
r
=
request_mem_region
(
r
->
start
,
SZ_4K
,
DRIVER_NAME
);
if
(
!
r
)
return
-
EBUSY
;
...
...
@@ -443,6 +432,17 @@ static int pxamci_probe(struct device *dev)
mmc
->
f_min
=
312500
;
mmc
->
f_max
=
20000000
;
/*
* We can do SG-DMA, but we don't because we never know how much
* data we successfully wrote to the card.
*/
mmc
->
max_phys_segs
=
NR_SG
;
/*
* Our hardware DMA can handle a maximum of one page per SG entry.
*/
mmc
->
max_seg_size
=
PAGE_SIZE
;
host
=
mmc_priv
(
mmc
);
host
->
mmc
=
mmc
;
host
->
dma
=
-
1
;
...
...
@@ -482,13 +482,14 @@ static int pxamci_probe(struct device *dev)
pxa_gpio_mode
(
GPIO8_MMCCS0_MD
);
pxa_set_cken
(
CKEN12_MMC
,
1
);
host
->
dma
=
pxa_request_dma
(
"PXAMCI"
,
DMA_PRIO_LOW
,
pxamci_dma_irq
,
host
);
host
->
dma
=
pxa_request_dma
(
DRIVER_NAME
,
DMA_PRIO_LOW
,
pxamci_dma_irq
,
host
);
if
(
host
->
dma
<
0
)
{
ret
=
-
EBUSY
;
goto
out
;
}
ret
=
request_irq
(
host
->
irq
,
pxamci_irq
,
0
,
"PXAMCI"
,
host
);
ret
=
request_irq
(
host
->
irq
,
pxamci_irq
,
0
,
DRIVER_NAME
,
host
);
if
(
ret
)
goto
out
;
...
...
@@ -579,7 +580,7 @@ static int pxamci_resume(struct device *dev, u32 level)
#endif
static
struct
device_driver
pxamci_driver
=
{
.
name
=
"pxa2xx-mci"
,
.
name
=
DRIVER_NAME
,
.
bus
=
&
platform_bus_type
,
.
probe
=
pxamci_probe
,
.
remove
=
pxamci_remove
,
...
...
include/linux/mmc/mmc.h
View file @
251f6b40
...
...
@@ -57,7 +57,7 @@ struct mmc_data {
unsigned
int
timeout_clks
;
/* data timeout (in clocks) */
unsigned
int
blksz_bits
;
/* data block size */
unsigned
int
blocks
;
/* number of blocks */
struct
request
*
req
;
/* request structure
*/
struct
request
*
req
__attribute__
((
deprecated
));
/* request structure (use the sg list instead)
*/
unsigned
int
error
;
/* data error */
unsigned
int
flags
;
...
...
@@ -69,6 +69,9 @@ struct mmc_data {
struct
mmc_command
*
stop
;
/* stop command */
struct
mmc_request
*
mrq
;
/* assoicated request */
unsigned
int
sg_len
;
/* size of scatter list */
struct
scatterlist
*
sg
;
/* I/O scatter list */
};
struct
mmc_request
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment