blob: fdfe720301f212ebf1326770cce5ed2d05f782f2 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001#include <linux/module.h>
2#include <linux/kernel.h>
3#include <linux/slab.h>
4#include <linux/notifier.h>
5#include <linux/platform_data/mv_usb.h>
6
7struct pxa_usb_extern_dev {
8 unsigned int id;
9 struct pxa_usb_extern_ops ops;
10 struct atomic_notifier_head *head;
11};
12
13static struct pxa_usb_extern_dev pxa_usb[PXA_USB_DEV_MAX];
14
15struct pxa_usb_extern_ops *pxa_usb_get_extern_ops(unsigned int id)
16{
17 if (id >= PXA_USB_DEV_MAX)
18 return NULL;
19
20 return &pxa_usb[id].ops;
21}
22
23int pxa_usb_register_notifier(unsigned int id, struct notifier_block *nb)
24{
25 struct pxa_usb_extern_dev *dev;
26 int ret;
27
28 if (id >= PXA_USB_DEV_MAX)
29 return -ENODEV;
30
31 dev = &pxa_usb[id];
32 if (dev->head == NULL) {
33 dev->head = kzalloc(sizeof(*dev->head), GFP_KERNEL);
34 if (dev->head == NULL)
35 return -ENOMEM;
36 ATOMIC_INIT_NOTIFIER_HEAD(dev->head);
37 }
38
39 ret = atomic_notifier_chain_register(dev->head, nb);
40 if (ret)
41 return ret;
42
43 return 0;
44}
45
46int pxa_usb_unregister_notifier(unsigned int id, struct notifier_block *nb)
47{
48 struct pxa_usb_extern_dev *dev;
49 int ret;
50
51 if (id >= PXA_USB_DEV_MAX)
52 return -ENODEV;
53
54 dev = &pxa_usb[id];
55 if (dev->head == NULL)
56 return -EINVAL;
57
58 ret = atomic_notifier_chain_unregister(dev->head, nb);
59 if (ret)
60 return ret;
61
62 return 0;
63}
64
65int pxa_usb_notify(unsigned int id, unsigned long val, void *v)
66{
67 struct pxa_usb_extern_dev *dev;
68 int ret;
69
70 if (id >= PXA_USB_DEV_MAX)
71 return -ENODEV;
72
73 dev = &pxa_usb[id];
74 if (dev->head == NULL)
75 return -EINVAL;
76
77 ret = atomic_notifier_call_chain(dev->head, val, v);
78 if (ret)
79 return ret;
80
81 return 0;
82}