Lines Matching +full:irq +full:- +full:device
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Xilinx XPS PS/2 device driver
24 /* Register offsets for the xps2 device */
66 int irq; member
71 struct device *dev;
79 * xps2_recv() - attempts to receive a byte from the PS/2 port.
80 * @drvdata: pointer to ps2 device private data structure
89 int status = -1; in xps2_recv()
92 sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET); in xps2_recv()
94 *byte = in_be32(drvdata->base_address + XPS2_RX_DATA_OFFSET); in xps2_recv()
104 static irqreturn_t xps2_interrupt(int irq, void *dev_id) in xps2_interrupt() argument
112 intr_sr = in_be32(drvdata->base_address + XPS2_IPISR_OFFSET); in xps2_interrupt()
113 out_be32(drvdata->base_address + XPS2_IPISR_OFFSET, intr_sr); in xps2_interrupt()
117 dev_warn(drvdata->dev, "receive overrun error\n"); in xps2_interrupt()
120 drvdata->flags |= SERIO_PARITY; in xps2_interrupt()
123 drvdata->flags |= SERIO_TIMEOUT; in xps2_interrupt()
130 dev_err(drvdata->dev, in xps2_interrupt()
133 serio_interrupt(drvdata->serio, c, drvdata->flags); in xps2_interrupt()
134 drvdata->flags = 0; in xps2_interrupt()
146 * sxps2_write() - sends a byte out through the PS/2 port.
157 struct xps2data *drvdata = pserio->port_data; in sxps2_write()
160 guard(spinlock_irqsave)(&drvdata->lock); in sxps2_write()
163 sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET); in sxps2_write()
165 return -EAGAIN; in sxps2_write()
167 out_be32(drvdata->base_address + XPS2_TX_DATA_OFFSET, c); in sxps2_write()
172 * sxps2_open() - called when a port is opened by the higher layer.
173 * @pserio: pointer to the serio structure of the PS/2 device
175 * This function requests irq and enables interrupts for the PS/2 device.
179 struct xps2data *drvdata = pserio->port_data; in sxps2_open()
183 error = request_irq(drvdata->irq, &xps2_interrupt, 0, in sxps2_open()
186 dev_err(drvdata->dev, in sxps2_open()
187 "Couldn't allocate interrupt %d\n", drvdata->irq); in sxps2_open()
192 out_be32(drvdata->base_address + XPS2_GIER_OFFSET, XPS2_GIER_GIE_MASK); in sxps2_open()
193 out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, XPS2_IPIXR_RX_ALL); in sxps2_open()
200 * sxps2_close() - frees the interrupt.
201 * @pserio: pointer to the serio structure of the PS/2 device
203 * This function frees the irq and disables interrupts for the PS/2 device.
207 struct xps2data *drvdata = pserio->port_data; in sxps2_close()
210 out_be32(drvdata->base_address + XPS2_GIER_OFFSET, 0x00); in sxps2_close()
211 out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0x00); in sxps2_close()
212 free_irq(drvdata->irq, drvdata); in sxps2_close()
216 * xps2_of_probe - probe method for the PS/2 device.
217 * @ofdev: pointer to OF device structure
219 * This function probes the PS/2 device in the device tree.
221 * It returns 0, if the driver is bound to the PS/2 device, or a negative
229 struct device *dev = &ofdev->dev; in xps2_of_probe()
231 unsigned int irq; in xps2_of_probe() local
234 dev_info(dev, "Device Tree Probing \'%pOFn\'\n", dev->of_node); in xps2_of_probe()
236 /* Get iospace for the device */ in xps2_of_probe()
237 error = of_address_to_resource(dev->of_node, 0, &r_mem); in xps2_of_probe()
243 /* Get IRQ for the device */ in xps2_of_probe()
244 irq = irq_of_parse_and_map(dev->of_node, 0); in xps2_of_probe()
245 if (!irq) { in xps2_of_probe()
246 dev_err(dev, "no IRQ found\n"); in xps2_of_probe()
247 return -ENODEV; in xps2_of_probe()
253 error = -ENOMEM; in xps2_of_probe()
257 spin_lock_init(&drvdata->lock); in xps2_of_probe()
258 drvdata->irq = irq; in xps2_of_probe()
259 drvdata->serio = serio; in xps2_of_probe()
260 drvdata->dev = dev; in xps2_of_probe()
267 error = -EBUSY; in xps2_of_probe()
272 drvdata->base_address = ioremap(phys_addr, remap_size); in xps2_of_probe()
273 if (drvdata->base_address == NULL) { in xps2_of_probe()
276 error = -EFAULT; in xps2_of_probe()
281 out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0); in xps2_of_probe()
284 * Reset the PS2 device and abort any current transaction, in xps2_of_probe()
287 out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET); in xps2_of_probe()
289 dev_info(dev, "Xilinx PS2 at 0x%08llX mapped to 0x%p, irq=%d\n", in xps2_of_probe()
290 (unsigned long long)phys_addr, drvdata->base_address, in xps2_of_probe()
291 drvdata->irq); in xps2_of_probe()
293 serio->id.type = SERIO_8042; in xps2_of_probe()
294 serio->write = sxps2_write; in xps2_of_probe()
295 serio->open = sxps2_open; in xps2_of_probe()
296 serio->close = sxps2_close; in xps2_of_probe()
297 serio->port_data = drvdata; in xps2_of_probe()
298 serio->dev.parent = dev; in xps2_of_probe()
299 snprintf(serio->name, sizeof(serio->name), in xps2_of_probe()
301 snprintf(serio->phys, sizeof(serio->phys), in xps2_of_probe()
319 * xps2_of_remove - unbinds the driver from the PS/2 device.
320 * @of_dev: pointer to OF device structure
322 * This function is called if a device is physically removed from the system or
324 * the device.
331 serio_unregister_port(drvdata->serio); in xps2_of_remove()
332 iounmap(drvdata->base_address); in xps2_of_remove()
334 /* Get iospace of the device */ in xps2_of_remove()
335 if (of_address_to_resource(of_dev->dev.of_node, 0, &r_mem)) in xps2_of_remove()
336 dev_err(drvdata->dev, "invalid address\n"); in xps2_of_remove()
345 { .compatible = "xlnx,xps-ps2-1.00.a", },