1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Intel MIC Platform Software Stack (MPSS)
4  *
5  * Copyright(c) 2013 Intel Corporation.
6  *
7  * Intel MIC Host driver.
8  */
9 #include <linux/delay.h>
10 #include <linux/firmware.h>
11 #include <linux/pci.h>
12 #include <linux/kmod.h>
13 #include <linux/mic_common.h>
14 #include <linux/mic_bus.h>
15 #include "../bus/scif_bus.h"
16 #include "../bus/vop_bus.h"
17 #include "../common/mic_dev.h"
18 #include "mic_device.h"
19 #include "mic_smpt.h"
20 
vpdev_to_mdev(struct device * dev)21 static inline struct mic_device *vpdev_to_mdev(struct device *dev)
22 {
23 	return dev_get_drvdata(dev->parent);
24 }
25 
26 static dma_addr_t
_mic_dma_map_page(struct device * dev,struct page * page,unsigned long offset,size_t size,enum dma_data_direction dir,unsigned long attrs)27 _mic_dma_map_page(struct device *dev, struct page *page,
28 		  unsigned long offset, size_t size,
29 		  enum dma_data_direction dir, unsigned long attrs)
30 {
31 	void *va = phys_to_virt(page_to_phys(page)) + offset;
32 	struct mic_device *mdev = vpdev_to_mdev(dev);
33 
34 	return mic_map_single(mdev, va, size);
35 }
36 
_mic_dma_unmap_page(struct device * dev,dma_addr_t dma_addr,size_t size,enum dma_data_direction dir,unsigned long attrs)37 static void _mic_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
38 				size_t size, enum dma_data_direction dir,
39 				unsigned long attrs)
40 {
41 	struct mic_device *mdev = vpdev_to_mdev(dev);
42 
43 	mic_unmap_single(mdev, dma_addr, size);
44 }
45 
46 static const struct dma_map_ops _mic_dma_ops = {
47 	.map_page = _mic_dma_map_page,
48 	.unmap_page = _mic_dma_unmap_page,
49 };
50 
51 static struct mic_irq *
__mic_request_irq(struct vop_device * vpdev,irqreturn_t (* func)(int irq,void * data),const char * name,void * data,int intr_src)52 __mic_request_irq(struct vop_device *vpdev,
53 		  irqreturn_t (*func)(int irq, void *data),
54 		  const char *name, void *data, int intr_src)
55 {
56 	struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev);
57 
58 	return mic_request_threaded_irq(mdev, func, NULL, name, data,
59 					intr_src, MIC_INTR_DB);
60 }
61 
__mic_free_irq(struct vop_device * vpdev,struct mic_irq * cookie,void * data)62 static void __mic_free_irq(struct vop_device *vpdev,
63 			   struct mic_irq *cookie, void *data)
64 {
65 	struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev);
66 
67 	mic_free_irq(mdev, cookie, data);
68 }
69 
__mic_ack_interrupt(struct vop_device * vpdev,int num)70 static void __mic_ack_interrupt(struct vop_device *vpdev, int num)
71 {
72 	struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev);
73 
74 	mdev->ops->intr_workarounds(mdev);
75 }
76 
__mic_next_db(struct vop_device * vpdev)77 static int __mic_next_db(struct vop_device *vpdev)
78 {
79 	struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev);
80 
81 	return mic_next_db(mdev);
82 }
83 
__mic_get_dp(struct vop_device * vpdev)84 static void *__mic_get_dp(struct vop_device *vpdev)
85 {
86 	struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev);
87 
88 	return mdev->dp;
89 }
90 
__mic_get_remote_dp(struct vop_device * vpdev)91 static void __iomem *__mic_get_remote_dp(struct vop_device *vpdev)
92 {
93 	return NULL;
94 }
95 
__mic_send_intr(struct vop_device * vpdev,int db)96 static void __mic_send_intr(struct vop_device *vpdev, int db)
97 {
98 	struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev);
99 
100 	mdev->ops->send_intr(mdev, db);
101 }
102 
__mic_ioremap(struct vop_device * vpdev,dma_addr_t pa,size_t len)103 static void __iomem *__mic_ioremap(struct vop_device *vpdev,
104 				   dma_addr_t pa, size_t len)
105 {
106 	struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev);
107 
108 	return mdev->aper.va + pa;
109 }
110 
__mic_iounmap(struct vop_device * vpdev,void __iomem * va)111 static void __mic_iounmap(struct vop_device *vpdev, void __iomem *va)
112 {
113 	/* nothing to do */
114 }
115 
116 static struct vop_hw_ops vop_hw_ops = {
117 	.request_irq = __mic_request_irq,
118 	.free_irq = __mic_free_irq,
119 	.ack_interrupt = __mic_ack_interrupt,
120 	.next_db = __mic_next_db,
121 	.get_dp = __mic_get_dp,
122 	.get_remote_dp = __mic_get_remote_dp,
123 	.send_intr = __mic_send_intr,
124 	.remap = __mic_ioremap,
125 	.unmap = __mic_iounmap,
126 };
127 
scdev_to_mdev(struct scif_hw_dev * scdev)128 static inline struct mic_device *scdev_to_mdev(struct scif_hw_dev *scdev)
129 {
130 	return dev_get_drvdata(scdev->dev.parent);
131 }
132 
__mic_dma_alloc(struct device * dev,size_t size,dma_addr_t * dma_handle,gfp_t gfp,unsigned long attrs)133 static void *__mic_dma_alloc(struct device *dev, size_t size,
134 			     dma_addr_t *dma_handle, gfp_t gfp,
135 			     unsigned long attrs)
136 {
137 	struct scif_hw_dev *scdev = dev_get_drvdata(dev);
138 	struct mic_device *mdev = scdev_to_mdev(scdev);
139 	dma_addr_t tmp;
140 	void *va = kmalloc(size, gfp | __GFP_ZERO);
141 
142 	if (va) {
143 		tmp = mic_map_single(mdev, va, size);
144 		if (dma_mapping_error(dev, tmp)) {
145 			kfree(va);
146 			va = NULL;
147 		} else {
148 			*dma_handle = tmp;
149 		}
150 	}
151 	return va;
152 }
153 
__mic_dma_free(struct device * dev,size_t size,void * vaddr,dma_addr_t dma_handle,unsigned long attrs)154 static void __mic_dma_free(struct device *dev, size_t size, void *vaddr,
155 			   dma_addr_t dma_handle, unsigned long attrs)
156 {
157 	struct scif_hw_dev *scdev = dev_get_drvdata(dev);
158 	struct mic_device *mdev = scdev_to_mdev(scdev);
159 
160 	mic_unmap_single(mdev, dma_handle, size);
161 	kfree(vaddr);
162 }
163 
164 static dma_addr_t
__mic_dma_map_page(struct device * dev,struct page * page,unsigned long offset,size_t size,enum dma_data_direction dir,unsigned long attrs)165 __mic_dma_map_page(struct device *dev, struct page *page, unsigned long offset,
166 		   size_t size, enum dma_data_direction dir,
167 		   unsigned long attrs)
168 {
169 	void *va = phys_to_virt(page_to_phys(page)) + offset;
170 	struct scif_hw_dev *scdev = dev_get_drvdata(dev);
171 	struct mic_device *mdev = scdev_to_mdev(scdev);
172 
173 	return mic_map_single(mdev, va, size);
174 }
175 
176 static void
__mic_dma_unmap_page(struct device * dev,dma_addr_t dma_addr,size_t size,enum dma_data_direction dir,unsigned long attrs)177 __mic_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
178 		     size_t size, enum dma_data_direction dir,
179 		     unsigned long attrs)
180 {
181 	struct scif_hw_dev *scdev = dev_get_drvdata(dev);
182 	struct mic_device *mdev = scdev_to_mdev(scdev);
183 
184 	mic_unmap_single(mdev, dma_addr, size);
185 }
186 
__mic_dma_map_sg(struct device * dev,struct scatterlist * sg,int nents,enum dma_data_direction dir,unsigned long attrs)187 static int __mic_dma_map_sg(struct device *dev, struct scatterlist *sg,
188 			    int nents, enum dma_data_direction dir,
189 			    unsigned long attrs)
190 {
191 	struct scif_hw_dev *scdev = dev_get_drvdata(dev);
192 	struct mic_device *mdev = scdev_to_mdev(scdev);
193 	struct scatterlist *s;
194 	int i, j, ret;
195 	dma_addr_t da;
196 
197 	ret = dma_map_sg(&mdev->pdev->dev, sg, nents, dir);
198 	if (ret <= 0)
199 		return 0;
200 
201 	for_each_sg(sg, s, nents, i) {
202 		da = mic_map(mdev, sg_dma_address(s) + s->offset, s->length);
203 		if (!da)
204 			goto err;
205 		sg_dma_address(s) = da;
206 	}
207 	return nents;
208 err:
209 	for_each_sg(sg, s, i, j) {
210 		mic_unmap(mdev, sg_dma_address(s), s->length);
211 		sg_dma_address(s) = mic_to_dma_addr(mdev, sg_dma_address(s));
212 	}
213 	dma_unmap_sg(&mdev->pdev->dev, sg, nents, dir);
214 	return 0;
215 }
216 
__mic_dma_unmap_sg(struct device * dev,struct scatterlist * sg,int nents,enum dma_data_direction dir,unsigned long attrs)217 static void __mic_dma_unmap_sg(struct device *dev,
218 			       struct scatterlist *sg, int nents,
219 			       enum dma_data_direction dir,
220 			       unsigned long attrs)
221 {
222 	struct scif_hw_dev *scdev = dev_get_drvdata(dev);
223 	struct mic_device *mdev = scdev_to_mdev(scdev);
224 	struct scatterlist *s;
225 	dma_addr_t da;
226 	int i;
227 
228 	for_each_sg(sg, s, nents, i) {
229 		da = mic_to_dma_addr(mdev, sg_dma_address(s));
230 		mic_unmap(mdev, sg_dma_address(s), s->length);
231 		sg_dma_address(s) = da;
232 	}
233 	dma_unmap_sg(&mdev->pdev->dev, sg, nents, dir);
234 }
235 
236 static const struct dma_map_ops __mic_dma_ops = {
237 	.alloc = __mic_dma_alloc,
238 	.free = __mic_dma_free,
239 	.map_page = __mic_dma_map_page,
240 	.unmap_page = __mic_dma_unmap_page,
241 	.map_sg = __mic_dma_map_sg,
242 	.unmap_sg = __mic_dma_unmap_sg,
243 };
244 
245 static struct mic_irq *
___mic_request_irq(struct scif_hw_dev * scdev,irqreturn_t (* func)(int irq,void * data),const char * name,void * data,int db)246 ___mic_request_irq(struct scif_hw_dev *scdev,
247 		   irqreturn_t (*func)(int irq, void *data),
248 				       const char *name,
249 				       void *data, int db)
250 {
251 	struct mic_device *mdev = scdev_to_mdev(scdev);
252 
253 	return mic_request_threaded_irq(mdev, func, NULL, name, data,
254 					db, MIC_INTR_DB);
255 }
256 
257 static void
___mic_free_irq(struct scif_hw_dev * scdev,struct mic_irq * cookie,void * data)258 ___mic_free_irq(struct scif_hw_dev *scdev,
259 		struct mic_irq *cookie, void *data)
260 {
261 	struct mic_device *mdev = scdev_to_mdev(scdev);
262 
263 	mic_free_irq(mdev, cookie, data);
264 }
265 
___mic_ack_interrupt(struct scif_hw_dev * scdev,int num)266 static void ___mic_ack_interrupt(struct scif_hw_dev *scdev, int num)
267 {
268 	struct mic_device *mdev = scdev_to_mdev(scdev);
269 
270 	mdev->ops->intr_workarounds(mdev);
271 }
272 
___mic_next_db(struct scif_hw_dev * scdev)273 static int ___mic_next_db(struct scif_hw_dev *scdev)
274 {
275 	struct mic_device *mdev = scdev_to_mdev(scdev);
276 
277 	return mic_next_db(mdev);
278 }
279 
___mic_send_intr(struct scif_hw_dev * scdev,int db)280 static void ___mic_send_intr(struct scif_hw_dev *scdev, int db)
281 {
282 	struct mic_device *mdev = scdev_to_mdev(scdev);
283 
284 	mdev->ops->send_intr(mdev, db);
285 }
286 
___mic_ioremap(struct scif_hw_dev * scdev,phys_addr_t pa,size_t len)287 static void __iomem *___mic_ioremap(struct scif_hw_dev *scdev,
288 				    phys_addr_t pa, size_t len)
289 {
290 	struct mic_device *mdev = scdev_to_mdev(scdev);
291 
292 	return mdev->aper.va + pa;
293 }
294 
___mic_iounmap(struct scif_hw_dev * scdev,void __iomem * va)295 static void ___mic_iounmap(struct scif_hw_dev *scdev, void __iomem *va)
296 {
297 	/* nothing to do */
298 }
299 
300 static struct scif_hw_ops scif_hw_ops = {
301 	.request_irq = ___mic_request_irq,
302 	.free_irq = ___mic_free_irq,
303 	.ack_interrupt = ___mic_ack_interrupt,
304 	.next_db = ___mic_next_db,
305 	.send_intr = ___mic_send_intr,
306 	.remap = ___mic_ioremap,
307 	.unmap = ___mic_iounmap,
308 };
309 
mbdev_to_mdev(struct mbus_device * mbdev)310 static inline struct mic_device *mbdev_to_mdev(struct mbus_device *mbdev)
311 {
312 	return dev_get_drvdata(mbdev->dev.parent);
313 }
314 
315 static dma_addr_t
mic_dma_map_page(struct device * dev,struct page * page,unsigned long offset,size_t size,enum dma_data_direction dir,unsigned long attrs)316 mic_dma_map_page(struct device *dev, struct page *page,
317 		 unsigned long offset, size_t size, enum dma_data_direction dir,
318 		 unsigned long attrs)
319 {
320 	void *va = phys_to_virt(page_to_phys(page)) + offset;
321 	struct mic_device *mdev = dev_get_drvdata(dev->parent);
322 
323 	return mic_map_single(mdev, va, size);
324 }
325 
326 static void
mic_dma_unmap_page(struct device * dev,dma_addr_t dma_addr,size_t size,enum dma_data_direction dir,unsigned long attrs)327 mic_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
328 		   size_t size, enum dma_data_direction dir,
329 		   unsigned long attrs)
330 {
331 	struct mic_device *mdev = dev_get_drvdata(dev->parent);
332 	mic_unmap_single(mdev, dma_addr, size);
333 }
334 
335 static const struct dma_map_ops mic_dma_ops = {
336 	.map_page = mic_dma_map_page,
337 	.unmap_page = mic_dma_unmap_page,
338 };
339 
340 static struct mic_irq *
_mic_request_threaded_irq(struct mbus_device * mbdev,irq_handler_t handler,irq_handler_t thread_fn,const char * name,void * data,int intr_src)341 _mic_request_threaded_irq(struct mbus_device *mbdev,
342 			  irq_handler_t handler, irq_handler_t thread_fn,
343 			  const char *name, void *data, int intr_src)
344 {
345 	return mic_request_threaded_irq(mbdev_to_mdev(mbdev), handler,
346 					thread_fn, name, data,
347 					intr_src, MIC_INTR_DMA);
348 }
349 
_mic_free_irq(struct mbus_device * mbdev,struct mic_irq * cookie,void * data)350 static void _mic_free_irq(struct mbus_device *mbdev,
351 			  struct mic_irq *cookie, void *data)
352 {
353 	mic_free_irq(mbdev_to_mdev(mbdev), cookie, data);
354 }
355 
_mic_ack_interrupt(struct mbus_device * mbdev,int num)356 static void _mic_ack_interrupt(struct mbus_device *mbdev, int num)
357 {
358 	struct mic_device *mdev = mbdev_to_mdev(mbdev);
359 	mdev->ops->intr_workarounds(mdev);
360 }
361 
362 static struct mbus_hw_ops mbus_hw_ops = {
363 	.request_threaded_irq = _mic_request_threaded_irq,
364 	.free_irq = _mic_free_irq,
365 	.ack_interrupt = _mic_ack_interrupt,
366 };
367 
368 /* Initialize the MIC bootparams */
mic_bootparam_init(struct mic_device * mdev)369 void mic_bootparam_init(struct mic_device *mdev)
370 {
371 	struct mic_bootparam *bootparam = mdev->dp;
372 
373 	bootparam->magic = cpu_to_le32(MIC_MAGIC);
374 	bootparam->h2c_config_db = -1;
375 	bootparam->node_id = mdev->id + 1;
376 	bootparam->scif_host_dma_addr = 0x0;
377 	bootparam->scif_card_dma_addr = 0x0;
378 	bootparam->c2h_scif_db = -1;
379 	bootparam->h2c_scif_db = -1;
380 }
381 
cosmdev_to_mdev(struct cosm_device * cdev)382 static inline struct mic_device *cosmdev_to_mdev(struct cosm_device *cdev)
383 {
384 	return dev_get_drvdata(cdev->dev.parent);
385 }
386 
_mic_reset(struct cosm_device * cdev)387 static void _mic_reset(struct cosm_device *cdev)
388 {
389 	struct mic_device *mdev = cosmdev_to_mdev(cdev);
390 
391 	mdev->ops->reset_fw_ready(mdev);
392 	mdev->ops->reset(mdev);
393 }
394 
_mic_ready(struct cosm_device * cdev)395 static bool _mic_ready(struct cosm_device *cdev)
396 {
397 	struct mic_device *mdev = cosmdev_to_mdev(cdev);
398 
399 	return mdev->ops->is_fw_ready(mdev);
400 }
401 
402 /**
403  * mic_request_dma_chans - Request DMA channels
404  * @mdev: pointer to mic_device instance
405  *
406  * returns number of DMA channels acquired
407  */
mic_request_dma_chans(struct mic_device * mdev)408 static int mic_request_dma_chans(struct mic_device *mdev)
409 {
410 	dma_cap_mask_t mask;
411 	struct dma_chan *chan;
412 
413 	dma_cap_zero(mask);
414 	dma_cap_set(DMA_MEMCPY, mask);
415 
416 	do {
417 		chan = dma_request_channel(mask, mdev->ops->dma_filter,
418 					   &mdev->pdev->dev);
419 		if (chan) {
420 			mdev->dma_ch[mdev->num_dma_ch++] = chan;
421 			if (mdev->num_dma_ch >= MIC_MAX_DMA_CHAN)
422 				break;
423 		}
424 	} while (chan);
425 	dev_info(&mdev->pdev->dev, "DMA channels # %d\n", mdev->num_dma_ch);
426 	return mdev->num_dma_ch;
427 }
428 
429 /**
430  * mic_free_dma_chans - release DMA channels
431  * @mdev: pointer to mic_device instance
432  *
433  * returns none
434  */
mic_free_dma_chans(struct mic_device * mdev)435 static void mic_free_dma_chans(struct mic_device *mdev)
436 {
437 	int i = 0;
438 
439 	for (i = 0; i < mdev->num_dma_ch; i++) {
440 		dma_release_channel(mdev->dma_ch[i]);
441 		mdev->dma_ch[i] = NULL;
442 	}
443 	mdev->num_dma_ch = 0;
444 }
445 
446 /**
447  * _mic_start - Start the MIC.
448  * @cdev: pointer to cosm_device instance
449  * @id: MIC device id/index provided by COSM used in other drivers like SCIF
450  *
451  * This function prepares an MIC for boot and initiates boot.
452  * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
453  *
454  * For all cosm_hw_ops the caller holds a mutex to ensure serialization.
455  */
_mic_start(struct cosm_device * cdev,int id)456 static int _mic_start(struct cosm_device *cdev, int id)
457 {
458 	struct mic_device *mdev = cosmdev_to_mdev(cdev);
459 	int rc;
460 
461 	mic_bootparam_init(mdev);
462 	mdev->dma_mbdev = mbus_register_device(&mdev->pdev->dev,
463 					       MBUS_DEV_DMA_HOST, &mic_dma_ops,
464 					       &mbus_hw_ops, id, mdev->mmio.va);
465 	if (IS_ERR(mdev->dma_mbdev)) {
466 		rc = PTR_ERR(mdev->dma_mbdev);
467 		goto unlock_ret;
468 	}
469 	if (!mic_request_dma_chans(mdev)) {
470 		rc = -ENODEV;
471 		goto dma_remove;
472 	}
473 	mdev->scdev = scif_register_device(&mdev->pdev->dev, MIC_SCIF_DEV,
474 					   &__mic_dma_ops, &scif_hw_ops,
475 					   id + 1, 0, &mdev->mmio,
476 					   &mdev->aper, mdev->dp, NULL,
477 					   mdev->dma_ch, mdev->num_dma_ch,
478 					   true);
479 	if (IS_ERR(mdev->scdev)) {
480 		rc = PTR_ERR(mdev->scdev);
481 		goto dma_free;
482 	}
483 
484 	mdev->vpdev = vop_register_device(&mdev->pdev->dev,
485 					  VOP_DEV_TRNSP, &_mic_dma_ops,
486 					  &vop_hw_ops, id + 1, &mdev->aper,
487 					  mdev->dma_ch[0]);
488 	if (IS_ERR(mdev->vpdev)) {
489 		rc = PTR_ERR(mdev->vpdev);
490 		goto scif_remove;
491 	}
492 
493 	rc = mdev->ops->load_mic_fw(mdev, NULL);
494 	if (rc)
495 		goto vop_remove;
496 	mic_smpt_restore(mdev);
497 	mic_intr_restore(mdev);
498 	mdev->intr_ops->enable_interrupts(mdev);
499 	mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr);
500 	mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32);
501 	mdev->ops->send_firmware_intr(mdev);
502 	goto unlock_ret;
503 vop_remove:
504 	vop_unregister_device(mdev->vpdev);
505 scif_remove:
506 	scif_unregister_device(mdev->scdev);
507 dma_free:
508 	mic_free_dma_chans(mdev);
509 dma_remove:
510 	mbus_unregister_device(mdev->dma_mbdev);
511 unlock_ret:
512 	return rc;
513 }
514 
515 /**
516  * _mic_stop - Prepare the MIC for reset and trigger reset.
517  * @cdev: pointer to cosm_device instance
518  * @force: force a MIC to reset even if it is already offline.
519  *
520  * RETURNS: None.
521  */
_mic_stop(struct cosm_device * cdev,bool force)522 static void _mic_stop(struct cosm_device *cdev, bool force)
523 {
524 	struct mic_device *mdev = cosmdev_to_mdev(cdev);
525 
526 	/*
527 	 * Since SCIF handles card shutdown and reset (using COSM), it will
528 	 * will be the first to be registered and the last to be
529 	 * unregistered.
530 	 */
531 	vop_unregister_device(mdev->vpdev);
532 	scif_unregister_device(mdev->scdev);
533 	mic_free_dma_chans(mdev);
534 	mbus_unregister_device(mdev->dma_mbdev);
535 	mic_bootparam_init(mdev);
536 }
537 
_mic_family(struct cosm_device * cdev,char * buf)538 static ssize_t _mic_family(struct cosm_device *cdev, char *buf)
539 {
540 	struct mic_device *mdev = cosmdev_to_mdev(cdev);
541 	static const char *family[MIC_FAMILY_LAST] = { "x100", "Unknown" };
542 
543 	return scnprintf(buf, PAGE_SIZE, "%s\n", family[mdev->family]);
544 }
545 
_mic_stepping(struct cosm_device * cdev,char * buf)546 static ssize_t _mic_stepping(struct cosm_device *cdev, char *buf)
547 {
548 	struct mic_device *mdev = cosmdev_to_mdev(cdev);
549 	const char *string = "??";
550 
551 	switch (mdev->stepping) {
552 	case MIC_A0_STEP:
553 		string = "A0";
554 		break;
555 	case MIC_B0_STEP:
556 		string = "B0";
557 		break;
558 	case MIC_B1_STEP:
559 		string = "B1";
560 		break;
561 	case MIC_C0_STEP:
562 		string = "C0";
563 		break;
564 	default:
565 		break;
566 	}
567 	return scnprintf(buf, PAGE_SIZE, "%s\n", string);
568 }
569 
_mic_aper(struct cosm_device * cdev)570 static struct mic_mw *_mic_aper(struct cosm_device *cdev)
571 {
572 	struct mic_device *mdev = cosmdev_to_mdev(cdev);
573 
574 	return &mdev->aper;
575 }
576 
577 struct cosm_hw_ops cosm_hw_ops = {
578 	.reset = _mic_reset,
579 	.force_reset = _mic_reset,
580 	.post_reset = NULL,
581 	.ready = _mic_ready,
582 	.start = _mic_start,
583 	.stop = _mic_stop,
584 	.family = _mic_family,
585 	.stepping = _mic_stepping,
586 	.aper = _mic_aper,
587 };
588