aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/serio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-01-06 20:14:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-06 20:14:01 -0500
commitdb30c70575822cc84d87b5613c19cac24734b99f (patch)
tree82945ad5813bfe6633698233981d270b5f0a310b /drivers/input/serio
parentc861ea2cb2c25c1698734d9b0540a09e253690a1 (diff)
parent9334e90d5ac5ee1fa6d8b75acb7c64a8907787d1 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (29 commits) Input: i8042 - add Dell Vostro 1510 to nomux list Input: gtco - use USB endpoint API Input: add support for Maple controller as a joystick Input: atkbd - broaden the Dell DMI signatures Input: HIL drivers - add MODULE_ALIAS() Input: map_to_7segment.h - convert to __inline__ for userspace Input: add support for enhanced rotary controller on pxa930 and pxa935 Input: add support for trackball on pxa930 and pxa935 Input: add da9034 touchscreen support Input: ads7846 - strict_strtoul takes unsigned long Input: make some variables and functions static Input: add tsc2007 based touchscreen driver Input: psmouse - add module parameters to control OLPC touchpad delays Input: i8042 - add Gigabyte M912 netbook to noloop exception table Input: atkbd - Samsung NC10 key repeat fix Input: atkbd - add keyboard quirk for HP Pavilion ZV6100 laptop Input: libps2 - handle 0xfc responses from devices Input: add support for Wacom W8001 penabled serial touchscreen Input: synaptics - report multi-taps only if supported by the device Input: add joystick driver for Walkera WK-0701 RC transmitter ...
Diffstat (limited to 'drivers/input/serio')
-rw-r--r--drivers/input/serio/hil_mlc.c1
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h15
-rw-r--r--drivers/input/serio/libps2.c20
-rw-r--r--drivers/input/serio/pcips2.c2
-rw-r--r--drivers/input/serio/serio.c4
-rw-r--r--drivers/input/serio/xilinx_ps2.c220
6 files changed, 148 insertions, 114 deletions
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c
index 37586a68d34..7ba9f2b2c04 100644
--- a/drivers/input/serio/hil_mlc.c
+++ b/drivers/input/serio/hil_mlc.c
@@ -934,6 +934,7 @@ int hil_mlc_register(hil_mlc *mlc)
934 snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i); 934 snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i);
935 snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i); 935 snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i);
936 mlc_serio->id = hil_mlc_serio_id; 936 mlc_serio->id = hil_mlc_serio_id;
937 mlc_serio->id.id = i; /* HIL port no. */
937 mlc_serio->write = hil_mlc_serio_write; 938 mlc_serio->write = hil_mlc_serio_write;
938 mlc_serio->open = hil_mlc_serio_open; 939 mlc_serio->open = hil_mlc_serio_open;
939 mlc_serio->close = hil_mlc_serio_close; 940 mlc_serio->close = hil_mlc_serio_close;
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 29e686388a2..6fa2deff744 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -143,6 +143,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
143 DMI_MATCH(DMI_PRODUCT_VERSION, "M606"), 143 DMI_MATCH(DMI_PRODUCT_VERSION, "M606"),
144 }, 144 },
145 }, 145 },
146 {
147 .ident = "Gigabyte M912",
148 .matches = {
149 DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
150 DMI_MATCH(DMI_PRODUCT_NAME, "M912"),
151 DMI_MATCH(DMI_PRODUCT_VERSION, "01"),
152 },
153 },
146 { } 154 { }
147}; 155};
148 156
@@ -351,6 +359,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
351 DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), 359 DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
352 }, 360 },
353 }, 361 },
362 {
363 .ident = "Dell Vostro 1510",
364 .matches = {
365 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
366 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
367 },
368 },
354 { } 369 { }
355}; 370};
356 371
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index 2b304c22c20..67248c31e19 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -262,9 +262,17 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
262 break; 262 break;
263 263
264 case PS2_RET_NAK: 264 case PS2_RET_NAK:
265 ps2dev->nak = 1; 265 ps2dev->flags |= PS2_FLAG_NAK;
266 ps2dev->nak = PS2_RET_NAK;
266 break; 267 break;
267 268
269 case PS2_RET_ERR:
270 if (ps2dev->flags & PS2_FLAG_NAK) {
271 ps2dev->flags &= ~PS2_FLAG_NAK;
272 ps2dev->nak = PS2_RET_ERR;
273 break;
274 }
275
268 /* 276 /*
269 * Workaround for mice which don't ACK the Get ID command. 277 * Workaround for mice which don't ACK the Get ID command.
270 * These are valid mouse IDs that we recognize. 278 * These are valid mouse IDs that we recognize.
@@ -282,8 +290,11 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
282 } 290 }
283 291
284 292
285 if (!ps2dev->nak && ps2dev->cmdcnt) 293 if (!ps2dev->nak) {
286 ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1; 294 ps2dev->flags &= ~PS2_FLAG_NAK;
295 if (ps2dev->cmdcnt)
296 ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
297 }
287 298
288 ps2dev->flags &= ~PS2_FLAG_ACK; 299 ps2dev->flags &= ~PS2_FLAG_ACK;
289 wake_up(&ps2dev->wait); 300 wake_up(&ps2dev->wait);
@@ -329,6 +340,7 @@ void ps2_cmd_aborted(struct ps2dev *ps2dev)
329 if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD)) 340 if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD))
330 wake_up(&ps2dev->wait); 341 wake_up(&ps2dev->wait);
331 342
332 ps2dev->flags = 0; 343 /* reset all flags except last nack */
344 ps2dev->flags &= PS2_FLAG_NAK;
333} 345}
334EXPORT_SYMBOL(ps2_cmd_aborted); 346EXPORT_SYMBOL(ps2_cmd_aborted);
diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
index 1b404f9e3bf..1dacbe0d934 100644
--- a/drivers/input/serio/pcips2.c
+++ b/drivers/input/serio/pcips2.c
@@ -153,7 +153,7 @@ static int __devinit pcips2_probe(struct pci_dev *dev, const struct pci_device_i
153 serio->open = pcips2_open; 153 serio->open = pcips2_open;
154 serio->close = pcips2_close; 154 serio->close = pcips2_close;
155 strlcpy(serio->name, pci_name(dev), sizeof(serio->name)); 155 strlcpy(serio->name, pci_name(dev), sizeof(serio->name));
156 strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys)); 156 strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
157 serio->port_data = ps2if; 157 serio->port_data = ps2if;
158 serio->dev.parent = &dev->dev; 158 serio->dev.parent = &dev->dev;
159 ps2if->io = serio; 159 ps2if->io = serio;
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 2f12d60eee3..bc033250dfc 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -546,8 +546,8 @@ static void serio_init_port(struct serio *serio)
546 spin_lock_init(&serio->lock); 546 spin_lock_init(&serio->lock);
547 mutex_init(&serio->drv_mutex); 547 mutex_init(&serio->drv_mutex);
548 device_initialize(&serio->dev); 548 device_initialize(&serio->dev);
549 snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id), 549 dev_set_name(&serio->dev, "serio%ld",
550 "serio%ld", (long)atomic_inc_return(&serio_no) - 1); 550 (long)atomic_inc_return(&serio_no) - 1);
551 serio->dev.bus = &serio_bus; 551 serio->dev.bus = &serio_bus;
552 serio->dev.release = serio_release_port; 552 serio->dev.release = serio_release_port;
553 if (serio->parent) { 553 if (serio->parent) {
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c
index 765007899d9..ebb22f88c84 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 */