1 /* mailbox.h */
2 
3 #ifndef MAILBOX_H
4 #define MAILBOX_H
5 
6 #include <linux/spinlock.h>
7 #include <linux/workqueue.h>
8 #include <linux/interrupt.h>
9 #include <linux/device.h>
10 #include <linux/kfifo.h>
11 
12 typedef u32 mbox_msg_t;
13 struct omap_mbox;
14 
15 typedef int __bitwise omap_mbox_irq_t;
16 #define IRQ_TX ((__force omap_mbox_irq_t) 1)
17 #define IRQ_RX ((__force omap_mbox_irq_t) 2)
18 
19 typedef int __bitwise omap_mbox_type_t;
20 #define OMAP_MBOX_TYPE1 ((__force omap_mbox_type_t) 1)
21 #define OMAP_MBOX_TYPE2 ((__force omap_mbox_type_t) 2)
22 
23 struct omap_mbox_ops {
24 	omap_mbox_type_t	type;
25 	int		(*startup)(struct omap_mbox *mbox);
26 	void		(*shutdown)(struct omap_mbox *mbox);
27 	/* fifo */
28 	mbox_msg_t	(*fifo_read)(struct omap_mbox *mbox);
29 	void		(*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg);
30 	int		(*fifo_empty)(struct omap_mbox *mbox);
31 	int		(*fifo_full)(struct omap_mbox *mbox);
32 	/* irq */
33 	void		(*enable_irq)(struct omap_mbox *mbox,
34 						omap_mbox_irq_t irq);
35 	void		(*disable_irq)(struct omap_mbox *mbox,
36 						omap_mbox_irq_t irq);
37 	void		(*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
38 	int		(*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
39 	/* ctx */
40 	void		(*save_ctx)(struct omap_mbox *mbox);
41 	void		(*restore_ctx)(struct omap_mbox *mbox);
42 };
43 
44 struct omap_mbox_queue {
45 	spinlock_t		lock;
46 	struct kfifo		fifo;
47 	struct work_struct	work;
48 	struct tasklet_struct	tasklet;
49 	struct omap_mbox	*mbox;
50 	bool full;
51 };
52 
53 struct omap_mbox {
54 	char			*name;
55 	unsigned int		irq;
56 	struct omap_mbox_queue	*txq, *rxq;
57 	struct omap_mbox_ops	*ops;
58 	struct device		*dev;
59 	void			*priv;
60 	int			use_count;
61 	struct blocking_notifier_head   notifier;
62 };
63 
64 int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
65 void omap_mbox_init_seq(struct omap_mbox *);
66 
67 struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);
68 void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb);
69 
70 int omap_mbox_register(struct device *parent, struct omap_mbox **);
71 int omap_mbox_unregister(void);
72 
omap_mbox_save_ctx(struct omap_mbox * mbox)73 static inline void omap_mbox_save_ctx(struct omap_mbox *mbox)
74 {
75 	if (!mbox->ops->save_ctx) {
76 		dev_err(mbox->dev, "%s:\tno save\n", __func__);
77 		return;
78 	}
79 
80 	mbox->ops->save_ctx(mbox);
81 }
82 
omap_mbox_restore_ctx(struct omap_mbox * mbox)83 static inline void omap_mbox_restore_ctx(struct omap_mbox *mbox)
84 {
85 	if (!mbox->ops->restore_ctx) {
86 		dev_err(mbox->dev, "%s:\tno restore\n", __func__);
87 		return;
88 	}
89 
90 	mbox->ops->restore_ctx(mbox);
91 }
92 
omap_mbox_enable_irq(struct omap_mbox * mbox,omap_mbox_irq_t irq)93 static inline void omap_mbox_enable_irq(struct omap_mbox *mbox,
94 					omap_mbox_irq_t irq)
95 {
96 	mbox->ops->enable_irq(mbox, irq);
97 }
98 
omap_mbox_disable_irq(struct omap_mbox * mbox,omap_mbox_irq_t irq)99 static inline void omap_mbox_disable_irq(struct omap_mbox *mbox,
100 					 omap_mbox_irq_t irq)
101 {
102 	mbox->ops->disable_irq(mbox, irq);
103 }
104 
105 #endif /* MAILBOX_H */
106