ASoC: hdac_hdmi: Add vendor id for Cannonlake HDMI codec
[linux-2.6-microblaze.git] / drivers / s390 / cio / eadm_sch.c
1 /*
2  * Driver for s390 eadm subchannels
3  *
4  * Copyright IBM Corp. 2012
5  * Author(s): Sebastian Ott <sebott@linux.vnet.ibm.com>
6  */
7
8 #include <linux/kernel_stat.h>
9 #include <linux/completion.h>
10 #include <linux/workqueue.h>
11 #include <linux/spinlock.h>
12 #include <linux/device.h>
13 #include <linux/module.h>
14 #include <linux/timer.h>
15 #include <linux/slab.h>
16 #include <linux/list.h>
17
18 #include <asm/css_chars.h>
19 #include <asm/debug.h>
20 #include <asm/isc.h>
21 #include <asm/cio.h>
22 #include <asm/scsw.h>
23 #include <asm/eadm.h>
24
25 #include "eadm_sch.h"
26 #include "ioasm.h"
27 #include "cio.h"
28 #include "css.h"
29 #include "orb.h"
30
31 MODULE_DESCRIPTION("driver for s390 eadm subchannels");
32 MODULE_LICENSE("GPL");
33
34 #define EADM_TIMEOUT (7 * HZ)
35 static DEFINE_SPINLOCK(list_lock);
36 static LIST_HEAD(eadm_list);
37
38 static debug_info_t *eadm_debug;
39
40 #define EADM_LOG(imp, txt) do {                                 \
41                 debug_text_event(eadm_debug, imp, txt);         \
42         } while (0)
43
44 static void EADM_LOG_HEX(int level, void *data, int length)
45 {
46         debug_event(eadm_debug, level, data, length);
47 }
48
49 static void orb_init(union orb *orb)
50 {
51         memset(orb, 0, sizeof(union orb));
52         orb->eadm.compat1 = 1;
53         orb->eadm.compat2 = 1;
54         orb->eadm.fmt = 1;
55         orb->eadm.x = 1;
56 }
57
58 static int eadm_subchannel_start(struct subchannel *sch, struct aob *aob)
59 {
60         union orb *orb = &get_eadm_private(sch)->orb;
61         int cc;
62
63         orb_init(orb);
64         orb->eadm.aob = (u32)__pa(aob);
65         orb->eadm.intparm = (u32)(addr_t)sch;
66         orb->eadm.key = PAGE_DEFAULT_KEY >> 4;
67
68         EADM_LOG(6, "start");
69         EADM_LOG_HEX(6, &sch->schid, sizeof(sch->schid));
70
71         cc = ssch(sch->schid, orb);
72         switch (cc) {
73         case 0:
74                 sch->schib.scsw.eadm.actl |= SCSW_ACTL_START_PEND;
75                 break;
76         case 1:         /* status pending */
77         case 2:         /* busy */
78                 return -EBUSY;
79         case 3:         /* not operational */
80                 return -ENODEV;
81         }
82         return 0;
83 }
84
85 static int eadm_subchannel_clear(struct subchannel *sch)
86 {
87         int cc;
88
89         cc = csch(sch->schid);
90         if (cc)
91                 return -ENODEV;
92
93         sch->schib.scsw.eadm.actl |= SCSW_ACTL_CLEAR_PEND;
94         return 0;
95 }
96
97 static void eadm_subchannel_timeout(struct timer_list *t)
98 {
99         struct eadm_private *private = from_timer(private, t, timer);
100         struct subchannel *sch = private->sch;
101
102         spin_lock_irq(sch->lock);
103         EADM_LOG(1, "timeout");
104         EADM_LOG_HEX(1, &sch->schid, sizeof(sch->schid));
105         if (eadm_subchannel_clear(sch))
106                 EADM_LOG(0, "clear failed");
107         spin_unlock_irq(sch->lock);
108 }
109
110 static void eadm_subchannel_set_timeout(struct subchannel *sch, int expires)
111 {
112         struct eadm_private *private = get_eadm_private(sch);
113
114         if (expires == 0) {
115                 del_timer(&private->timer);
116                 return;
117         }
118         if (timer_pending(&private->timer)) {
119                 if (mod_timer(&private->timer, jiffies + expires))
120                         return;
121         }
122         private->timer.expires = jiffies + expires;
123         add_timer(&private->timer);
124 }
125
126 static void eadm_subchannel_irq(struct subchannel *sch)
127 {
128         struct eadm_private *private = get_eadm_private(sch);
129         struct eadm_scsw *scsw = &sch->schib.scsw.eadm;
130         struct irb *irb = this_cpu_ptr(&cio_irb);
131         blk_status_t error = BLK_STS_OK;
132
133         EADM_LOG(6, "irq");
134         EADM_LOG_HEX(6, irb, sizeof(*irb));
135
136         inc_irq_stat(IRQIO_ADM);
137
138         if ((scsw->stctl & (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND))
139             && scsw->eswf == 1 && irb->esw.eadm.erw.r)
140                 error = BLK_STS_IOERR;
141
142         if (scsw->fctl & SCSW_FCTL_CLEAR_FUNC)
143                 error = BLK_STS_TIMEOUT;
144
145         eadm_subchannel_set_timeout(sch, 0);
146
147         if (private->state != EADM_BUSY) {
148                 EADM_LOG(1, "irq unsol");
149                 EADM_LOG_HEX(1, irb, sizeof(*irb));
150                 private->state = EADM_NOT_OPER;
151                 css_sched_sch_todo(sch, SCH_TODO_EVAL);
152                 return;
153         }
154         scm_irq_handler((struct aob *)(unsigned long)scsw->aob, error);
155         private->state = EADM_IDLE;
156
157         if (private->completion)
158                 complete(private->completion);
159 }
160
161 static struct subchannel *eadm_get_idle_sch(void)
162 {
163         struct eadm_private *private;
164         struct subchannel *sch;
165         unsigned long flags;
166
167         spin_lock_irqsave(&list_lock, flags);
168         list_for_each_entry(private, &eadm_list, head) {
169                 sch = private->sch;
170                 spin_lock(sch->lock);
171                 if (private->state == EADM_IDLE) {
172                         private->state = EADM_BUSY;
173                         list_move_tail(&private->head, &eadm_list);
174                         spin_unlock(sch->lock);
175                         spin_unlock_irqrestore(&list_lock, flags);
176
177                         return sch;
178                 }
179                 spin_unlock(sch->lock);
180         }
181         spin_unlock_irqrestore(&list_lock, flags);
182
183         return NULL;
184 }
185
186 int eadm_start_aob(struct aob *aob)
187 {
188         struct eadm_private *private;
189         struct subchannel *sch;
190         unsigned long flags;
191         int ret;
192
193         sch = eadm_get_idle_sch();
194         if (!sch)
195                 return -EBUSY;
196
197         spin_lock_irqsave(sch->lock, flags);
198         eadm_subchannel_set_timeout(sch, EADM_TIMEOUT);
199         ret = eadm_subchannel_start(sch, aob);
200         if (!ret)
201                 goto out_unlock;
202
203         /* Handle start subchannel failure. */
204         eadm_subchannel_set_timeout(sch, 0);
205         private = get_eadm_private(sch);
206         private->state = EADM_NOT_OPER;
207         css_sched_sch_todo(sch, SCH_TODO_EVAL);
208
209 out_unlock:
210         spin_unlock_irqrestore(sch->lock, flags);
211
212         return ret;
213 }
214 EXPORT_SYMBOL_GPL(eadm_start_aob);
215
216 static int eadm_subchannel_probe(struct subchannel *sch)
217 {
218         struct eadm_private *private;
219         int ret;
220
221         private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
222         if (!private)
223                 return -ENOMEM;
224
225         INIT_LIST_HEAD(&private->head);
226         timer_setup(&private->timer, eadm_subchannel_timeout, 0);
227
228         spin_lock_irq(sch->lock);
229         set_eadm_private(sch, private);
230         private->state = EADM_IDLE;
231         private->sch = sch;
232         sch->isc = EADM_SCH_ISC;
233         ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
234         if (ret) {
235                 set_eadm_private(sch, NULL);
236                 spin_unlock_irq(sch->lock);
237                 kfree(private);
238                 goto out;
239         }
240         spin_unlock_irq(sch->lock);
241
242         spin_lock_irq(&list_lock);
243         list_add(&private->head, &eadm_list);
244         spin_unlock_irq(&list_lock);
245
246         if (dev_get_uevent_suppress(&sch->dev)) {
247                 dev_set_uevent_suppress(&sch->dev, 0);
248                 kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
249         }
250 out:
251         return ret;
252 }
253
254 static void eadm_quiesce(struct subchannel *sch)
255 {
256         struct eadm_private *private = get_eadm_private(sch);
257         DECLARE_COMPLETION_ONSTACK(completion);
258         int ret;
259
260         spin_lock_irq(sch->lock);
261         if (private->state != EADM_BUSY)
262                 goto disable;
263
264         if (eadm_subchannel_clear(sch))
265                 goto disable;
266
267         private->completion = &completion;
268         spin_unlock_irq(sch->lock);
269
270         wait_for_completion_io(&completion);
271
272         spin_lock_irq(sch->lock);
273         private->completion = NULL;
274
275 disable:
276         eadm_subchannel_set_timeout(sch, 0);
277         do {
278                 ret = cio_disable_subchannel(sch);
279         } while (ret == -EBUSY);
280
281         spin_unlock_irq(sch->lock);
282 }
283
284 static int eadm_subchannel_remove(struct subchannel *sch)
285 {
286         struct eadm_private *private = get_eadm_private(sch);
287
288         spin_lock_irq(&list_lock);
289         list_del(&private->head);
290         spin_unlock_irq(&list_lock);
291
292         eadm_quiesce(sch);
293
294         spin_lock_irq(sch->lock);
295         set_eadm_private(sch, NULL);
296         spin_unlock_irq(sch->lock);
297
298         kfree(private);
299
300         return 0;
301 }
302
303 static void eadm_subchannel_shutdown(struct subchannel *sch)
304 {
305         eadm_quiesce(sch);
306 }
307
308 static int eadm_subchannel_freeze(struct subchannel *sch)
309 {
310         return cio_disable_subchannel(sch);
311 }
312
313 static int eadm_subchannel_restore(struct subchannel *sch)
314 {
315         return cio_enable_subchannel(sch, (u32)(unsigned long)sch);
316 }
317
318 /**
319  * eadm_subchannel_sch_event - process subchannel event
320  * @sch: subchannel
321  * @process: non-zero if function is called in process context
322  *
323  * An unspecified event occurred for this subchannel. Adjust data according
324  * to the current operational state of the subchannel. Return zero when the
325  * event has been handled sufficiently or -EAGAIN when this function should
326  * be called again in process context.
327  */
328 static int eadm_subchannel_sch_event(struct subchannel *sch, int process)
329 {
330         struct eadm_private *private;
331         unsigned long flags;
332
333         spin_lock_irqsave(sch->lock, flags);
334         if (!device_is_registered(&sch->dev))
335                 goto out_unlock;
336
337         if (work_pending(&sch->todo_work))
338                 goto out_unlock;
339
340         if (cio_update_schib(sch)) {
341                 css_sched_sch_todo(sch, SCH_TODO_UNREG);
342                 goto out_unlock;
343         }
344         private = get_eadm_private(sch);
345         if (private->state == EADM_NOT_OPER)
346                 private->state = EADM_IDLE;
347
348 out_unlock:
349         spin_unlock_irqrestore(sch->lock, flags);
350
351         return 0;
352 }
353
354 static struct css_device_id eadm_subchannel_ids[] = {
355         { .match_flags = 0x1, .type = SUBCHANNEL_TYPE_ADM, },
356         { /* end of list */ },
357 };
358 MODULE_DEVICE_TABLE(css, eadm_subchannel_ids);
359
360 static struct css_driver eadm_subchannel_driver = {
361         .drv = {
362                 .name = "eadm_subchannel",
363                 .owner = THIS_MODULE,
364         },
365         .subchannel_type = eadm_subchannel_ids,
366         .irq = eadm_subchannel_irq,
367         .probe = eadm_subchannel_probe,
368         .remove = eadm_subchannel_remove,
369         .shutdown = eadm_subchannel_shutdown,
370         .sch_event = eadm_subchannel_sch_event,
371         .freeze = eadm_subchannel_freeze,
372         .thaw = eadm_subchannel_restore,
373         .restore = eadm_subchannel_restore,
374 };
375
376 static int __init eadm_sch_init(void)
377 {
378         int ret;
379
380         if (!css_general_characteristics.eadm)
381                 return -ENXIO;
382
383         eadm_debug = debug_register("eadm_log", 16, 1, 16);
384         if (!eadm_debug)
385                 return -ENOMEM;
386
387         debug_register_view(eadm_debug, &debug_hex_ascii_view);
388         debug_set_level(eadm_debug, 2);
389
390         isc_register(EADM_SCH_ISC);
391         ret = css_driver_register(&eadm_subchannel_driver);
392         if (ret)
393                 goto cleanup;
394
395         return ret;
396
397 cleanup:
398         isc_unregister(EADM_SCH_ISC);
399         debug_unregister(eadm_debug);
400         return ret;
401 }
402
403 static void __exit eadm_sch_exit(void)
404 {
405         css_driver_unregister(&eadm_subchannel_driver);
406         isc_unregister(EADM_SCH_ISC);
407         debug_unregister(eadm_debug);
408 }
409 module_init(eadm_sch_init);
410 module_exit(eadm_sch_exit);