Commit fcff08de authored by Hiroshi DOYU's avatar Hiroshi DOYU Committed by Tony Lindgren

ARM:OMAP: Integrated blk request queues for mbox fwk

- Taken from maemo.org N800 kernel package.
- Use request queues
- move mbox initialization to late init.
Signed-off-by: default avatarTrilok Soni <soni.trilok@gmail.com>
Signed-off-by: default avatarHiroshi DOYU <Hiroshi.DOYU@nokia.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 6cda72c7
......@@ -156,6 +156,31 @@ static inline void dsp_clk_autoidle(void)
}
#endif
#if defined(CONFIG_ARCH_OMAP1)
static inline void dsp_clk_enable(void) {}
static inline void dsp_clk_disable(void) {}
#elif defined(CONFIG_ARCH_OMAP2)
static inline void dsp_clk_enable(void)
{
/*XXX should be handled in mach-omap[1,2] XXX*/
PM_PWSTCTRL_DSP = (1 << 18) | (1 << 0);
CM_AUTOIDLE_DSP |= (1 << 1);
CM_CLKSTCTRL_DSP |= (1 << 0);
clk_enable(dsp_fck_handle);
clk_enable(dsp_ick_handle);
__dsp_per_enable();
}
static inline void dsp_clk_disable(void)
{
__dsp_per_disable();
clk_disable(dsp_ick_handle);
clk_disable(dsp_fck_handle);
PM_PWSTCTRL_DSP = (1 << 18) | (3 << 0);
}
#endif
struct dsp_kfunc_device {
char *name;
struct clk *fck;
......
......@@ -516,14 +516,13 @@ int dsp_late_init(void)
{
int ret;
dsp_clk_autoidle();
/*dsp_clk_autoidle();*/
dsp_clk_enable();
#ifdef CONFIG_ARCH_OMAP2
clk_enable(dsp_fck_handle);
clk_enable(dsp_ick_handle);
__dsp_per_enable();
#endif
dsp_mem_late_init();
ret = dsp_mbox_init();
if (ret)
goto fail_mbox;
#ifdef CONFIG_ARCH_OMAP1
dsp_set_idle_boot_base(IDLEPG_BASE, IDLEPG_SIZE);
......@@ -531,9 +530,17 @@ int dsp_late_init(void)
ret = dsp_kfunc_enable_devices(omap_dsp,
DSP_KFUNC_DEV_TYPE_COMMON, 0);
if (ret == 0)
omap_dsp->enabled = 0;
goto fail_kfunc;
omap_dsp->enabled = 1;
return 0;
fail_kfunc:
dsp_mbox_exit();
fail_mbox:
dsp_clk_disable();
return ret;
}
extern int dsp_ctl_core_init(void);
......@@ -590,13 +597,9 @@ static int __init dsp_drv_probe(struct platform_device *pdev)
mblog_init();
if ((ret = dsp_taskmod_init()) < 0)
goto fail4;
if ((ret = dsp_mbox_init()) < 0)
goto fail5;
return 0;
fail5:
dsp_taskmod_exit();
fail4:
mblog_exit();
dsp_ctl_exit();
......
......@@ -330,7 +330,7 @@ void mbox_fbctl_upd(void) { }
static ssize_t dsp_mem_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
return __omap_mmu_mem_read(&dsp_mmu, buf, *ppos, count);
return __omap_mmu_mem_read(&dsp_mmu, (char __user *)buf, *ppos, count);
}
static ssize_t dsp_mem_write(struct file *file, const char __user *buf,
......
This diff is collapsed.
......@@ -12,98 +12,7 @@
#ifndef __ARCH_ARM_PLAT_MAILBOX_H
#define __ARCH_ARM_PLAT_MAILBOX_H
/*
* Mailbox queue handling API
*/
#define MBQ_DEPTH 16
struct omap_mbq {
rwlock_t lock;
mbox_msg_t msg[MBQ_DEPTH];
mbox_msg_t *rp, *wp;
int cnt;
};
static inline int mbq_init(struct omap_mbq **addr)
{
struct omap_mbq *m = kmalloc(sizeof(struct omap_mbq), GFP_KERNEL);
if (!m)
return -ENOMEM;
rwlock_init(&m->lock);
write_lock_irq(&m->lock);
m->rp = m->wp = &m->msg[0];
m->cnt = 0;
write_unlock_irq(&m->lock);
*addr = m;
return 0;
}
static inline int mbq_empty(struct omap_mbq *mbq)
{
int ret;
read_lock_irq(&mbq->lock);
ret = (mbq->cnt == 0);
read_unlock_irq(&mbq->lock);
return ret;
}
static inline int mbq_full(struct omap_mbq *mbq)
{
int ret;
read_lock_irq(&mbq->lock);
ret = (mbq->cnt == MBQ_DEPTH);
read_unlock_irq(&mbq->lock);
return ret;
}
static inline int mbq_add(struct omap_mbq *mbq, mbox_msg_t msg)
{
int ret = 0;
write_lock_irq(&mbq->lock);
*mbq->wp = msg;
if (++mbq->wp == &mbq->msg[MBQ_DEPTH])
mbq->wp = &mbq->msg[0];
if (++mbq->cnt == MBQ_DEPTH) /* full */
ret = -1;
write_unlock_irq(&mbq->lock);
return ret;
}
static inline mbox_msg_t mbq_get(struct omap_mbq *mbq)
{
mbox_msg_t msg;
write_lock_irq(&mbq->lock);
msg = *mbq->rp;
if (++mbq->rp == &mbq->msg[MBQ_DEPTH])
mbq->rp = &mbq->msg[0];
mbq->cnt--;
write_unlock_irq(&mbq->lock);
return msg;
}
static inline void mbq_exit(struct omap_mbq **addr)
{
if (*addr)
kfree(*addr);
}
#define MBOX_NAME_LEN 255
/*
* Mailbox sequence bit API
......
......@@ -5,11 +5,11 @@
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <linux/blkdev.h>
typedef u32 mbox_msg_t;
typedef void (mbox_receiver_t)(mbox_msg_t msg);
struct omap_mbox;
struct omap_mbq;
typedef int __bitwise omap_mbox_irq_t;
#define IRQ_TX ((__force omap_mbox_irq_t) 1)
......@@ -21,48 +21,52 @@ typedef int __bitwise omap_mbox_type_t;
struct omap_mbox_ops {
omap_mbox_type_t type;
int (*startup)(struct omap_mbox *mbox);
void (*shutdown)(struct omap_mbox *mbox);
int (*startup)(struct omap_mbox *mbox);
void (*shutdown)(struct omap_mbox *mbox);
/* fifo */
mbox_msg_t (*fifo_read)(struct omap_mbox *mbox);
void (*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg);
int (*fifo_empty)(struct omap_mbox *mbox);
int (*fifo_full)(struct omap_mbox *mbox);
mbox_msg_t (*fifo_read)(struct omap_mbox *mbox);
void (*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg);
int (*fifo_empty)(struct omap_mbox *mbox);
int (*fifo_full)(struct omap_mbox *mbox);
/* irq */
void (*enable_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
void (*disable_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
void (*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
int (*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
void (*enable_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
void (*disable_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
void (*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
int (*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
};
struct omap_mbox {
char *name;
spinlock_t lock;
unsigned int irq;
struct omap_mbox_ops *ops;
char *name;
spinlock_t lock;
unsigned int irq;
wait_queue_head_t tx_waitq;
struct workqueue_struct *workq;
struct work_struct msg_receive;
struct work_struct msg_receive;
void (*msg_receive_cb)(mbox_msg_t);
struct omap_mbq *mbq;
request_queue_t *txq, *rxq;
int (*msg_sender_cb)(void*);
void (*msg_receive_cb)(mbox_msg_t);
int (*msg_sender_cb)(void*);
mbox_msg_t seq_snd, seq_rcv;
struct omap_mbox_ops *ops;
struct device dev;
mbox_msg_t seq_snd, seq_rcv;
void *priv;
struct device dev;
struct omap_mbox *next;
struct omap_mbox *next;
void *priv;
void (*err_notify)(void);
};
int omap_mbox_msg_send(struct omap_mbox *mbox_h, mbox_msg_t msg, void* arg);
void omap_mbox_init_seq(struct omap_mbox *mbox);
int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg, void *);
void omap_mbox_init_seq(struct omap_mbox *);
struct omap_mbox *omap_mbox_get(const char *);
void omap_mbox_put(struct omap_mbox *);
struct omap_mbox *omap_mbox_get(const char *name);
int omap_mbox_register(struct omap_mbox *mbox);
int omap_mbox_unregister(struct omap_mbox *mbox);
int omap_mbox_register(struct omap_mbox *);
int omap_mbox_unregister(struct omap_mbox *);
#endif /* MAILBOX_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment