Merge branch 'for-linus' of git://openrisc.net/~jonas/linux
* 'for-linus' of git://openrisc.net/~jonas/linux: Add missing DMA ops openrisc: don't use pt_regs in struct sigcontext
This commit is contained in:
commit
14f69ec706
|
@ -31,7 +31,6 @@
|
||||||
|
|
||||||
#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
|
#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
|
||||||
|
|
||||||
int dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
|
|
||||||
|
|
||||||
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
|
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
|
||||||
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
|
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
|
||||||
|
@ -47,6 +46,12 @@ dma_addr_t or1k_map_page(struct device *dev, struct page *page,
|
||||||
void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle,
|
void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle,
|
||||||
size_t size, enum dma_data_direction dir,
|
size_t size, enum dma_data_direction dir,
|
||||||
struct dma_attrs *attrs);
|
struct dma_attrs *attrs);
|
||||||
|
int or1k_map_sg(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents, enum dma_data_direction dir,
|
||||||
|
struct dma_attrs *attrs);
|
||||||
|
void or1k_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents, enum dma_data_direction dir,
|
||||||
|
struct dma_attrs *attrs);
|
||||||
void or1k_sync_single_for_cpu(struct device *dev,
|
void or1k_sync_single_for_cpu(struct device *dev,
|
||||||
dma_addr_t dma_handle, size_t size,
|
dma_addr_t dma_handle, size_t size,
|
||||||
enum dma_data_direction dir);
|
enum dma_data_direction dir);
|
||||||
|
@ -98,6 +103,51 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
|
||||||
debug_dma_unmap_page(dev, addr, size, dir, true);
|
debug_dma_unmap_page(dev, addr, size, dir, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents, enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
int i, ents;
|
||||||
|
struct scatterlist *s;
|
||||||
|
|
||||||
|
for_each_sg(sg, s, nents, i)
|
||||||
|
kmemcheck_mark_initialized(sg_virt(s), s->length);
|
||||||
|
BUG_ON(!valid_dma_direction(dir));
|
||||||
|
ents = or1k_map_sg(dev, sg, nents, dir, NULL);
|
||||||
|
debug_dma_map_sg(dev, sg, nents, ents, dir);
|
||||||
|
|
||||||
|
return ents;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents, enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
BUG_ON(!valid_dma_direction(dir));
|
||||||
|
debug_dma_unmap_sg(dev, sg, nents, dir);
|
||||||
|
or1k_unmap_sg(dev, sg, nents, dir, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
|
||||||
|
size_t offset, size_t size,
|
||||||
|
enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
dma_addr_t addr;
|
||||||
|
|
||||||
|
kmemcheck_mark_initialized(page_address(page) + offset, size);
|
||||||
|
BUG_ON(!valid_dma_direction(dir));
|
||||||
|
addr = or1k_map_page(dev, page, offset, size, dir, NULL);
|
||||||
|
debug_dma_map_page(dev, page, offset, size, dir, addr, false);
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
|
||||||
|
size_t size, enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
BUG_ON(!valid_dma_direction(dir));
|
||||||
|
or1k_unmap_page(dev, addr, size, dir, NULL);
|
||||||
|
debug_dma_unmap_page(dev, addr, size, dir, true);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
|
static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
|
||||||
size_t size,
|
size_t size,
|
||||||
enum dma_data_direction dir)
|
enum dma_data_direction dir)
|
||||||
|
@ -119,7 +169,12 @@ static inline void dma_sync_single_for_device(struct device *dev,
|
||||||
static inline int dma_supported(struct device *dev, u64 dma_mask)
|
static inline int dma_supported(struct device *dev, u64 dma_mask)
|
||||||
{
|
{
|
||||||
/* Support 32 bit DMA mask exclusively */
|
/* Support 32 bit DMA mask exclusively */
|
||||||
return dma_mask == 0xffffffffULL;
|
return dma_mask == DMA_BIT_MASK(32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int dma_set_mask(struct device *dev, u64 dma_mask)
|
static inline int dma_set_mask(struct device *dev, u64 dma_mask)
|
||||||
|
|
|
@ -23,16 +23,11 @@
|
||||||
|
|
||||||
/* This struct is saved by setup_frame in signal.c, to keep the current
|
/* This struct is saved by setup_frame in signal.c, to keep the current
|
||||||
context while a signal handler is executed. It's restored by sys_sigreturn.
|
context while a signal handler is executed. It's restored by sys_sigreturn.
|
||||||
|
|
||||||
To keep things simple, we use pt_regs here even though normally you just
|
|
||||||
specify the list of regs to save. Then we can use copy_from_user on the
|
|
||||||
entire regs instead of a bunch of get_user's as well...
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct sigcontext {
|
struct sigcontext {
|
||||||
struct pt_regs regs; /* needs to be first */
|
struct user_regs_struct regs; /* needs to be first */
|
||||||
unsigned long oldmask;
|
unsigned long oldmask;
|
||||||
unsigned long usp; /* usp before stacking this gunk on it */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __ASM_OPENRISC_SIGCONTEXT_H */
|
#endif /* __ASM_OPENRISC_SIGCONTEXT_H */
|
||||||
|
|
|
@ -154,6 +154,33 @@ void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle,
|
||||||
/* Nothing special to do here... */
|
/* Nothing special to do here... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int or1k_map_sg(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents, enum dma_data_direction dir,
|
||||||
|
struct dma_attrs *attrs)
|
||||||
|
{
|
||||||
|
struct scatterlist *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for_each_sg(sg, s, nents, i) {
|
||||||
|
s->dma_address = or1k_map_page(dev, sg_page(s), s->offset,
|
||||||
|
s->length, dir, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nents;
|
||||||
|
}
|
||||||
|
|
||||||
|
void or1k_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents, enum dma_data_direction dir,
|
||||||
|
struct dma_attrs *attrs)
|
||||||
|
{
|
||||||
|
struct scatterlist *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for_each_sg(sg, s, nents, i) {
|
||||||
|
or1k_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void or1k_sync_single_for_cpu(struct device *dev,
|
void or1k_sync_single_for_cpu(struct device *dev,
|
||||||
dma_addr_t dma_handle, size_t size,
|
dma_addr_t dma_handle, size_t size,
|
||||||
enum dma_data_direction dir)
|
enum dma_data_direction dir)
|
||||||
|
@ -187,5 +214,4 @@ static int __init dma_init(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_initcall(dma_init);
|
fs_initcall(dma_init);
|
||||||
|
|
|
@ -52,31 +52,25 @@ struct rt_sigframe {
|
||||||
static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
|
static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
|
||||||
{
|
{
|
||||||
unsigned int err = 0;
|
unsigned int err = 0;
|
||||||
unsigned long old_usp;
|
|
||||||
|
|
||||||
/* Alwys make any pending restarted system call return -EINTR */
|
/* Alwys make any pending restarted system call return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/* restore the regs from &sc->regs (same as sc, since regs is first)
|
/*
|
||||||
|
* Restore the regs from &sc->regs.
|
||||||
* (sc is already checked for VERIFY_READ since the sigframe was
|
* (sc is already checked for VERIFY_READ since the sigframe was
|
||||||
* checked in sys_sigreturn previously)
|
* checked in sys_sigreturn previously)
|
||||||
*/
|
*/
|
||||||
|
if (__copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long)))
|
||||||
if (__copy_from_user(regs, sc, sizeof(struct pt_regs)))
|
goto badframe;
|
||||||
|
if (__copy_from_user(®s->pc, &sc->regs.pc, sizeof(unsigned long)))
|
||||||
|
goto badframe;
|
||||||
|
if (__copy_from_user(®s->sr, &sc->regs.sr, sizeof(unsigned long)))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
|
|
||||||
/* make sure the SM-bit is cleared so user-mode cannot fool us */
|
/* make sure the SM-bit is cleared so user-mode cannot fool us */
|
||||||
regs->sr &= ~SPR_SR_SM;
|
regs->sr &= ~SPR_SR_SM;
|
||||||
|
|
||||||
/* restore the old USP as it was before we stacked the sc etc.
|
|
||||||
* (we cannot just pop the sigcontext since we aligned the sp and
|
|
||||||
* stuff after pushing it)
|
|
||||||
*/
|
|
||||||
|
|
||||||
err |= __get_user(old_usp, &sc->usp);
|
|
||||||
|
|
||||||
regs->sp = old_usp;
|
|
||||||
|
|
||||||
/* TODO: the other ports use regs->orig_XX to disable syscall checks
|
/* TODO: the other ports use regs->orig_XX to disable syscall checks
|
||||||
* after this completes, but we don't use that mechanism. maybe we can
|
* after this completes, but we don't use that mechanism. maybe we can
|
||||||
* use it now ?
|
* use it now ?
|
||||||
|
@ -137,18 +131,17 @@ static int setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
|
||||||
unsigned long mask)
|
unsigned long mask)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
unsigned long usp = regs->sp;
|
|
||||||
|
|
||||||
/* copy the regs. they are first in sc so we can use sc directly */
|
/* copy the regs */
|
||||||
|
|
||||||
err |= __copy_to_user(sc, regs, sizeof(struct pt_regs));
|
err |= __copy_to_user(sc->regs.gpr, regs, 32 * sizeof(unsigned long));
|
||||||
|
err |= __copy_to_user(&sc->regs.pc, ®s->pc, sizeof(unsigned long));
|
||||||
|
err |= __copy_to_user(&sc->regs.sr, ®s->sr, sizeof(unsigned long));
|
||||||
|
|
||||||
/* then some other stuff */
|
/* then some other stuff */
|
||||||
|
|
||||||
err |= __put_user(mask, &sc->oldmask);
|
err |= __put_user(mask, &sc->oldmask);
|
||||||
|
|
||||||
err |= __put_user(usp, &sc->usp);
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue