Lines Matching +full:irq +full:- +full:device
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * dell-smo8800.c - Dell Latitude ACPI SMO88XX freefall sensor driver
22 u32 irq; /* acpi device irq */ member
25 unsigned long misc_opened; /* whether the device is open */
27 struct device *dev; /* acpi device */
30 static irqreturn_t smo8800_interrupt_quick(int irq, void *data) in smo8800_interrupt_quick() argument
34 atomic_inc(&smo8800->counter); in smo8800_interrupt_quick()
35 wake_up_interruptible(&smo8800->misc_wait); in smo8800_interrupt_quick()
39 static irqreturn_t smo8800_interrupt_thread(int irq, void *data) in smo8800_interrupt_thread() argument
43 dev_info(smo8800->dev, "detected free fall\n"); in smo8800_interrupt_thread()
50 struct acpi_resource_extended_irq *irq; in smo8800_get_resource() local
52 if (resource->type != ACPI_RESOURCE_TYPE_EXTENDED_IRQ) in smo8800_get_resource()
55 irq = &resource->data.extended_irq; in smo8800_get_resource()
56 if (!irq || !irq->interrupt_count) in smo8800_get_resource()
59 *((u32 *)context) = irq->interrupts[0]; in smo8800_get_resource()
63 static u32 smo8800_get_irq(struct acpi_device *device) in smo8800_get_irq() argument
65 u32 irq = 0; in smo8800_get_irq() local
68 status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, in smo8800_get_irq()
69 smo8800_get_resource, &irq); in smo8800_get_irq()
71 dev_err(&device->dev, "acpi_walk_resources failed\n"); in smo8800_get_irq()
75 return irq; in smo8800_get_irq()
81 struct smo8800_device *smo8800 = container_of(file->private_data, in smo8800_misc_read()
89 return -EINVAL; in smo8800_misc_read()
91 atomic_set(&smo8800->counter, 0); in smo8800_misc_read()
92 retval = wait_event_interruptible(smo8800->misc_wait, in smo8800_misc_read()
93 (data = atomic_xchg(&smo8800->counter, 0))); in smo8800_misc_read()
106 retval = -EFAULT; in smo8800_misc_read()
113 struct smo8800_device *smo8800 = container_of(file->private_data, in smo8800_misc_open()
116 if (test_and_set_bit(0, &smo8800->misc_opened)) in smo8800_misc_open()
117 return -EBUSY; /* already open */ in smo8800_misc_open()
119 atomic_set(&smo8800->counter, 0); in smo8800_misc_open()
125 struct smo8800_device *smo8800 = container_of(file->private_data, in smo8800_misc_release()
128 clear_bit(0, &smo8800->misc_opened); /* release the device */ in smo8800_misc_release()
139 static int smo8800_add(struct acpi_device *device) in smo8800_add() argument
144 smo8800 = devm_kzalloc(&device->dev, sizeof(*smo8800), GFP_KERNEL); in smo8800_add()
146 dev_err(&device->dev, "failed to allocate device data\n"); in smo8800_add()
147 return -ENOMEM; in smo8800_add()
150 smo8800->dev = &device->dev; in smo8800_add()
151 smo8800->miscdev.minor = MISC_DYNAMIC_MINOR; in smo8800_add()
152 smo8800->miscdev.name = "freefall"; in smo8800_add()
153 smo8800->miscdev.fops = &smo8800_misc_fops; in smo8800_add()
155 init_waitqueue_head(&smo8800->misc_wait); in smo8800_add()
157 err = misc_register(&smo8800->miscdev); in smo8800_add()
159 dev_err(&device->dev, "failed to register misc dev: %d\n", err); in smo8800_add()
163 device->driver_data = smo8800; in smo8800_add()
165 smo8800->irq = smo8800_get_irq(device); in smo8800_add()
166 if (!smo8800->irq) { in smo8800_add()
167 dev_err(&device->dev, "failed to obtain IRQ\n"); in smo8800_add()
168 err = -EINVAL; in smo8800_add()
172 err = request_threaded_irq(smo8800->irq, smo8800_interrupt_quick, in smo8800_add()
177 dev_err(&device->dev, in smo8800_add()
178 "failed to request thread for IRQ %d: %d\n", in smo8800_add()
179 smo8800->irq, err); in smo8800_add()
183 dev_dbg(&device->dev, "device /dev/freefall registered with IRQ %d\n", in smo8800_add()
184 smo8800->irq); in smo8800_add()
188 misc_deregister(&smo8800->miscdev); in smo8800_add()
192 static int smo8800_remove(struct acpi_device *device) in smo8800_remove() argument
194 struct smo8800_device *smo8800 = device->driver_data; in smo8800_remove()
196 free_irq(smo8800->irq, smo8800); in smo8800_remove()
197 misc_deregister(&smo8800->miscdev); in smo8800_remove()
198 dev_dbg(&device->dev, "device /dev/freefall unregistered\n"); in smo8800_remove()
202 /* NOTE: Keep this list in sync with drivers/i2c/busses/i2c-i801.c */