0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/serio.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/errno.h>
0014 #include <linux/slab.h>
0015 #include <linux/list.h>
0016 #include <linux/io.h>
0017 #include <linux/of_address.h>
0018 #include <linux/of_device.h>
0019 #include <linux/of_irq.h>
0020 #include <linux/of_platform.h>
0021
0022 #define DRIVER_NAME "xilinx_ps2"
0023
0024
0025 #define XPS2_SRST_OFFSET 0x00000000
0026 #define XPS2_STATUS_OFFSET 0x00000004
0027 #define XPS2_RX_DATA_OFFSET 0x00000008
0028 #define XPS2_TX_DATA_OFFSET 0x0000000C
0029 #define XPS2_GIER_OFFSET 0x0000002C
0030 #define XPS2_IPISR_OFFSET 0x00000030
0031 #define XPS2_IPIER_OFFSET 0x00000038
0032
0033
0034 #define XPS2_SRST_RESET 0x0000000A
0035
0036
0037 #define XPS2_STATUS_RX_FULL 0x00000001
0038 #define XPS2_STATUS_TX_FULL 0x00000002
0039
0040
0041
0042
0043
0044 #define XPS2_IPIXR_WDT_TOUT 0x00000001
0045 #define XPS2_IPIXR_TX_NOACK 0x00000002
0046 #define XPS2_IPIXR_TX_ACK 0x00000004
0047 #define XPS2_IPIXR_RX_OVF 0x00000008
0048 #define XPS2_IPIXR_RX_ERR 0x00000010
0049 #define XPS2_IPIXR_RX_FULL 0x00000020
0050
0051
0052 #define XPS2_IPIXR_TX_ALL (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_TX_ACK)
0053
0054
0055 #define XPS2_IPIXR_RX_ALL (XPS2_IPIXR_RX_OVF | XPS2_IPIXR_RX_ERR | \
0056 XPS2_IPIXR_RX_FULL)
0057
0058
0059 #define XPS2_IPIXR_ALL (XPS2_IPIXR_TX_ALL | XPS2_IPIXR_RX_ALL | \
0060 XPS2_IPIXR_WDT_TOUT)
0061
0062
0063 #define XPS2_GIER_GIE_MASK 0x80000000
0064
0065 struct xps2data {
0066 int irq;
0067 spinlock_t lock;
0068 void __iomem *base_address;
0069 unsigned int flags;
0070 struct serio *serio;
0071 struct device *dev;
0072 };
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 static int xps2_recv(struct xps2data *drvdata, u8 *byte)
0087 {
0088 u32 sr;
0089 int status = -1;
0090
0091
0092 sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET);
0093 if (sr & XPS2_STATUS_RX_FULL) {
0094 *byte = in_be32(drvdata->base_address + XPS2_RX_DATA_OFFSET);
0095 status = 0;
0096 }
0097
0098 return status;
0099 }
0100
0101
0102
0103
0104 static irqreturn_t xps2_interrupt(int irq, void *dev_id)
0105 {
0106 struct xps2data *drvdata = dev_id;
0107 u32 intr_sr;
0108 u8 c;
0109 int status;
0110
0111
0112 intr_sr = in_be32(drvdata->base_address + XPS2_IPISR_OFFSET);
0113 out_be32(drvdata->base_address + XPS2_IPISR_OFFSET, intr_sr);
0114
0115
0116 if (intr_sr & XPS2_IPIXR_RX_OVF)
0117 dev_warn(drvdata->dev, "receive overrun error\n");
0118
0119 if (intr_sr & XPS2_IPIXR_RX_ERR)
0120 drvdata->flags |= SERIO_PARITY;
0121
0122 if (intr_sr & (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT))
0123 drvdata->flags |= SERIO_TIMEOUT;
0124
0125 if (intr_sr & XPS2_IPIXR_RX_FULL) {
0126 status = xps2_recv(drvdata, &c);
0127
0128
0129 if (status) {
0130 dev_err(drvdata->dev,
0131 "wrong rcvd byte count (%d)\n", status);
0132 } else {
0133 serio_interrupt(drvdata->serio, c, drvdata->flags);
0134 drvdata->flags = 0;
0135 }
0136 }
0137
0138 return IRQ_HANDLED;
0139 }
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155 static int sxps2_write(struct serio *pserio, unsigned char c)
0156 {
0157 struct xps2data *drvdata = pserio->port_data;
0158 unsigned long flags;
0159 u32 sr;
0160 int status = -1;
0161
0162 spin_lock_irqsave(&drvdata->lock, flags);
0163
0164
0165 sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET);
0166 if (!(sr & XPS2_STATUS_TX_FULL)) {
0167 out_be32(drvdata->base_address + XPS2_TX_DATA_OFFSET, c);
0168 status = 0;
0169 }
0170
0171 spin_unlock_irqrestore(&drvdata->lock, flags);
0172
0173 return status;
0174 }
0175
0176
0177
0178
0179
0180
0181
0182 static int sxps2_open(struct serio *pserio)
0183 {
0184 struct xps2data *drvdata = pserio->port_data;
0185 int error;
0186 u8 c;
0187
0188 error = request_irq(drvdata->irq, &xps2_interrupt, 0,
0189 DRIVER_NAME, drvdata);
0190 if (error) {
0191 dev_err(drvdata->dev,
0192 "Couldn't allocate interrupt %d\n", drvdata->irq);
0193 return error;
0194 }
0195
0196
0197 out_be32(drvdata->base_address + XPS2_GIER_OFFSET, XPS2_GIER_GIE_MASK);
0198 out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, XPS2_IPIXR_RX_ALL);
0199 (void)xps2_recv(drvdata, &c);
0200
0201 return 0;
0202 }
0203
0204
0205
0206
0207
0208
0209
0210 static void sxps2_close(struct serio *pserio)
0211 {
0212 struct xps2data *drvdata = pserio->port_data;
0213
0214
0215 out_be32(drvdata->base_address + XPS2_GIER_OFFSET, 0x00);
0216 out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0x00);
0217 free_irq(drvdata->irq, drvdata);
0218 }
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230 static int xps2_of_probe(struct platform_device *ofdev)
0231 {
0232 struct resource r_mem;
0233 struct xps2data *drvdata;
0234 struct serio *serio;
0235 struct device *dev = &ofdev->dev;
0236 resource_size_t remap_size, phys_addr;
0237 unsigned int irq;
0238 int error;
0239
0240 dev_info(dev, "Device Tree Probing \'%pOFn\'\n", dev->of_node);
0241
0242
0243 error = of_address_to_resource(dev->of_node, 0, &r_mem);
0244 if (error) {
0245 dev_err(dev, "invalid address\n");
0246 return error;
0247 }
0248
0249
0250 irq = irq_of_parse_and_map(dev->of_node, 0);
0251 if (!irq) {
0252 dev_err(dev, "no IRQ found\n");
0253 return -ENODEV;
0254 }
0255
0256 drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
0257 serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
0258 if (!drvdata || !serio) {
0259 error = -ENOMEM;
0260 goto failed1;
0261 }
0262
0263 spin_lock_init(&drvdata->lock);
0264 drvdata->irq = irq;
0265 drvdata->serio = serio;
0266 drvdata->dev = dev;
0267
0268 phys_addr = r_mem.start;
0269 remap_size = resource_size(&r_mem);
0270 if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
0271 dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
0272 (unsigned long long)phys_addr);
0273 error = -EBUSY;
0274 goto failed1;
0275 }
0276
0277
0278 drvdata->base_address = ioremap(phys_addr, remap_size);
0279 if (drvdata->base_address == NULL) {
0280 dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n",
0281 (unsigned long long)phys_addr);
0282 error = -EFAULT;
0283 goto failed2;
0284 }
0285
0286
0287 out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0);
0288
0289
0290
0291
0292
0293 out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);
0294
0295 dev_info(dev, "Xilinx PS2 at 0x%08llX mapped to 0x%p, irq=%d\n",
0296 (unsigned long long)phys_addr, drvdata->base_address,
0297 drvdata->irq);
0298
0299 serio->id.type = SERIO_8042;
0300 serio->write = sxps2_write;
0301 serio->open = sxps2_open;
0302 serio->close = sxps2_close;
0303 serio->port_data = drvdata;
0304 serio->dev.parent = dev;
0305 snprintf(serio->name, sizeof(serio->name),
0306 "Xilinx XPS PS/2 at %08llX", (unsigned long long)phys_addr);
0307 snprintf(serio->phys, sizeof(serio->phys),
0308 "xilinxps2/serio at %08llX", (unsigned long long)phys_addr);
0309
0310 serio_register_port(serio);
0311
0312 platform_set_drvdata(ofdev, drvdata);
0313 return 0;
0314
0315 failed2:
0316 release_mem_region(phys_addr, remap_size);
0317 failed1:
0318 kfree(serio);
0319 kfree(drvdata);
0320
0321 return error;
0322 }
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332 static int xps2_of_remove(struct platform_device *of_dev)
0333 {
0334 struct xps2data *drvdata = platform_get_drvdata(of_dev);
0335 struct resource r_mem;
0336
0337 serio_unregister_port(drvdata->serio);
0338 iounmap(drvdata->base_address);
0339
0340
0341 if (of_address_to_resource(of_dev->dev.of_node, 0, &r_mem))
0342 dev_err(drvdata->dev, "invalid address\n");
0343 else
0344 release_mem_region(r_mem.start, resource_size(&r_mem));
0345
0346 kfree(drvdata);
0347
0348 return 0;
0349 }
0350
0351
0352 static const struct of_device_id xps2_of_match[] = {
0353 { .compatible = "xlnx,xps-ps2-1.00.a", },
0354 { },
0355 };
0356 MODULE_DEVICE_TABLE(of, xps2_of_match);
0357
0358 static struct platform_driver xps2_of_driver = {
0359 .driver = {
0360 .name = DRIVER_NAME,
0361 .of_match_table = xps2_of_match,
0362 },
0363 .probe = xps2_of_probe,
0364 .remove = xps2_of_remove,
0365 };
0366 module_platform_driver(xps2_of_driver);
0367
0368 MODULE_AUTHOR("Xilinx, Inc.");
0369 MODULE_DESCRIPTION("Xilinx XPS PS/2 driver");
0370 MODULE_LICENSE("GPL");
0371