diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-21 14:21:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-21 14:21:19 -0400 |
commit | 43d451f163c1b615c1bedef95258c49712679eeb (patch) | |
tree | 52ed78b04435ffbd663a902bbd5bdb69a65ad584 /Documentation | |
parent | 21d2271fd0812ebe3716cab0b48356837485a74d (diff) | |
parent | 9f3e3cacb2ffdefe28c7cf490bf543e4dcb2770a (diff) |
Merge branch 'mailbox-for-linus' of git://git.linaro.org/landing-teams/working/fujitsu/integration
Pull mailbox framework from Jassi Brar:
"A framework for Mailbox controllers and clients have been cooking for
more than a year now.
Everybody in the CC list had been copied on patchset revisions and
most of them have made sounds of approval, though just one concrete
Reviewed-by. The patchset has also been in linux-next for a couple of
weeks now and no conflict has been reported. The framework has the
backing of at least 5 platforms, though I can't say if/when they
upstream their drivers (some businesses have 'changed')"
(Further acked-by by Arnd Bergmann and Suman Anna in the pull request
thread)
* 'mailbox-for-linus' of git://git.linaro.org/landing-teams/working/fujitsu/integration:
dt: mailbox: add generic bindings
doc: add documentation for mailbox framework
mailbox: Introduce framework for mailbox
mailbox: rename pl320-ipc specific mailbox.h
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/devicetree/bindings/mailbox/mailbox.txt | 38 | ||||
-rw-r--r-- | Documentation/mailbox.txt | 122 |
2 files changed, 160 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/mailbox/mailbox.txt b/Documentation/devicetree/bindings/mailbox/mailbox.txt new file mode 100644 index 000000000000..1a2cd3d266db --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/mailbox.txt | |||
@@ -0,0 +1,38 @@ | |||
1 | * Generic Mailbox Controller and client driver bindings | ||
2 | |||
3 | Generic binding to provide a way for Mailbox controller drivers to | ||
4 | assign appropriate mailbox channel to client drivers. | ||
5 | |||
6 | * Mailbox Controller | ||
7 | |||
8 | Required property: | ||
9 | - #mbox-cells: Must be at least 1. Number of cells in a mailbox | ||
10 | specifier. | ||
11 | |||
12 | Example: | ||
13 | mailbox: mailbox { | ||
14 | ... | ||
15 | #mbox-cells = <1>; | ||
16 | }; | ||
17 | |||
18 | |||
19 | * Mailbox Client | ||
20 | |||
21 | Required property: | ||
22 | - mboxes: List of phandle and mailbox channel specifiers. | ||
23 | |||
24 | Optional property: | ||
25 | - mbox-names: List of identifier strings for each mailbox channel | ||
26 | required by the client. The use of this property | ||
27 | is discouraged in favor of using index in list of | ||
28 | 'mboxes' while requesting a mailbox. Instead the | ||
29 | platforms may define channel indices, in DT headers, | ||
30 | to something legible. | ||
31 | |||
32 | Example: | ||
33 | pwr_cntrl: power { | ||
34 | ... | ||
35 | mbox-names = "pwr-ctrl", "rpc"; | ||
36 | mboxes = <&mailbox 0 | ||
37 | &mailbox 1>; | ||
38 | }; | ||
diff --git a/Documentation/mailbox.txt b/Documentation/mailbox.txt new file mode 100644 index 000000000000..60f43ff629aa --- /dev/null +++ b/Documentation/mailbox.txt | |||
@@ -0,0 +1,122 @@ | |||
1 | The Common Mailbox Framework | ||
2 | Jassi Brar <jaswinder.singh@linaro.org> | ||
3 | |||
4 | This document aims to help developers write client and controller | ||
5 | drivers for the API. But before we start, let us note that the | ||
6 | client (especially) and controller drivers are likely going to be | ||
7 | very platform specific because the remote firmware is likely to be | ||
8 | proprietary and implement non-standard protocol. So even if two | ||
9 | platforms employ, say, PL320 controller, the client drivers can't | ||
10 | be shared across them. Even the PL320 driver might need to accommodate | ||
11 | some platform specific quirks. So the API is meant mainly to avoid | ||
12 | similar copies of code written for each platform. Having said that, | ||
13 | nothing prevents the remote f/w to also be Linux based and use the | ||
14 | same api there. However none of that helps us locally because we only | ||
15 | ever deal at client's protocol level. | ||
16 | Some of the choices made during implementation are the result of this | ||
17 | peculiarity of this "common" framework. | ||
18 | |||
19 | |||
20 | |||
21 | Part 1 - Controller Driver (See include/linux/mailbox_controller.h) | ||
22 | |||
23 | Allocate mbox_controller and the array of mbox_chan. | ||
24 | Populate mbox_chan_ops, except peek_data() all are mandatory. | ||
25 | The controller driver might know a message has been consumed | ||
26 | by the remote by getting an IRQ or polling some hardware flag | ||
27 | or it can never know (the client knows by way of the protocol). | ||
28 | The method in order of preference is IRQ -> Poll -> None, which | ||
29 | the controller driver should set via 'txdone_irq' or 'txdone_poll' | ||
30 | or neither. | ||
31 | |||
32 | |||
33 | Part 2 - Client Driver (See include/linux/mailbox_client.h) | ||
34 | |||
35 | The client might want to operate in blocking mode (synchronously | ||
36 | send a message through before returning) or non-blocking/async mode (submit | ||
37 | a message and a callback function to the API and return immediately). | ||
38 | |||
39 | |||
40 | struct demo_client { | ||
41 | struct mbox_client cl; | ||
42 | struct mbox_chan *mbox; | ||
43 | struct completion c; | ||
44 | bool async; | ||
45 | /* ... */ | ||
46 | }; | ||
47 | |||
48 | /* | ||
49 | * This is the handler for data received from remote. The behaviour is purely | ||
50 | * dependent upon the protocol. This is just an example. | ||
51 | */ | ||
52 | static void message_from_remote(struct mbox_client *cl, void *mssg) | ||
53 | { | ||
54 | struct demo_client *dc = container_of(mbox_client, | ||
55 | struct demo_client, cl); | ||
56 | if (dc->aysnc) { | ||
57 | if (is_an_ack(mssg)) { | ||
58 | /* An ACK to our last sample sent */ | ||
59 | return; /* Or do something else here */ | ||
60 | } else { /* A new message from remote */ | ||
61 | queue_req(mssg); | ||
62 | } | ||
63 | } else { | ||
64 | /* Remote f/w sends only ACK packets on this channel */ | ||
65 | return; | ||
66 | } | ||
67 | } | ||
68 | |||
69 | static void sample_sent(struct mbox_client *cl, void *mssg, int r) | ||
70 | { | ||
71 | struct demo_client *dc = container_of(mbox_client, | ||
72 | struct demo_client, cl); | ||
73 | complete(&dc->c); | ||
74 | } | ||
75 | |||
76 | static void client_demo(struct platform_device *pdev) | ||
77 | { | ||
78 | struct demo_client *dc_sync, *dc_async; | ||
79 | /* The controller already knows async_pkt and sync_pkt */ | ||
80 | struct async_pkt ap; | ||
81 | struct sync_pkt sp; | ||
82 | |||
83 | dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL); | ||
84 | dc_async = kzalloc(sizeof(*dc_async), GFP_KERNEL); | ||
85 | |||
86 | /* Populate non-blocking mode client */ | ||
87 | dc_async->cl.dev = &pdev->dev; | ||
88 | dc_async->cl.rx_callback = message_from_remote; | ||
89 | dc_async->cl.tx_done = sample_sent; | ||
90 | dc_async->cl.tx_block = false; | ||
91 | dc_async->cl.tx_tout = 0; /* doesn't matter here */ | ||
92 | dc_async->cl.knows_txdone = false; /* depending upon protocol */ | ||
93 | dc_async->async = true; | ||
94 | init_completion(&dc_async->c); | ||
95 | |||
96 | /* Populate blocking mode client */ | ||
97 | dc_sync->cl.dev = &pdev->dev; | ||
98 | dc_sync->cl.rx_callback = message_from_remote; | ||
99 | dc_sync->cl.tx_done = NULL; /* operate in blocking mode */ | ||
100 | dc_sync->cl.tx_block = true; | ||
101 | dc_sync->cl.tx_tout = 500; /* by half a second */ | ||
102 | dc_sync->cl.knows_txdone = false; /* depending upon protocol */ | ||
103 | dc_sync->async = false; | ||
104 | |||
105 | /* ASync mailbox is listed second in 'mboxes' property */ | ||
106 | dc_async->mbox = mbox_request_channel(&dc_async->cl, 1); | ||
107 | /* Populate data packet */ | ||
108 | /* ap.xxx = 123; etc */ | ||
109 | /* Send async message to remote */ | ||
110 | mbox_send_message(dc_async->mbox, &ap); | ||
111 | |||
112 | /* Sync mailbox is listed first in 'mboxes' property */ | ||
113 | dc_sync->mbox = mbox_request_channel(&dc_sync->cl, 0); | ||
114 | /* Populate data packet */ | ||
115 | /* sp.abc = 123; etc */ | ||
116 | /* Send message to remote in blocking mode */ | ||
117 | mbox_send_message(dc_sync->mbox, &sp); | ||
118 | /* At this point 'sp' has been sent */ | ||
119 | |||
120 | /* Now wait for async chan to be done */ | ||
121 | wait_for_completion(&dc_async->c); | ||
122 | } | ||