diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2009-03-18 12:13:09 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:43:30 -0400 |
commit | 21508b902b314e0cd9c081a9141b138e96c9f441 (patch) | |
tree | f6ba4272148c629b3f69ac9a3cb56f4f09a97059 /drivers/media | |
parent | 14386c2b7793652a656021a3345cff3b0f6771f9 (diff) |
V4L/DVB (11114): cafe_ccic: convert to v4l2_device.
Convert this driver to v4l2_device and removed the unnecessary cafe_dev_list.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Acked-by: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/cafe_ccic.c | 158 |
1 files changed, 54 insertions, 104 deletions
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 46fd573a4f15..600dde379efe 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
27 | #include <linux/videodev2.h> | 27 | #include <linux/videodev2.h> |
28 | #include <media/v4l2-common.h> | 28 | #include <media/v4l2-device.h> |
29 | #include <media/v4l2-ioctl.h> | 29 | #include <media/v4l2-ioctl.h> |
30 | #include <media/v4l2-chip-ident.h> | 30 | #include <media/v4l2-chip-ident.h> |
31 | #include <linux/device.h> | 31 | #include <linux/device.h> |
@@ -136,6 +136,7 @@ struct cafe_sio_buffer { | |||
136 | */ | 136 | */ |
137 | struct cafe_camera | 137 | struct cafe_camera |
138 | { | 138 | { |
139 | struct v4l2_device v4l2_dev; | ||
139 | enum cafe_state state; | 140 | enum cafe_state state; |
140 | unsigned long flags; /* Buffer status, mainly (dev_lock) */ | 141 | unsigned long flags; /* Buffer status, mainly (dev_lock) */ |
141 | int users; /* How many open FDs */ | 142 | int users; /* How many open FDs */ |
@@ -145,7 +146,7 @@ struct cafe_camera | |||
145 | * Subsystem structures. | 146 | * Subsystem structures. |
146 | */ | 147 | */ |
147 | struct pci_dev *pdev; | 148 | struct pci_dev *pdev; |
148 | struct video_device v4ldev; | 149 | struct video_device vdev; |
149 | struct i2c_adapter i2c_adapter; | 150 | struct i2c_adapter i2c_adapter; |
150 | struct i2c_client *sensor; | 151 | struct i2c_client *sensor; |
151 | 152 | ||
@@ -196,6 +197,11 @@ struct cafe_camera | |||
196 | #define CF_CONFIG_NEEDED 4 /* Must configure hardware */ | 197 | #define CF_CONFIG_NEEDED 4 /* Must configure hardware */ |
197 | 198 | ||
198 | 199 | ||
200 | static inline struct cafe_camera *to_cam(struct v4l2_device *dev) | ||
201 | { | ||
202 | return container_of(dev, struct cafe_camera, v4l2_dev); | ||
203 | } | ||
204 | |||
199 | 205 | ||
200 | /* | 206 | /* |
201 | * Start over with DMA buffers - dev_lock needed. | 207 | * Start over with DMA buffers - dev_lock needed. |
@@ -238,59 +244,7 @@ static void cafe_set_config_needed(struct cafe_camera *cam, int needed) | |||
238 | 244 | ||
239 | 245 | ||
240 | /* ---------------------------------------------------------------------*/ | 246 | /* ---------------------------------------------------------------------*/ |
241 | /* | ||
242 | * We keep a simple list of known devices to search at open time. | ||
243 | */ | ||
244 | static LIST_HEAD(cafe_dev_list); | ||
245 | static DEFINE_MUTEX(cafe_dev_list_lock); | ||
246 | |||
247 | static void cafe_add_dev(struct cafe_camera *cam) | ||
248 | { | ||
249 | mutex_lock(&cafe_dev_list_lock); | ||
250 | list_add_tail(&cam->dev_list, &cafe_dev_list); | ||
251 | mutex_unlock(&cafe_dev_list_lock); | ||
252 | } | ||
253 | |||
254 | static void cafe_remove_dev(struct cafe_camera *cam) | ||
255 | { | ||
256 | mutex_lock(&cafe_dev_list_lock); | ||
257 | list_del(&cam->dev_list); | ||
258 | mutex_unlock(&cafe_dev_list_lock); | ||
259 | } | ||
260 | |||
261 | static struct cafe_camera *cafe_find_dev(int minor) | ||
262 | { | ||
263 | struct cafe_camera *cam; | ||
264 | 247 | ||
265 | mutex_lock(&cafe_dev_list_lock); | ||
266 | list_for_each_entry(cam, &cafe_dev_list, dev_list) { | ||
267 | if (cam->v4ldev.minor == minor) | ||
268 | goto done; | ||
269 | } | ||
270 | cam = NULL; | ||
271 | done: | ||
272 | mutex_unlock(&cafe_dev_list_lock); | ||
273 | return cam; | ||
274 | } | ||
275 | |||
276 | |||
277 | static struct cafe_camera *cafe_find_by_pdev(struct pci_dev *pdev) | ||
278 | { | ||
279 | struct cafe_camera *cam; | ||
280 | |||
281 | mutex_lock(&cafe_dev_list_lock); | ||
282 | list_for_each_entry(cam, &cafe_dev_list, dev_list) { | ||
283 | if (cam->pdev == pdev) | ||
284 | goto done; | ||
285 | } | ||
286 | cam = NULL; | ||
287 | done: | ||
288 | mutex_unlock(&cafe_dev_list_lock); | ||
289 | return cam; | ||
290 | } | ||
291 | |||
292 | |||
293 | /* ------------------------------------------------------------------------ */ | ||
294 | /* | 248 | /* |
295 | * Device register I/O | 249 | * Device register I/O |
296 | */ | 250 | */ |
@@ -481,7 +435,8 @@ static int cafe_smbus_xfer(struct i2c_adapter *adapter, u16 addr, | |||
481 | unsigned short flags, char rw, u8 command, | 435 | unsigned short flags, char rw, u8 command, |
482 | int size, union i2c_smbus_data *data) | 436 | int size, union i2c_smbus_data *data) |
483 | { | 437 | { |
484 | struct cafe_camera *cam = i2c_get_adapdata(adapter); | 438 | struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter); |
439 | struct cafe_camera *cam = to_cam(v4l2_dev); | ||
485 | int ret = -EINVAL; | 440 | int ret = -EINVAL; |
486 | 441 | ||
487 | /* | 442 | /* |
@@ -536,7 +491,8 @@ static void cafe_ctlr_power_down(struct cafe_camera *cam); | |||
536 | 491 | ||
537 | static int cafe_smbus_attach(struct i2c_client *client) | 492 | static int cafe_smbus_attach(struct i2c_client *client) |
538 | { | 493 | { |
539 | struct cafe_camera *cam = i2c_get_adapdata(client->adapter); | 494 | struct v4l2_device *v4l2_dev = i2c_get_adapdata(client->adapter); |
495 | struct cafe_camera *cam = to_cam(v4l2_dev); | ||
540 | 496 | ||
541 | /* | 497 | /* |
542 | * Don't talk to chips we don't recognize. | 498 | * Don't talk to chips we don't recognize. |
@@ -550,7 +506,8 @@ static int cafe_smbus_attach(struct i2c_client *client) | |||
550 | 506 | ||
551 | static int cafe_smbus_detach(struct i2c_client *client) | 507 | static int cafe_smbus_detach(struct i2c_client *client) |
552 | { | 508 | { |
553 | struct cafe_camera *cam = i2c_get_adapdata(client->adapter); | 509 | struct v4l2_device *v4l2_dev = i2c_get_adapdata(client->adapter); |
510 | struct cafe_camera *cam = to_cam(v4l2_dev); | ||
554 | 511 | ||
555 | if (cam->sensor == client) { | 512 | if (cam->sensor == client) { |
556 | cafe_ctlr_stop_dma(cam); | 513 | cafe_ctlr_stop_dma(cam); |
@@ -575,7 +532,7 @@ static int cafe_smbus_setup(struct cafe_camera *cam) | |||
575 | adap->algo = &cafe_smbus_algo; | 532 | adap->algo = &cafe_smbus_algo; |
576 | strcpy(adap->name, "cafe_ccic"); | 533 | strcpy(adap->name, "cafe_ccic"); |
577 | adap->dev.parent = &cam->pdev->dev; | 534 | adap->dev.parent = &cam->pdev->dev; |
578 | i2c_set_adapdata(adap, cam); | 535 | i2c_set_adapdata(adap, &cam->v4l2_dev); |
579 | ret = i2c_add_adapter(adap); | 536 | ret = i2c_add_adapter(adap); |
580 | if (ret) | 537 | if (ret) |
581 | printk(KERN_ERR "Unable to register cafe i2c adapter\n"); | 538 | printk(KERN_ERR "Unable to register cafe i2c adapter\n"); |
@@ -809,9 +766,9 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam) | |||
809 | * Control 1 is power down, set to 0 to operate. | 766 | * Control 1 is power down, set to 0 to operate. |
810 | */ | 767 | */ |
811 | cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */ | 768 | cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */ |
812 | // mdelay(1); /* Marvell says 1ms will do it */ | 769 | /* mdelay(1); */ /* Marvell says 1ms will do it */ |
813 | cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0); | 770 | cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0); |
814 | // mdelay(1); /* Enough? */ | 771 | /* mdelay(1); */ /* Enough? */ |
815 | spin_unlock_irqrestore(&cam->dev_lock, flags); | 772 | spin_unlock_irqrestore(&cam->dev_lock, flags); |
816 | msleep(5); /* Just to be sure */ | 773 | msleep(5); /* Just to be sure */ |
817 | } | 774 | } |
@@ -874,7 +831,7 @@ static int cafe_cam_init(struct cafe_camera *cam) | |||
874 | if (ret) | 831 | if (ret) |
875 | goto out; | 832 | goto out; |
876 | cam->sensor_type = chip.ident; | 833 | cam->sensor_type = chip.ident; |
877 | // if (cam->sensor->addr != OV7xx0_SID) { | 834 | /* if (cam->sensor->addr != OV7xx0_SID) { */ |
878 | if (cam->sensor_type != V4L2_IDENT_OV7670) { | 835 | if (cam->sensor_type != V4L2_IDENT_OV7670) { |
879 | cam_err(cam, "Unsupported sensor type %d", cam->sensor->addr); | 836 | cam_err(cam, "Unsupported sensor type %d", cam->sensor->addr); |
880 | ret = -EINVAL; | 837 | ret = -EINVAL; |
@@ -1474,11 +1431,8 @@ static int cafe_v4l_mmap(struct file *filp, struct vm_area_struct *vma) | |||
1474 | 1431 | ||
1475 | static int cafe_v4l_open(struct file *filp) | 1432 | static int cafe_v4l_open(struct file *filp) |
1476 | { | 1433 | { |
1477 | struct cafe_camera *cam; | 1434 | struct cafe_camera *cam = video_drvdata(filp); |
1478 | 1435 | ||
1479 | cam = cafe_find_dev(video_devdata(filp)->minor); | ||
1480 | if (cam == NULL) | ||
1481 | return -ENODEV; | ||
1482 | filp->private_data = cam; | 1436 | filp->private_data = cam; |
1483 | 1437 | ||
1484 | mutex_lock(&cam->s_mutex); | 1438 | mutex_lock(&cam->s_mutex); |
@@ -1532,7 +1486,7 @@ static unsigned int cafe_v4l_poll(struct file *filp, | |||
1532 | static int cafe_vidioc_queryctrl(struct file *filp, void *priv, | 1486 | static int cafe_vidioc_queryctrl(struct file *filp, void *priv, |
1533 | struct v4l2_queryctrl *qc) | 1487 | struct v4l2_queryctrl *qc) |
1534 | { | 1488 | { |
1535 | struct cafe_camera *cam = filp->private_data; | 1489 | struct cafe_camera *cam = priv; |
1536 | int ret; | 1490 | int ret; |
1537 | 1491 | ||
1538 | mutex_lock(&cam->s_mutex); | 1492 | mutex_lock(&cam->s_mutex); |
@@ -1545,7 +1499,7 @@ static int cafe_vidioc_queryctrl(struct file *filp, void *priv, | |||
1545 | static int cafe_vidioc_g_ctrl(struct file *filp, void *priv, | 1499 | static int cafe_vidioc_g_ctrl(struct file *filp, void *priv, |
1546 | struct v4l2_control *ctrl) | 1500 | struct v4l2_control *ctrl) |
1547 | { | 1501 | { |
1548 | struct cafe_camera *cam = filp->private_data; | 1502 | struct cafe_camera *cam = priv; |
1549 | int ret; | 1503 | int ret; |
1550 | 1504 | ||
1551 | mutex_lock(&cam->s_mutex); | 1505 | mutex_lock(&cam->s_mutex); |
@@ -1558,7 +1512,7 @@ static int cafe_vidioc_g_ctrl(struct file *filp, void *priv, | |||
1558 | static int cafe_vidioc_s_ctrl(struct file *filp, void *priv, | 1512 | static int cafe_vidioc_s_ctrl(struct file *filp, void *priv, |
1559 | struct v4l2_control *ctrl) | 1513 | struct v4l2_control *ctrl) |
1560 | { | 1514 | { |
1561 | struct cafe_camera *cam = filp->private_data; | 1515 | struct cafe_camera *cam = priv; |
1562 | int ret; | 1516 | int ret; |
1563 | 1517 | ||
1564 | mutex_lock(&cam->s_mutex); | 1518 | mutex_lock(&cam->s_mutex); |
@@ -1745,15 +1699,6 @@ static int cafe_vidioc_s_parm(struct file *filp, void *priv, | |||
1745 | return ret; | 1699 | return ret; |
1746 | } | 1700 | } |
1747 | 1701 | ||
1748 | |||
1749 | static void cafe_v4l_dev_release(struct video_device *vd) | ||
1750 | { | ||
1751 | struct cafe_camera *cam = container_of(vd, struct cafe_camera, v4ldev); | ||
1752 | |||
1753 | kfree(cam); | ||
1754 | } | ||
1755 | |||
1756 | |||
1757 | /* | 1702 | /* |
1758 | * This template device holds all of those v4l2 methods; we | 1703 | * This template device holds all of those v4l2 methods; we |
1759 | * clone it for specific real devices. | 1704 | * clone it for specific real devices. |
@@ -1800,15 +1745,10 @@ static struct video_device cafe_v4l_template = { | |||
1800 | 1745 | ||
1801 | .fops = &cafe_v4l_fops, | 1746 | .fops = &cafe_v4l_fops, |
1802 | .ioctl_ops = &cafe_v4l_ioctl_ops, | 1747 | .ioctl_ops = &cafe_v4l_ioctl_ops, |
1803 | .release = cafe_v4l_dev_release, | 1748 | .release = video_device_release_empty, |
1804 | }; | 1749 | }; |
1805 | 1750 | ||
1806 | 1751 | ||
1807 | |||
1808 | |||
1809 | |||
1810 | |||
1811 | |||
1812 | /* ---------------------------------------------------------------------- */ | 1752 | /* ---------------------------------------------------------------------- */ |
1813 | /* | 1753 | /* |
1814 | * Interrupt handler stuff | 1754 | * Interrupt handler stuff |
@@ -2054,10 +1994,10 @@ static void cafe_dfs_cam_setup(struct cafe_camera *cam) | |||
2054 | 1994 | ||
2055 | if (!cafe_dfs_root) | 1995 | if (!cafe_dfs_root) |
2056 | return; | 1996 | return; |
2057 | sprintf(fname, "regs-%d", cam->v4ldev.num); | 1997 | sprintf(fname, "regs-%d", cam->vdev.num); |
2058 | cam->dfs_regs = debugfs_create_file(fname, 0444, cafe_dfs_root, | 1998 | cam->dfs_regs = debugfs_create_file(fname, 0444, cafe_dfs_root, |
2059 | cam, &cafe_dfs_reg_ops); | 1999 | cam, &cafe_dfs_reg_ops); |
2060 | sprintf(fname, "cam-%d", cam->v4ldev.num); | 2000 | sprintf(fname, "cam-%d", cam->vdev.num); |
2061 | cam->dfs_cam_regs = debugfs_create_file(fname, 0444, cafe_dfs_root, | 2001 | cam->dfs_cam_regs = debugfs_create_file(fname, 0444, cafe_dfs_root, |
2062 | cam, &cafe_dfs_cam_ops); | 2002 | cam, &cafe_dfs_cam_ops); |
2063 | } | 2003 | } |
@@ -2100,6 +2040,10 @@ static int cafe_pci_probe(struct pci_dev *pdev, | |||
2100 | cam = kzalloc(sizeof(struct cafe_camera), GFP_KERNEL); | 2040 | cam = kzalloc(sizeof(struct cafe_camera), GFP_KERNEL); |
2101 | if (cam == NULL) | 2041 | if (cam == NULL) |
2102 | goto out; | 2042 | goto out; |
2043 | ret = v4l2_device_register(&pdev->dev, &cam->v4l2_dev); | ||
2044 | if (ret) | ||
2045 | goto out_free; | ||
2046 | |||
2103 | mutex_init(&cam->s_mutex); | 2047 | mutex_init(&cam->s_mutex); |
2104 | mutex_lock(&cam->s_mutex); | 2048 | mutex_lock(&cam->s_mutex); |
2105 | spin_lock_init(&cam->dev_lock); | 2049 | spin_lock_init(&cam->dev_lock); |
@@ -2118,14 +2062,14 @@ static int cafe_pci_probe(struct pci_dev *pdev, | |||
2118 | */ | 2062 | */ |
2119 | ret = pci_enable_device(pdev); | 2063 | ret = pci_enable_device(pdev); |
2120 | if (ret) | 2064 | if (ret) |
2121 | goto out_free; | 2065 | goto out_unreg; |
2122 | pci_set_master(pdev); | 2066 | pci_set_master(pdev); |
2123 | 2067 | ||
2124 | ret = -EIO; | 2068 | ret = -EIO; |
2125 | cam->regs = pci_iomap(pdev, 0, 0); | 2069 | cam->regs = pci_iomap(pdev, 0, 0); |
2126 | if (! cam->regs) { | 2070 | if (! cam->regs) { |
2127 | printk(KERN_ERR "Unable to ioremap cafe-ccic regs\n"); | 2071 | printk(KERN_ERR "Unable to ioremap cafe-ccic regs\n"); |
2128 | goto out_free; | 2072 | goto out_unreg; |
2129 | } | 2073 | } |
2130 | ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam); | 2074 | ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam); |
2131 | if (ret) | 2075 | if (ret) |
@@ -2149,13 +2093,15 @@ static int cafe_pci_probe(struct pci_dev *pdev, | |||
2149 | * Get the v4l2 setup done. | 2093 | * Get the v4l2 setup done. |
2150 | */ | 2094 | */ |
2151 | mutex_lock(&cam->s_mutex); | 2095 | mutex_lock(&cam->s_mutex); |
2152 | cam->v4ldev = cafe_v4l_template; | 2096 | cam->vdev = cafe_v4l_template; |
2153 | cam->v4ldev.debug = 0; | 2097 | cam->vdev.debug = 0; |
2154 | // cam->v4ldev.debug = V4L2_DEBUG_IOCTL_ARG; | 2098 | /* cam->vdev.debug = V4L2_DEBUG_IOCTL_ARG;*/ |
2155 | cam->v4ldev.parent = &pdev->dev; | 2099 | cam->vdev.v4l2_dev = &cam->v4l2_dev; |
2156 | ret = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, -1); | 2100 | ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); |
2157 | if (ret) | 2101 | if (ret) |
2158 | goto out_smbus; | 2102 | goto out_smbus; |
2103 | video_set_drvdata(&cam->vdev, cam); | ||
2104 | |||
2159 | /* | 2105 | /* |
2160 | * If so requested, try to get our DMA buffers now. | 2106 | * If so requested, try to get our DMA buffers now. |
2161 | */ | 2107 | */ |
@@ -2167,19 +2113,20 @@ static int cafe_pci_probe(struct pci_dev *pdev, | |||
2167 | 2113 | ||
2168 | cafe_dfs_cam_setup(cam); | 2114 | cafe_dfs_cam_setup(cam); |
2169 | mutex_unlock(&cam->s_mutex); | 2115 | mutex_unlock(&cam->s_mutex); |
2170 | cafe_add_dev(cam); | ||
2171 | return 0; | 2116 | return 0; |
2172 | 2117 | ||
2173 | out_smbus: | 2118 | out_smbus: |
2174 | cafe_smbus_shutdown(cam); | 2119 | cafe_smbus_shutdown(cam); |
2175 | out_freeirq: | 2120 | out_freeirq: |
2176 | cafe_ctlr_power_down(cam); | 2121 | cafe_ctlr_power_down(cam); |
2177 | free_irq(pdev->irq, cam); | 2122 | free_irq(pdev->irq, cam); |
2178 | out_iounmap: | 2123 | out_iounmap: |
2179 | pci_iounmap(pdev, cam->regs); | 2124 | pci_iounmap(pdev, cam->regs); |
2180 | out_free: | 2125 | out_free: |
2126 | v4l2_device_unregister(&cam->v4l2_dev); | ||
2127 | out_unreg: | ||
2181 | kfree(cam); | 2128 | kfree(cam); |
2182 | out: | 2129 | out: |
2183 | return ret; | 2130 | return ret; |
2184 | } | 2131 | } |
2185 | 2132 | ||
@@ -2194,21 +2141,20 @@ static void cafe_shutdown(struct cafe_camera *cam) | |||
2194 | if (cam->n_sbufs > 0) | 2141 | if (cam->n_sbufs > 0) |
2195 | /* What if they are still mapped? Shouldn't be, but... */ | 2142 | /* What if they are still mapped? Shouldn't be, but... */ |
2196 | cafe_free_sio_buffers(cam); | 2143 | cafe_free_sio_buffers(cam); |
2197 | cafe_remove_dev(cam); | ||
2198 | cafe_ctlr_stop_dma(cam); | 2144 | cafe_ctlr_stop_dma(cam); |
2199 | cafe_ctlr_power_down(cam); | 2145 | cafe_ctlr_power_down(cam); |
2200 | cafe_smbus_shutdown(cam); | 2146 | cafe_smbus_shutdown(cam); |
2201 | cafe_free_dma_bufs(cam); | 2147 | cafe_free_dma_bufs(cam); |
2202 | free_irq(cam->pdev->irq, cam); | 2148 | free_irq(cam->pdev->irq, cam); |
2203 | pci_iounmap(cam->pdev, cam->regs); | 2149 | pci_iounmap(cam->pdev, cam->regs); |
2204 | video_unregister_device(&cam->v4ldev); | 2150 | video_unregister_device(&cam->vdev); |
2205 | /* kfree(cam); done in v4l_release () */ | ||
2206 | } | 2151 | } |
2207 | 2152 | ||
2208 | 2153 | ||
2209 | static void cafe_pci_remove(struct pci_dev *pdev) | 2154 | static void cafe_pci_remove(struct pci_dev *pdev) |
2210 | { | 2155 | { |
2211 | struct cafe_camera *cam = cafe_find_by_pdev(pdev); | 2156 | struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); |
2157 | struct cafe_camera *cam = to_cam(v4l2_dev); | ||
2212 | 2158 | ||
2213 | if (cam == NULL) { | 2159 | if (cam == NULL) { |
2214 | printk(KERN_WARNING "pci_remove on unknown pdev %p\n", pdev); | 2160 | printk(KERN_WARNING "pci_remove on unknown pdev %p\n", pdev); |
@@ -2218,6 +2164,8 @@ static void cafe_pci_remove(struct pci_dev *pdev) | |||
2218 | if (cam->users > 0) | 2164 | if (cam->users > 0) |
2219 | cam_warn(cam, "Removing a device with users!\n"); | 2165 | cam_warn(cam, "Removing a device with users!\n"); |
2220 | cafe_shutdown(cam); | 2166 | cafe_shutdown(cam); |
2167 | v4l2_device_unregister(&cam->v4l2_dev); | ||
2168 | kfree(cam); | ||
2221 | /* No unlock - it no longer exists */ | 2169 | /* No unlock - it no longer exists */ |
2222 | } | 2170 | } |
2223 | 2171 | ||
@@ -2228,7 +2176,8 @@ static void cafe_pci_remove(struct pci_dev *pdev) | |||
2228 | */ | 2176 | */ |
2229 | static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state) | 2177 | static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
2230 | { | 2178 | { |
2231 | struct cafe_camera *cam = cafe_find_by_pdev(pdev); | 2179 | struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); |
2180 | struct cafe_camera *cam = to_cam(v4l2_dev); | ||
2232 | int ret; | 2181 | int ret; |
2233 | enum cafe_state cstate; | 2182 | enum cafe_state cstate; |
2234 | 2183 | ||
@@ -2246,7 +2195,8 @@ static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2246 | 2195 | ||
2247 | static int cafe_pci_resume(struct pci_dev *pdev) | 2196 | static int cafe_pci_resume(struct pci_dev *pdev) |
2248 | { | 2197 | { |
2249 | struct cafe_camera *cam = cafe_find_by_pdev(pdev); | 2198 | struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); |
2199 | struct cafe_camera *cam = to_cam(v4l2_dev); | ||
2250 | int ret = 0; | 2200 | int ret = 0; |
2251 | 2201 | ||
2252 | ret = pci_restore_state(pdev); | 2202 | ret = pci_restore_state(pdev); |