source: mainline/uspace/lib/drv/generic/remote_hw_res.c@ c280d7e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c280d7e was d51838f, checked in by Jiri Svoboda <jiri@…>, 8 years ago

Let leaf drivers enable/disable/clear interrupts via hw_res instead of directly using irc.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 * Copyright (c) 2010 Lenka Trochtova
3 * Copyright (c) 2011 Jan Vesely
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup libdrv
31 * @{
32 */
33/** @file
34 */
35
36#include <async.h>
37#include <errno.h>
38#include <macros.h>
39
40#include "ops/hw_res.h"
41#include "ddf/driver.h"
42
43static void remote_hw_res_get_resource_list(ddf_fun_t *, void *, ipc_callid_t,
44 ipc_call_t *);
45static void remote_hw_res_enable_interrupt(ddf_fun_t *, void *, ipc_callid_t,
46 ipc_call_t *);
47static void remote_hw_res_disable_interrupt(ddf_fun_t *, void *, ipc_callid_t,
48 ipc_call_t *);
49static void remote_hw_res_clear_interrupt(ddf_fun_t *, void *, ipc_callid_t,
50 ipc_call_t *);
51static void remote_hw_res_dma_channel_setup(ddf_fun_t *, void *, ipc_callid_t,
52 ipc_call_t *);
53static void remote_hw_res_dma_channel_remain(ddf_fun_t *, void *, ipc_callid_t,
54 ipc_call_t *);
55
56static const remote_iface_func_ptr_t remote_hw_res_iface_ops [] = {
57 [HW_RES_GET_RESOURCE_LIST] = &remote_hw_res_get_resource_list,
58 [HW_RES_ENABLE_INTERRUPT] = &remote_hw_res_enable_interrupt,
59 [HW_RES_DISABLE_INTERRUPT] = &remote_hw_res_disable_interrupt,
60 [HW_RES_CLEAR_INTERRUPT] = &remote_hw_res_clear_interrupt,
61 [HW_RES_DMA_CHANNEL_SETUP] = &remote_hw_res_dma_channel_setup,
62 [HW_RES_DMA_CHANNEL_REMAIN] = &remote_hw_res_dma_channel_remain,
63};
64
65const remote_iface_t remote_hw_res_iface = {
66 .method_count = ARRAY_SIZE(remote_hw_res_iface_ops),
67 .methods = remote_hw_res_iface_ops
68};
69
70static void remote_hw_res_enable_interrupt(ddf_fun_t *fun, void *ops,
71 ipc_callid_t callid, ipc_call_t *call)
72{
73 hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
74
75 if (hw_res_ops->enable_interrupt == NULL) {
76 async_answer_0(callid, ENOTSUP);
77 return;
78 }
79
80 const int irq = DEV_IPC_GET_ARG1(*call);
81 const int ret = hw_res_ops->enable_interrupt(fun, irq);
82 async_answer_0(callid, ret);
83}
84
85static void remote_hw_res_disable_interrupt(ddf_fun_t *fun, void *ops,
86 ipc_callid_t callid, ipc_call_t *call)
87{
88 hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
89
90 if (hw_res_ops->disable_interrupt == NULL) {
91 async_answer_0(callid, ENOTSUP);
92 return;
93 }
94
95 const int irq = DEV_IPC_GET_ARG1(*call);
96 const int ret = hw_res_ops->disable_interrupt(fun, irq);
97 async_answer_0(callid, ret);
98}
99
100static void remote_hw_res_clear_interrupt(ddf_fun_t *fun, void *ops,
101 ipc_callid_t callid, ipc_call_t *call)
102{
103 hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
104
105 if (hw_res_ops->clear_interrupt == NULL) {
106 async_answer_0(callid, ENOTSUP);
107 return;
108 }
109
110 const int irq = DEV_IPC_GET_ARG1(*call);
111 const int ret = hw_res_ops->enable_interrupt(fun, irq);
112 async_answer_0(callid, ret);
113}
114
115static void remote_hw_res_get_resource_list(ddf_fun_t *fun, void *ops,
116 ipc_callid_t callid, ipc_call_t *call)
117{
118 hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
119
120 if (hw_res_ops->get_resource_list == NULL) {
121 async_answer_0(callid, ENOTSUP);
122 return;
123 }
124
125 hw_resource_list_t *hw_resources = hw_res_ops->get_resource_list(fun);
126 if (hw_resources == NULL){
127 async_answer_0(callid, ENOENT);
128 return;
129 }
130
131 async_answer_1(callid, EOK, hw_resources->count);
132
133 size_t len;
134 if (!async_data_read_receive(&callid, &len)) {
135 /* Protocol error - the recipient is not accepting data */
136 return;
137 }
138 async_data_read_finalize(callid, hw_resources->resources, len);
139}
140
141static void remote_hw_res_dma_channel_setup(ddf_fun_t *fun, void *ops,
142 ipc_callid_t callid, ipc_call_t *call)
143{
144 hw_res_ops_t *hw_res_ops = ops;
145
146 if (hw_res_ops->dma_channel_setup == NULL) {
147 async_answer_0(callid, ENOTSUP);
148 return;
149 }
150 const unsigned channel = DEV_IPC_GET_ARG1(*call) & 0xffff;
151 const uint8_t mode = DEV_IPC_GET_ARG1(*call) >> 16;
152 const uint32_t address = DEV_IPC_GET_ARG2(*call);
153 const uint32_t size = DEV_IPC_GET_ARG3(*call);
154
155 const int ret = hw_res_ops->dma_channel_setup(
156 fun, channel, address, size, mode);
157 async_answer_0(callid, ret);
158}
159
160static void remote_hw_res_dma_channel_remain(ddf_fun_t *fun, void *ops,
161 ipc_callid_t callid, ipc_call_t *call)
162{
163 hw_res_ops_t *hw_res_ops = ops;
164
165 if (hw_res_ops->dma_channel_setup == NULL) {
166 async_answer_0(callid, ENOTSUP);
167 return;
168 }
169 const unsigned channel = DEV_IPC_GET_ARG1(*call);
170 size_t remain = 0;
171 const int ret = hw_res_ops->dma_channel_remain(fun, channel, &remain);
172 async_answer_1(callid, ret, remain);
173}
174/**
175 * @}
176 */
Note: See TracBrowser for help on using the repository browser.