aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/tifm_core.c102
1 files changed, 47 insertions, 55 deletions
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
index 6799b9cca055..dcff45a19bcb 100644
--- a/drivers/misc/tifm_core.c
+++ b/drivers/misc/tifm_core.c
@@ -60,14 +60,54 @@ static int tifm_uevent(struct device *dev, char **envp, int num_envp,
60 return 0; 60 return 0;
61} 61}
62 62
63static int tifm_device_probe(struct device *dev)
64{
65 struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
66 struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver,
67 driver);
68 int rc = -ENODEV;
69
70 get_device(dev);
71 if (dev->driver && drv->probe) {
72 rc = drv->probe(sock);
73 if (!rc)
74 return 0;
75 }
76 put_device(dev);
77 return rc;
78}
79
80static void tifm_dummy_event(struct tifm_dev *sock)
81{
82 return;
83}
84
85static int tifm_device_remove(struct device *dev)
86{
87 struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
88 struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver,
89 driver);
90
91 if (dev->driver && drv->remove) {
92 sock->card_event = tifm_dummy_event;
93 sock->data_event = tifm_dummy_event;
94 drv->remove(sock);
95 sock->dev.driver = NULL;
96 }
97
98 put_device(dev);
99 return 0;
100}
101
63#ifdef CONFIG_PM 102#ifdef CONFIG_PM
64 103
65static int tifm_device_suspend(struct device *dev, pm_message_t state) 104static int tifm_device_suspend(struct device *dev, pm_message_t state)
66{ 105{
67 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); 106 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
68 struct tifm_driver *drv = fm_dev->drv; 107 struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver,
108 driver);
69 109
70 if (drv && drv->suspend) 110 if (dev->driver && drv->suspend)
71 return drv->suspend(fm_dev, state); 111 return drv->suspend(fm_dev, state);
72 return 0; 112 return 0;
73} 113}
@@ -75,9 +115,10 @@ static int tifm_device_suspend(struct device *dev, pm_message_t state)
75static int tifm_device_resume(struct device *dev) 115static int tifm_device_resume(struct device *dev)
76{ 116{
77 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); 117 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
78 struct tifm_driver *drv = fm_dev->drv; 118 struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver,
119 driver);
79 120
80 if (drv && drv->resume) 121 if (dev->driver && drv->resume)
81 return drv->resume(fm_dev); 122 return drv->resume(fm_dev);
82 return 0; 123 return 0;
83} 124}
@@ -93,6 +134,8 @@ static struct bus_type tifm_bus_type = {
93 .name = "tifm", 134 .name = "tifm",
94 .match = tifm_match, 135 .match = tifm_match,
95 .uevent = tifm_uevent, 136 .uevent = tifm_uevent,
137 .probe = tifm_device_probe,
138 .remove = tifm_device_remove,
96 .suspend = tifm_device_suspend, 139 .suspend = tifm_device_suspend,
97 .resume = tifm_device_resume 140 .resume = tifm_device_resume
98}; 141};
@@ -175,11 +218,6 @@ void tifm_free_device(struct device *dev)
175} 218}
176EXPORT_SYMBOL(tifm_free_device); 219EXPORT_SYMBOL(tifm_free_device);
177 220
178static void tifm_dummy_event(struct tifm_dev *sock)
179{
180 return;
181}
182
183struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm) 221struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm)
184{ 222{
185 struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL); 223 struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL);
@@ -218,55 +256,9 @@ void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents,
218} 256}
219EXPORT_SYMBOL(tifm_unmap_sg); 257EXPORT_SYMBOL(tifm_unmap_sg);
220 258
221static int tifm_device_probe(struct device *dev)
222{
223 struct tifm_driver *drv;
224 struct tifm_dev *fm_dev;
225 int rc = 0;
226 const tifm_media_id *id;
227
228 drv = container_of(dev->driver, struct tifm_driver, driver);
229 fm_dev = container_of(dev, struct tifm_dev, dev);
230 get_device(dev);
231 if (!fm_dev->drv && drv->probe && drv->id_table) {
232 rc = -ENODEV;
233 id = tifm_device_match(drv->id_table, fm_dev);
234 if (id)
235 rc = drv->probe(fm_dev);
236 if (rc >= 0) {
237 rc = 0;
238 fm_dev->drv = drv;
239 }
240 }
241 if (rc)
242 put_device(dev);
243 return rc;
244}
245
246static int tifm_device_remove(struct device *dev)
247{
248 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
249 struct tifm_driver *drv = fm_dev->drv;
250
251 if (drv) {
252 fm_dev->card_event = tifm_dummy_event;
253 fm_dev->data_event = tifm_dummy_event;
254 if (drv->remove)
255 drv->remove(fm_dev);
256 fm_dev->drv = NULL;
257 }
258
259 put_device(dev);
260 return 0;
261}
262
263int tifm_register_driver(struct tifm_driver *drv) 259int tifm_register_driver(struct tifm_driver *drv)
264{ 260{
265 drv->driver.bus = &tifm_bus_type; 261 drv->driver.bus = &tifm_bus_type;
266 drv->driver.probe = tifm_device_probe;
267 drv->driver.remove = tifm_device_remove;
268 drv->driver.suspend = tifm_device_suspend;
269 drv->driver.resume = tifm_device_resume;
270 262
271 return driver_register(&drv->driver); 263 return driver_register(&drv->driver);
272} 264}