diff options
Diffstat (limited to 'drivers/misc/mei/wd.c')
-rw-r--r-- | drivers/misc/mei/wd.c | 77 |
1 files changed, 44 insertions, 33 deletions
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 9299a8c29a6f..2413247fc392 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c | |||
@@ -21,11 +21,13 @@ | |||
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | #include <linux/watchdog.h> | 22 | #include <linux/watchdog.h> |
23 | 23 | ||
24 | #include "mei_dev.h" | ||
25 | #include "hw.h" | ||
26 | #include "interface.h" | ||
27 | #include <linux/mei.h> | 24 | #include <linux/mei.h> |
28 | 25 | ||
26 | #include "mei_dev.h" | ||
27 | #include "hbm.h" | ||
28 | #include "hw-me.h" | ||
29 | #include "client.h" | ||
30 | |||
29 | static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; | 31 | static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; |
30 | static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; | 32 | static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; |
31 | 33 | ||
@@ -62,30 +64,41 @@ static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout) | |||
62 | */ | 64 | */ |
63 | int mei_wd_host_init(struct mei_device *dev) | 65 | int mei_wd_host_init(struct mei_device *dev) |
64 | { | 66 | { |
65 | int id; | 67 | struct mei_cl *cl = &dev->wd_cl; |
66 | mei_cl_init(&dev->wd_cl, dev); | 68 | int i; |
69 | int ret; | ||
70 | |||
71 | mei_cl_init(cl, dev); | ||
67 | 72 | ||
68 | /* look for WD client and connect to it */ | ||
69 | dev->wd_cl.state = MEI_FILE_DISCONNECTED; | ||
70 | dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT; | 73 | dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT; |
71 | dev->wd_state = MEI_WD_IDLE; | 74 | dev->wd_state = MEI_WD_IDLE; |
72 | 75 | ||
73 | /* Connect WD ME client to the host client */ | ||
74 | id = mei_me_cl_link(dev, &dev->wd_cl, | ||
75 | &mei_wd_guid, MEI_WD_HOST_CLIENT_ID); | ||
76 | 76 | ||
77 | if (id < 0) { | 77 | /* check for valid client id */ |
78 | i = mei_me_cl_by_uuid(dev, &mei_wd_guid); | ||
79 | if (i < 0) { | ||
78 | dev_info(&dev->pdev->dev, "wd: failed to find the client\n"); | 80 | dev_info(&dev->pdev->dev, "wd: failed to find the client\n"); |
79 | return -ENOENT; | 81 | return -ENOENT; |
80 | } | 82 | } |
81 | 83 | ||
82 | if (mei_connect(dev, &dev->wd_cl)) { | 84 | cl->me_client_id = dev->me_clients[i].client_id; |
85 | |||
86 | ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID); | ||
87 | |||
88 | if (ret < 0) { | ||
89 | dev_info(&dev->pdev->dev, "wd: failed link client\n"); | ||
90 | return -ENOENT; | ||
91 | } | ||
92 | |||
93 | cl->state = MEI_FILE_CONNECTING; | ||
94 | |||
95 | if (mei_hbm_cl_connect_req(dev, cl)) { | ||
83 | dev_err(&dev->pdev->dev, "wd: failed to connect to the client\n"); | 96 | dev_err(&dev->pdev->dev, "wd: failed to connect to the client\n"); |
84 | dev->wd_cl.state = MEI_FILE_DISCONNECTED; | 97 | cl->state = MEI_FILE_DISCONNECTED; |
85 | dev->wd_cl.host_client_id = 0; | 98 | cl->host_client_id = 0; |
86 | return -EIO; | 99 | return -EIO; |
87 | } | 100 | } |
88 | dev->wd_cl.timer_count = MEI_CONNECT_TIMEOUT; | 101 | cl->timer_count = MEI_CONNECT_TIMEOUT; |
89 | 102 | ||
90 | return 0; | 103 | return 0; |
91 | } | 104 | } |
@@ -101,22 +114,21 @@ int mei_wd_host_init(struct mei_device *dev) | |||
101 | */ | 114 | */ |
102 | int mei_wd_send(struct mei_device *dev) | 115 | int mei_wd_send(struct mei_device *dev) |
103 | { | 116 | { |
104 | struct mei_msg_hdr *mei_hdr; | 117 | struct mei_msg_hdr hdr; |
105 | 118 | ||
106 | mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; | 119 | hdr.host_addr = dev->wd_cl.host_client_id; |
107 | mei_hdr->host_addr = dev->wd_cl.host_client_id; | 120 | hdr.me_addr = dev->wd_cl.me_client_id; |
108 | mei_hdr->me_addr = dev->wd_cl.me_client_id; | 121 | hdr.msg_complete = 1; |
109 | mei_hdr->msg_complete = 1; | 122 | hdr.reserved = 0; |
110 | mei_hdr->reserved = 0; | ||
111 | 123 | ||
112 | if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE)) | 124 | if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE)) |
113 | mei_hdr->length = MEI_WD_START_MSG_SIZE; | 125 | hdr.length = MEI_WD_START_MSG_SIZE; |
114 | else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_HDR_SIZE)) | 126 | else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_HDR_SIZE)) |
115 | mei_hdr->length = MEI_WD_STOP_MSG_SIZE; | 127 | hdr.length = MEI_WD_STOP_MSG_SIZE; |
116 | else | 128 | else |
117 | return -EINVAL; | 129 | return -EINVAL; |
118 | 130 | ||
119 | return mei_write_message(dev, mei_hdr, dev->wd_data, mei_hdr->length); | 131 | return mei_write_message(dev, &hdr, dev->wd_data); |
120 | } | 132 | } |
121 | 133 | ||
122 | /** | 134 | /** |
@@ -141,16 +153,16 @@ int mei_wd_stop(struct mei_device *dev) | |||
141 | 153 | ||
142 | dev->wd_state = MEI_WD_STOPPING; | 154 | dev->wd_state = MEI_WD_STOPPING; |
143 | 155 | ||
144 | ret = mei_flow_ctrl_creds(dev, &dev->wd_cl); | 156 | ret = mei_cl_flow_ctrl_creds(&dev->wd_cl); |
145 | if (ret < 0) | 157 | if (ret < 0) |
146 | goto out; | 158 | goto out; |
147 | 159 | ||
148 | if (ret && dev->mei_host_buffer_is_empty) { | 160 | if (ret && dev->hbuf_is_ready) { |
149 | ret = 0; | 161 | ret = 0; |
150 | dev->mei_host_buffer_is_empty = false; | 162 | dev->hbuf_is_ready = false; |
151 | 163 | ||
152 | if (!mei_wd_send(dev)) { | 164 | if (!mei_wd_send(dev)) { |
153 | ret = mei_flow_ctrl_reduce(dev, &dev->wd_cl); | 165 | ret = mei_cl_flow_ctrl_reduce(&dev->wd_cl); |
154 | if (ret) | 166 | if (ret) |
155 | goto out; | 167 | goto out; |
156 | } else { | 168 | } else { |
@@ -270,10 +282,9 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) | |||
270 | dev->wd_state = MEI_WD_RUNNING; | 282 | dev->wd_state = MEI_WD_RUNNING; |
271 | 283 | ||
272 | /* Check if we can send the ping to HW*/ | 284 | /* Check if we can send the ping to HW*/ |
273 | if (dev->mei_host_buffer_is_empty && | 285 | if (dev->hbuf_is_ready && mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) { |
274 | mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { | ||
275 | 286 | ||
276 | dev->mei_host_buffer_is_empty = false; | 287 | dev->hbuf_is_ready = false; |
277 | dev_dbg(&dev->pdev->dev, "wd: sending ping\n"); | 288 | dev_dbg(&dev->pdev->dev, "wd: sending ping\n"); |
278 | 289 | ||
279 | if (mei_wd_send(dev)) { | 290 | if (mei_wd_send(dev)) { |
@@ -282,9 +293,9 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) | |||
282 | goto end; | 293 | goto end; |
283 | } | 294 | } |
284 | 295 | ||
285 | if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) { | 296 | if (mei_cl_flow_ctrl_reduce(&dev->wd_cl)) { |
286 | dev_err(&dev->pdev->dev, | 297 | dev_err(&dev->pdev->dev, |
287 | "wd: mei_flow_ctrl_reduce() failed.\n"); | 298 | "wd: mei_cl_flow_ctrl_reduce() failed.\n"); |
288 | ret = -EIO; | 299 | ret = -EIO; |
289 | goto end; | 300 | goto end; |
290 | } | 301 | } |