aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorJohn Linn <john.linn@xilinx.com>2008-10-27 22:17:22 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2008-10-27 22:23:32 -0400
commitb4a3ac9a3c26e82e31f8a8f55cb014bc580b1216 (patch)
tree88d6b866e40144c2c220b758640674aeffd25406 /drivers/input
parent2d56f3a32c0e62f99c043d2579840f9731fe5855 (diff)
Input: xilinx_ps2 - various cleanups
Review comments were incorporated to improve the driver. 1. Some data was eliminated that was not needed. 2. Renaming of variables for clarity. 3. Removed unneeded type casting. 4. Changed to use dev_err rather than other I/O. 5. Merged together some functions. 6. Added kerneldoc format to functions. Signed-off-by: Sadanand <sadanan@xilinx.com> Signed-off-by: John Linn <john.linn@xilinx.com> Acked-by: Peter Korsgaard <jacmet@sunsite.dk> Acked-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/serio/xilinx_ps2.c220
1 files changed, 113 insertions, 107 deletions
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c
index 765007899d9a..ebb22f88c842 100644
--- a/drivers/input/serio/xilinx_ps2.c
+++ b/drivers/input/serio/xilinx_ps2.c
@@ -58,23 +58,20 @@
58 58
59/* Mask for all the Receive Interrupts */ 59/* Mask for all the Receive Interrupts */
60#define XPS2_IPIXR_RX_ALL (XPS2_IPIXR_RX_OVF | XPS2_IPIXR_RX_ERR | \ 60#define XPS2_IPIXR_RX_ALL (XPS2_IPIXR_RX_OVF | XPS2_IPIXR_RX_ERR | \
61 XPS2_IPIXR_RX_FULL) 61 XPS2_IPIXR_RX_FULL)
62 62
63/* Mask for all the Interrupts */ 63/* Mask for all the Interrupts */
64#define XPS2_IPIXR_ALL (XPS2_IPIXR_TX_ALL | XPS2_IPIXR_RX_ALL | \ 64#define XPS2_IPIXR_ALL (XPS2_IPIXR_TX_ALL | XPS2_IPIXR_RX_ALL | \
65 XPS2_IPIXR_WDT_TOUT) 65 XPS2_IPIXR_WDT_TOUT)
66 66
67/* Global Interrupt Enable mask */ 67/* Global Interrupt Enable mask */
68#define XPS2_GIER_GIE_MASK 0x80000000 68#define XPS2_GIER_GIE_MASK 0x80000000
69 69
70struct xps2data { 70struct xps2data {
71 int irq; 71 int irq;
72 u32 phys_addr;
73 u32 remap_size;
74 spinlock_t lock; 72 spinlock_t lock;
75 u8 rxb; /* Rx buffer */
76 void __iomem *base_address; /* virt. address of control registers */ 73 void __iomem *base_address; /* virt. address of control registers */
77 unsigned int dfl; 74 unsigned int flags;
78 struct serio serio; /* serio */ 75 struct serio serio; /* serio */
79}; 76};
80 77
@@ -82,8 +79,13 @@ struct xps2data {
82/* XPS PS/2 data transmission calls */ 79/* XPS PS/2 data transmission calls */
83/************************************/ 80/************************************/
84 81
85/* 82/**
86 * xps2_recv() will attempt to receive a byte of data from the PS/2 port. 83 * xps2_recv() - attempts to receive a byte from the PS/2 port.
84 * @drvdata: pointer to ps2 device private data structure
85 * @byte: address where the read data will be copied
86 *
87 * If there is any data available in the PS/2 receiver, this functions reads
88 * the data, otherwise it returns error.
87 */ 89 */
88static int xps2_recv(struct xps2data *drvdata, u8 *byte) 90static int xps2_recv(struct xps2data *drvdata, u8 *byte)
89{ 91{
@@ -116,33 +118,27 @@ static irqreturn_t xps2_interrupt(int irq, void *dev_id)
116 118
117 /* Check which interrupt is active */ 119 /* Check which interrupt is active */
118 if (intr_sr & XPS2_IPIXR_RX_OVF) 120 if (intr_sr & XPS2_IPIXR_RX_OVF)
119 printk(KERN_WARNING "%s: receive overrun error\n", 121 dev_warn(drvdata->serio.dev.parent, "receive overrun error\n");
120 drvdata->serio.name);
121 122
122 if (intr_sr & XPS2_IPIXR_RX_ERR) 123 if (intr_sr & XPS2_IPIXR_RX_ERR)
123 drvdata->dfl |= SERIO_PARITY; 124 drvdata->flags |= SERIO_PARITY;
124 125
125 if (intr_sr & (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT)) 126 if (intr_sr & (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT))
126 drvdata->dfl |= SERIO_TIMEOUT; 127 drvdata->flags |= SERIO_TIMEOUT;
127 128
128 if (intr_sr & XPS2_IPIXR_RX_FULL) { 129 if (intr_sr & XPS2_IPIXR_RX_FULL) {
129 status = xps2_recv(drvdata, &drvdata->rxb); 130 status = xps2_recv(drvdata, &c);
130 131
131 /* Error, if a byte is not received */ 132 /* Error, if a byte is not received */
132 if (status) { 133 if (status) {
133 printk(KERN_ERR 134 dev_err(drvdata->serio.dev.parent,
134 "%s: wrong rcvd byte count (%d)\n", 135 "wrong rcvd byte count (%d)\n", status);
135 drvdata->serio.name, status);
136 } else { 136 } else {
137 c = drvdata->rxb; 137 serio_interrupt(&drvdata->serio, c, drvdata->flags);
138 serio_interrupt(&drvdata->serio, c, drvdata->dfl); 138 drvdata->flags = 0;
139 drvdata->dfl = 0;
140 } 139 }
141 } 140 }
142 141
143 if (intr_sr & XPS2_IPIXR_TX_ACK)
144 drvdata->dfl = 0;
145
146 return IRQ_HANDLED; 142 return IRQ_HANDLED;
147} 143}
148 144
@@ -150,8 +146,15 @@ static irqreturn_t xps2_interrupt(int irq, void *dev_id)
150/* serio callbacks */ 146/* serio callbacks */
151/*******************/ 147/*******************/
152 148
153/* 149/**
154 * sxps2_write() sends a byte out through the PS/2 interface. 150 * sxps2_write() - sends a byte out through the PS/2 port.
151 * @pserio: pointer to the serio structure of the PS/2 port
152 * @c: data that needs to be written to the PS/2 port
153 *
154 * This function checks if the PS/2 transmitter is empty and sends a byte.
155 * Otherwise it returns error. Transmission fails only when nothing is connected
156 * to the PS/2 port. Thats why, we do not try to resend the data in case of a
157 * failure.
155 */ 158 */
156static int sxps2_write(struct serio *pserio, unsigned char c) 159static int sxps2_write(struct serio *pserio, unsigned char c)
157{ 160{
@@ -174,33 +177,39 @@ static int sxps2_write(struct serio *pserio, unsigned char c)
174 return status; 177 return status;
175} 178}
176 179
177/* 180/**
178 * sxps2_open() is called when a port is open by the higher layer. 181 * sxps2_open() - called when a port is opened by the higher layer.
182 * @pserio: pointer to the serio structure of the PS/2 device
183 *
184 * This function requests irq and enables interrupts for the PS/2 device.
179 */ 185 */
180static int sxps2_open(struct serio *pserio) 186static int sxps2_open(struct serio *pserio)
181{ 187{
182 struct xps2data *drvdata = pserio->port_data; 188 struct xps2data *drvdata = pserio->port_data;
183 int retval; 189 int error;
190 u8 c;
184 191
185 retval = request_irq(drvdata->irq, &xps2_interrupt, 0, 192 error = request_irq(drvdata->irq, &xps2_interrupt, 0,
186 DRIVER_NAME, drvdata); 193 DRIVER_NAME, drvdata);
187 if (retval) { 194 if (error) {
188 printk(KERN_ERR 195 dev_err(drvdata->serio.dev.parent,
189 "%s: Couldn't allocate interrupt %d\n", 196 "Couldn't allocate interrupt %d\n", drvdata->irq);
190 drvdata->serio.name, drvdata->irq); 197 return error;
191 return retval;
192 } 198 }
193 199
194 /* start reception by enabling the interrupts */ 200 /* start reception by enabling the interrupts */
195 out_be32(drvdata->base_address + XPS2_GIER_OFFSET, XPS2_GIER_GIE_MASK); 201 out_be32(drvdata->base_address + XPS2_GIER_OFFSET, XPS2_GIER_GIE_MASK);
196 out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, XPS2_IPIXR_RX_ALL); 202 out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, XPS2_IPIXR_RX_ALL);
197 (void)xps2_recv(drvdata, &drvdata->rxb); 203 (void)xps2_recv(drvdata, &c);
198 204
199 return 0; /* success */ 205 return 0; /* success */
200} 206}
201 207
202/* 208/**
203 * sxps2_close() frees the interrupt. 209 * sxps2_close() - frees the interrupt.
210 * @pserio: pointer to the serio structure of the PS/2 device
211 *
212 * This function frees the irq and disables interrupts for the PS/2 device.
204 */ 213 */
205static void sxps2_close(struct serio *pserio) 214static void sxps2_close(struct serio *pserio)
206{ 215{
@@ -212,24 +221,41 @@ static void sxps2_close(struct serio *pserio)
212 free_irq(drvdata->irq, drvdata); 221 free_irq(drvdata->irq, drvdata);
213} 222}
214 223
215/*********************/ 224/**
216/* Device setup code */ 225 * xps2_of_probe - probe method for the PS/2 device.
217/*********************/ 226 * @of_dev: pointer to OF device structure
218 227 * @match: pointer to the stucture used for matching a device
219static int xps2_setup(struct device *dev, struct resource *regs_res, 228 *
220 struct resource *irq_res) 229 * This function probes the PS/2 device in the device tree.
230 * It initializes the driver data structure and the hardware.
231 * It returns 0, if the driver is bound to the PS/2 device, or a negative
232 * value if there is an error.
233 */
234static int __devinit xps2_of_probe(struct of_device *ofdev,
235 const struct of_device_id *match)
221{ 236{
237 struct resource r_irq; /* Interrupt resources */
238 struct resource r_mem; /* IO mem resources */
222 struct xps2data *drvdata; 239 struct xps2data *drvdata;
223 struct serio *serio; 240 struct serio *serio;
224 unsigned long remap_size; 241 struct device *dev = &ofdev->dev;
225 int retval; 242 resource_size_t remap_size, phys_addr;
243 int error;
244
245 dev_info(dev, "Device Tree Probing \'%s\'\n",
246 ofdev->node->name);
226 247
227 if (!dev) 248 /* Get iospace for the device */
228 return -EINVAL; 249 error = of_address_to_resource(ofdev->node, 0, &r_mem);
250 if (error) {
251 dev_err(dev, "invalid address\n");
252 return error;
253 }
229 254
230 if (!regs_res || !irq_res) { 255 /* Get IRQ for the device */
231 dev_err(dev, "IO resource(s) not found\n"); 256 if (of_irq_to_resource(ofdev->node, 0, &r_irq) == NO_IRQ) {
232 return -EINVAL; 257 dev_err(dev, "no IRQ found\n");
258 return -ENODEV;
233 } 259 }
234 260
235 drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL); 261 drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
@@ -241,24 +267,23 @@ static int xps2_setup(struct device *dev, struct resource *regs_res,
241 dev_set_drvdata(dev, drvdata); 267 dev_set_drvdata(dev, drvdata);
242 268
243 spin_lock_init(&drvdata->lock); 269 spin_lock_init(&drvdata->lock);
244 drvdata->irq = irq_res->start; 270 drvdata->irq = r_irq.start;
245 271
246 remap_size = regs_res->end - regs_res->start + 1; 272 phys_addr = r_mem.start;
247 if (!request_mem_region(regs_res->start, remap_size, DRIVER_NAME)) { 273 remap_size = r_mem.end - r_mem.start + 1;
248 dev_err(dev, "Couldn't lock memory region at 0x%08X\n", 274 if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
249 (unsigned int)regs_res->start); 275 dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
250 retval = -EBUSY; 276 (unsigned long long)phys_addr);
277 error = -EBUSY;
251 goto failed1; 278 goto failed1;
252 } 279 }
253 280
254 /* Fill in configuration data and add them to the list */ 281 /* Fill in configuration data and add them to the list */
255 drvdata->phys_addr = regs_res->start; 282 drvdata->base_address = ioremap(phys_addr, remap_size);
256 drvdata->remap_size = remap_size;
257 drvdata->base_address = ioremap(regs_res->start, remap_size);
258 if (drvdata->base_address == NULL) { 283 if (drvdata->base_address == NULL) {
259 dev_err(dev, "Couldn't ioremap memory at 0x%08X\n", 284 dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n",
260 (unsigned int)regs_res->start); 285 (unsigned long long)phys_addr);
261 retval = -EFAULT; 286 error = -EFAULT;
262 goto failed2; 287 goto failed2;
263 } 288 }
264 289
@@ -269,8 +294,9 @@ static int xps2_setup(struct device *dev, struct resource *regs_res,
269 * we have the PS2 in a good state */ 294 * we have the PS2 in a good state */
270 out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET); 295 out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);
271 296
272 dev_info(dev, "Xilinx PS2 at 0x%08X mapped to 0x%p, irq=%d\n", 297 dev_info(dev, "Xilinx PS2 at 0x%08llX mapped to 0x%p, irq=%d\n",
273 drvdata->phys_addr, drvdata->base_address, drvdata->irq); 298 (unsigned long long)phys_addr, drvdata->base_address,
299 drvdata->irq);
274 300
275 serio = &drvdata->serio; 301 serio = &drvdata->serio;
276 serio->id.type = SERIO_8042; 302 serio->id.type = SERIO_8042;
@@ -280,71 +306,51 @@ static int xps2_setup(struct device *dev, struct resource *regs_res,
280 serio->port_data = drvdata; 306 serio->port_data = drvdata;
281 serio->dev.parent = dev; 307 serio->dev.parent = dev;
282 snprintf(serio->name, sizeof(serio->name), 308 snprintf(serio->name, sizeof(serio->name),
283 "Xilinx XPS PS/2 at %08X", drvdata->phys_addr); 309 "Xilinx XPS PS/2 at %08llX", (unsigned long long)phys_addr);
284 snprintf(serio->phys, sizeof(serio->phys), 310 snprintf(serio->phys, sizeof(serio->phys),
285 "xilinxps2/serio at %08X", drvdata->phys_addr); 311 "xilinxps2/serio at %08llX", (unsigned long long)phys_addr);
312
286 serio_register_port(serio); 313 serio_register_port(serio);
287 314
288 return 0; /* success */ 315 return 0; /* success */
289 316
290failed2: 317failed2:
291 release_mem_region(regs_res->start, remap_size); 318 release_mem_region(phys_addr, remap_size);
292failed1: 319failed1:
293 kfree(drvdata); 320 kfree(drvdata);
294 dev_set_drvdata(dev, NULL); 321 dev_set_drvdata(dev, NULL);
295 322
296 return retval; 323 return error;
297}
298
299/***************************/
300/* OF Platform Bus Support */
301/***************************/
302
303static int __devinit xps2_of_probe(struct of_device *ofdev, const struct
304 of_device_id * match)
305{
306 struct resource r_irq; /* Interrupt resources */
307 struct resource r_mem; /* IO mem resources */
308 int rc = 0;
309
310 printk(KERN_INFO "Device Tree Probing \'%s\'\n",
311 ofdev->node->name);
312
313 /* Get iospace for the device */
314 rc = of_address_to_resource(ofdev->node, 0, &r_mem);
315 if (rc) {
316 dev_err(&ofdev->dev, "invalid address\n");
317 return rc;
318 }
319
320 /* Get IRQ for the device */
321 rc = of_irq_to_resource(ofdev->node, 0, &r_irq);
322 if (rc == NO_IRQ) {
323 dev_err(&ofdev->dev, "no IRQ found\n");
324 return rc;
325 }
326
327 return xps2_setup(&ofdev->dev, &r_mem, &r_irq);
328} 324}
329 325
326/**
327 * xps2_of_remove - unbinds the driver from the PS/2 device.
328 * @of_dev: pointer to OF device structure
329 *
330 * This function is called if a device is physically removed from the system or
331 * if the driver module is being unloaded. It frees any resources allocated to
332 * the device.
333 */
330static int __devexit xps2_of_remove(struct of_device *of_dev) 334static int __devexit xps2_of_remove(struct of_device *of_dev)
331{ 335{
332 struct device *dev = &of_dev->dev; 336 struct device *dev = &of_dev->dev;
333 struct xps2data *drvdata; 337 struct xps2data *drvdata = dev_get_drvdata(dev);
334 338 struct resource r_mem; /* IO mem resources */
335 if (!dev)
336 return -EINVAL;
337
338 drvdata = dev_get_drvdata(dev);
339 339
340 serio_unregister_port(&drvdata->serio); 340 serio_unregister_port(&drvdata->serio);
341 iounmap(drvdata->base_address); 341 iounmap(drvdata->base_address);
342 release_mem_region(drvdata->phys_addr, drvdata->remap_size); 342
343 /* Get iospace of the device */
344 if (of_address_to_resource(of_dev->node, 0, &r_mem))
345 dev_err(dev, "invalid address\n");
346 else
347 release_mem_region(r_mem.start, r_mem.end - r_mem.start + 1);
348
343 kfree(drvdata); 349 kfree(drvdata);
344 350
345 dev_set_drvdata(dev, NULL); 351 dev_set_drvdata(dev, NULL);
346 352
347 return 0; /* success */ 353 return 0;
348} 354}
349 355
350/* Match table for of_platform binding */ 356/* Match table for of_platform binding */