Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.21-rc3 742 lines 17 kB view raw
1/* 2 * Driver for NEC VR4100 series General-purpose I/O Unit. 3 * 4 * Copyright (C) 2002 MontaVista Software Inc. 5 * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com> 6 * Copyright (C) 2003-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22#include <linux/platform_device.h> 23#include <linux/errno.h> 24#include <linux/fs.h> 25#include <linux/init.h> 26#include <linux/irq.h> 27#include <linux/interrupt.h> 28#include <linux/kernel.h> 29#include <linux/module.h> 30#include <linux/spinlock.h> 31#include <linux/types.h> 32 33#include <asm/cpu.h> 34#include <asm/io.h> 35#include <asm/vr41xx/giu.h> 36#include <asm/vr41xx/irq.h> 37#include <asm/vr41xx/vr41xx.h> 38 39MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); 40MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver"); 41MODULE_LICENSE("GPL"); 42 43static int major; /* default is dynamic major device number */ 44module_param(major, int, 0); 45MODULE_PARM_DESC(major, "Major device number"); 46 47#define GIU_TYPE1_START 0x0b000100UL 48#define GIU_TYPE1_SIZE 0x20UL 49 50#define GIU_TYPE2_START 0x0f000140UL 51#define GIU_TYPE2_SIZE 0x20UL 52 53#define GIU_TYPE3_START 0x0f000140UL 54#define GIU_TYPE3_SIZE 0x28UL 55 56#define GIU_PULLUPDOWN_START 0x0b0002e0UL 57#define GIU_PULLUPDOWN_SIZE 0x04UL 58 59#define GIUIOSELL 0x00 60#define GIUIOSELH 0x02 61#define GIUPIODL 0x04 62#define GIUPIODH 0x06 63#define GIUINTSTATL 0x08 64#define GIUINTSTATH 0x0a 65#define GIUINTENL 0x0c 66#define GIUINTENH 0x0e 67#define GIUINTTYPL 0x10 68#define GIUINTTYPH 0x12 69#define GIUINTALSELL 0x14 70#define GIUINTALSELH 0x16 71#define GIUINTHTSELL 0x18 72#define GIUINTHTSELH 0x1a 73#define GIUPODATL 0x1c 74#define GIUPODATEN 0x1c 75#define GIUPODATH 0x1e 76 #define PIOEN0 0x0100 77 #define PIOEN1 0x0200 78#define GIUPODAT 0x1e 79#define GIUFEDGEINHL 0x20 80#define GIUFEDGEINHH 0x22 81#define GIUREDGEINHL 0x24 82#define GIUREDGEINHH 0x26 83 84#define GIUUSEUPDN 0x1e0 85#define GIUTERMUPDN 0x1e2 86 87#define GPIO_HAS_PULLUPDOWN_IO 0x0001 88#define GPIO_HAS_OUTPUT_ENABLE 0x0002 89#define GPIO_HAS_INTERRUPT_EDGE_SELECT 0x0100 90 91static spinlock_t giu_lock; 92static struct resource *giu_resource1; 93static struct resource *giu_resource2; 94static unsigned long giu_flags; 95static unsigned int giu_nr_pins; 96 97static void __iomem *giu_base; 98 99#define giu_read(offset) readw(giu_base + (offset)) 100#define giu_write(offset, value) writew((value), giu_base + (offset)) 101 102#define GPIO_PIN_OF_IRQ(irq) ((irq) - GIU_IRQ_BASE) 103#define GIUINT_HIGH_OFFSET 16 104#define GIUINT_HIGH_MAX 32 105 106static inline uint16_t giu_set(uint16_t offset, uint16_t set) 107{ 108 uint16_t data; 109 110 data = giu_read(offset); 111 data |= set; 112 giu_write(offset, data); 113 114 return data; 115} 116 117static inline uint16_t giu_clear(uint16_t offset, uint16_t clear) 118{ 119 uint16_t data; 120 121 data = giu_read(offset); 122 data &= ~clear; 123 giu_write(offset, data); 124 125 return data; 126} 127 128static void ack_giuint_low(unsigned int irq) 129{ 130 giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq)); 131} 132 133static void mask_giuint_low(unsigned int irq) 134{ 135 giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); 136} 137 138static void mask_ack_giuint_low(unsigned int irq) 139{ 140 unsigned int pin; 141 142 pin = GPIO_PIN_OF_IRQ(irq); 143 giu_clear(GIUINTENL, 1 << pin); 144 giu_write(GIUINTSTATL, 1 << pin); 145} 146 147static void unmask_giuint_low(unsigned int irq) 148{ 149 giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); 150} 151 152static struct irq_chip giuint_low_irq_chip = { 153 .name = "GIUINTL", 154 .ack = ack_giuint_low, 155 .mask = mask_giuint_low, 156 .mask_ack = mask_ack_giuint_low, 157 .unmask = unmask_giuint_low, 158}; 159 160static void ack_giuint_high(unsigned int irq) 161{ 162 giu_write(GIUINTSTATH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); 163} 164 165static void mask_giuint_high(unsigned int irq) 166{ 167 giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); 168} 169 170static void mask_ack_giuint_high(unsigned int irq) 171{ 172 unsigned int pin; 173 174 pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; 175 giu_clear(GIUINTENH, 1 << pin); 176 giu_write(GIUINTSTATH, 1 << pin); 177} 178 179static void unmask_giuint_high(unsigned int irq) 180{ 181 giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); 182} 183 184static struct irq_chip giuint_high_irq_chip = { 185 .name = "GIUINTH", 186 .ack = ack_giuint_high, 187 .mask = mask_giuint_high, 188 .mask_ack = mask_ack_giuint_high, 189 .unmask = unmask_giuint_high, 190}; 191 192static int giu_get_irq(unsigned int irq) 193{ 194 uint16_t pendl, pendh, maskl, maskh; 195 int i; 196 197 pendl = giu_read(GIUINTSTATL); 198 pendh = giu_read(GIUINTSTATH); 199 maskl = giu_read(GIUINTENL); 200 maskh = giu_read(GIUINTENH); 201 202 maskl &= pendl; 203 maskh &= pendh; 204 205 if (maskl) { 206 for (i = 0; i < 16; i++) { 207 if (maskl & (1 << i)) 208 return GIU_IRQ(i); 209 } 210 } else if (maskh) { 211 for (i = 0; i < 16; i++) { 212 if (maskh & (1 << i)) 213 return GIU_IRQ(i + GIUINT_HIGH_OFFSET); 214 } 215 } 216 217 printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", 218 maskl, pendl, maskh, pendh); 219 220 atomic_inc(&irq_err_count); 221 222 return -EINVAL; 223} 224 225void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_t signal) 226{ 227 uint16_t mask; 228 229 if (pin < GIUINT_HIGH_OFFSET) { 230 mask = 1 << pin; 231 if (trigger != IRQ_TRIGGER_LEVEL) { 232 giu_set(GIUINTTYPL, mask); 233 if (signal == IRQ_SIGNAL_HOLD) 234 giu_set(GIUINTHTSELL, mask); 235 else 236 giu_clear(GIUINTHTSELL, mask); 237 if (current_cpu_data.cputype == CPU_VR4133) { 238 switch (trigger) { 239 case IRQ_TRIGGER_EDGE_FALLING: 240 giu_set(GIUFEDGEINHL, mask); 241 giu_clear(GIUREDGEINHL, mask); 242 break; 243 case IRQ_TRIGGER_EDGE_RISING: 244 giu_clear(GIUFEDGEINHL, mask); 245 giu_set(GIUREDGEINHL, mask); 246 break; 247 default: 248 giu_set(GIUFEDGEINHL, mask); 249 giu_set(GIUREDGEINHL, mask); 250 break; 251 } 252 } 253 set_irq_chip_and_handler(GIU_IRQ(pin), 254 &giuint_low_irq_chip, 255 handle_edge_irq); 256 } else { 257 giu_clear(GIUINTTYPL, mask); 258 giu_clear(GIUINTHTSELL, mask); 259 set_irq_chip_and_handler(GIU_IRQ(pin), 260 &giuint_low_irq_chip, 261 handle_level_irq); 262 } 263 giu_write(GIUINTSTATL, mask); 264 } else if (pin < GIUINT_HIGH_MAX) { 265 mask = 1 << (pin - GIUINT_HIGH_OFFSET); 266 if (trigger != IRQ_TRIGGER_LEVEL) { 267 giu_set(GIUINTTYPH, mask); 268 if (signal == IRQ_SIGNAL_HOLD) 269 giu_set(GIUINTHTSELH, mask); 270 else 271 giu_clear(GIUINTHTSELH, mask); 272 if (current_cpu_data.cputype == CPU_VR4133) { 273 switch (trigger) { 274 case IRQ_TRIGGER_EDGE_FALLING: 275 giu_set(GIUFEDGEINHH, mask); 276 giu_clear(GIUREDGEINHH, mask); 277 break; 278 case IRQ_TRIGGER_EDGE_RISING: 279 giu_clear(GIUFEDGEINHH, mask); 280 giu_set(GIUREDGEINHH, mask); 281 break; 282 default: 283 giu_set(GIUFEDGEINHH, mask); 284 giu_set(GIUREDGEINHH, mask); 285 break; 286 } 287 } 288 set_irq_chip_and_handler(GIU_IRQ(pin), 289 &giuint_high_irq_chip, 290 handle_edge_irq); 291 } else { 292 giu_clear(GIUINTTYPH, mask); 293 giu_clear(GIUINTHTSELH, mask); 294 set_irq_chip_and_handler(GIU_IRQ(pin), 295 &giuint_high_irq_chip, 296 handle_level_irq); 297 } 298 giu_write(GIUINTSTATH, mask); 299 } 300} 301 302EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger); 303 304void vr41xx_set_irq_level(unsigned int pin, irq_level_t level) 305{ 306 uint16_t mask; 307 308 if (pin < GIUINT_HIGH_OFFSET) { 309 mask = 1 << pin; 310 if (level == IRQ_LEVEL_HIGH) 311 giu_set(GIUINTALSELL, mask); 312 else 313 giu_clear(GIUINTALSELL, mask); 314 giu_write(GIUINTSTATL, mask); 315 } else if (pin < GIUINT_HIGH_MAX) { 316 mask = 1 << (pin - GIUINT_HIGH_OFFSET); 317 if (level == IRQ_LEVEL_HIGH) 318 giu_set(GIUINTALSELH, mask); 319 else 320 giu_clear(GIUINTALSELH, mask); 321 giu_write(GIUINTSTATH, mask); 322 } 323} 324 325EXPORT_SYMBOL_GPL(vr41xx_set_irq_level); 326 327gpio_data_t vr41xx_gpio_get_pin(unsigned int pin) 328{ 329 uint16_t reg, mask; 330 331 if (pin >= giu_nr_pins) 332 return GPIO_DATA_INVAL; 333 334 if (pin < 16) { 335 reg = giu_read(GIUPIODL); 336 mask = (uint16_t)1 << pin; 337 } else if (pin < 32) { 338 reg = giu_read(GIUPIODH); 339 mask = (uint16_t)1 << (pin - 16); 340 } else if (pin < 48) { 341 reg = giu_read(GIUPODATL); 342 mask = (uint16_t)1 << (pin - 32); 343 } else { 344 reg = giu_read(GIUPODATH); 345 mask = (uint16_t)1 << (pin - 48); 346 } 347 348 if (reg & mask) 349 return GPIO_DATA_HIGH; 350 351 return GPIO_DATA_LOW; 352} 353 354EXPORT_SYMBOL_GPL(vr41xx_gpio_get_pin); 355 356int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data) 357{ 358 uint16_t offset, mask, reg; 359 unsigned long flags; 360 361 if (pin >= giu_nr_pins) 362 return -EINVAL; 363 364 if (pin < 16) { 365 offset = GIUPIODL; 366 mask = (uint16_t)1 << pin; 367 } else if (pin < 32) { 368 offset = GIUPIODH; 369 mask = (uint16_t)1 << (pin - 16); 370 } else if (pin < 48) { 371 offset = GIUPODATL; 372 mask = (uint16_t)1 << (pin - 32); 373 } else { 374 offset = GIUPODATH; 375 mask = (uint16_t)1 << (pin - 48); 376 } 377 378 spin_lock_irqsave(&giu_lock, flags); 379 380 reg = giu_read(offset); 381 if (data == GPIO_DATA_HIGH) 382 reg |= mask; 383 else 384 reg &= ~mask; 385 giu_write(offset, reg); 386 387 spin_unlock_irqrestore(&giu_lock, flags); 388 389 return 0; 390} 391 392EXPORT_SYMBOL_GPL(vr41xx_gpio_set_pin); 393 394int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir) 395{ 396 uint16_t offset, mask, reg; 397 unsigned long flags; 398 399 if (pin >= giu_nr_pins) 400 return -EINVAL; 401 402 if (pin < 16) { 403 offset = GIUIOSELL; 404 mask = (uint16_t)1 << pin; 405 } else if (pin < 32) { 406 offset = GIUIOSELH; 407 mask = (uint16_t)1 << (pin - 16); 408 } else { 409 if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) { 410 offset = GIUPODATEN; 411 mask = (uint16_t)1 << (pin - 32); 412 } else { 413 switch (pin) { 414 case 48: 415 offset = GIUPODATH; 416 mask = PIOEN0; 417 break; 418 case 49: 419 offset = GIUPODATH; 420 mask = PIOEN1; 421 break; 422 default: 423 return -EINVAL; 424 } 425 } 426 } 427 428 spin_lock_irqsave(&giu_lock, flags); 429 430 reg = giu_read(offset); 431 if (dir == GPIO_OUTPUT) 432 reg |= mask; 433 else 434 reg &= ~mask; 435 giu_write(offset, reg); 436 437 spin_unlock_irqrestore(&giu_lock, flags); 438 439 return 0; 440} 441 442EXPORT_SYMBOL_GPL(vr41xx_gpio_set_direction); 443 444int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull) 445{ 446 uint16_t reg, mask; 447 unsigned long flags; 448 449 if ((giu_flags & GPIO_HAS_PULLUPDOWN_IO) != GPIO_HAS_PULLUPDOWN_IO) 450 return -EPERM; 451 452 if (pin >= 15) 453 return -EINVAL; 454 455 mask = (uint16_t)1 << pin; 456 457 spin_lock_irqsave(&giu_lock, flags); 458 459 if (pull == GPIO_PULL_UP || pull == GPIO_PULL_DOWN) { 460 reg = giu_read(GIUTERMUPDN); 461 if (pull == GPIO_PULL_UP) 462 reg |= mask; 463 else 464 reg &= ~mask; 465 giu_write(GIUTERMUPDN, reg); 466 467 reg = giu_read(GIUUSEUPDN); 468 reg |= mask; 469 giu_write(GIUUSEUPDN, reg); 470 } else { 471 reg = giu_read(GIUUSEUPDN); 472 reg &= ~mask; 473 giu_write(GIUUSEUPDN, reg); 474 } 475 476 spin_unlock_irqrestore(&giu_lock, flags); 477 478 return 0; 479} 480 481EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown); 482 483static ssize_t gpio_read(struct file *file, char __user *buf, size_t len, 484 loff_t *ppos) 485{ 486 unsigned int pin; 487 char value = '0'; 488 489 pin = iminor(file->f_path.dentry->d_inode); 490 if (pin >= giu_nr_pins) 491 return -EBADF; 492 493 if (vr41xx_gpio_get_pin(pin) == GPIO_DATA_HIGH) 494 value = '1'; 495 496 if (len <= 0) 497 return -EFAULT; 498 499 if (put_user(value, buf)) 500 return -EFAULT; 501 502 return 1; 503} 504 505static ssize_t gpio_write(struct file *file, const char __user *data, 506 size_t len, loff_t *ppos) 507{ 508 unsigned int pin; 509 size_t i; 510 char c; 511 int retval = 0; 512 513 pin = iminor(file->f_path.dentry->d_inode); 514 if (pin >= giu_nr_pins) 515 return -EBADF; 516 517 for (i = 0; i < len; i++) { 518 if (get_user(c, data + i)) 519 return -EFAULT; 520 521 switch (c) { 522 case '0': 523 retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_LOW); 524 break; 525 case '1': 526 retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_HIGH); 527 break; 528 case 'D': 529 printk(KERN_INFO "GPIO%d: pull down\n", pin); 530 retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DOWN); 531 break; 532 case 'd': 533 printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin); 534 retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE); 535 break; 536 case 'I': 537 printk(KERN_INFO "GPIO%d: input\n", pin); 538 retval = vr41xx_gpio_set_direction(pin, GPIO_INPUT); 539 break; 540 case 'O': 541 printk(KERN_INFO "GPIO%d: output\n", pin); 542 retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT); 543 break; 544 case 'o': 545 printk(KERN_INFO "GPIO%d: output disable\n", pin); 546 retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT_DISABLE); 547 break; 548 case 'P': 549 printk(KERN_INFO "GPIO%d: pull up\n", pin); 550 retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_UP); 551 break; 552 case 'p': 553 printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin); 554 retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE); 555 break; 556 default: 557 break; 558 } 559 560 if (retval < 0) 561 break; 562 } 563 564 return i; 565} 566 567static int gpio_open(struct inode *inode, struct file *file) 568{ 569 unsigned int pin; 570 571 pin = iminor(inode); 572 if (pin >= giu_nr_pins) 573 return -EBADF; 574 575 return nonseekable_open(inode, file); 576} 577 578static int gpio_release(struct inode *inode, struct file *file) 579{ 580 unsigned int pin; 581 582 pin = iminor(inode); 583 if (pin >= giu_nr_pins) 584 return -EBADF; 585 586 return 0; 587} 588 589static const struct file_operations gpio_fops = { 590 .owner = THIS_MODULE, 591 .read = gpio_read, 592 .write = gpio_write, 593 .open = gpio_open, 594 .release = gpio_release, 595}; 596 597static int __devinit giu_probe(struct platform_device *dev) 598{ 599 unsigned long start, size, flags = 0; 600 unsigned int nr_pins = 0, trigger, i, pin; 601 struct resource *res1, *res2 = NULL; 602 void *base; 603 struct irq_chip *chip; 604 int retval; 605 606 switch (current_cpu_data.cputype) { 607 case CPU_VR4111: 608 case CPU_VR4121: 609 start = GIU_TYPE1_START; 610 size = GIU_TYPE1_SIZE; 611 flags = GPIO_HAS_PULLUPDOWN_IO; 612 nr_pins = 50; 613 break; 614 case CPU_VR4122: 615 case CPU_VR4131: 616 start = GIU_TYPE2_START; 617 size = GIU_TYPE2_SIZE; 618 nr_pins = 36; 619 break; 620 case CPU_VR4133: 621 start = GIU_TYPE3_START; 622 size = GIU_TYPE3_SIZE; 623 flags = GPIO_HAS_INTERRUPT_EDGE_SELECT; 624 nr_pins = 48; 625 break; 626 default: 627 return -ENODEV; 628 } 629 630 res1 = request_mem_region(start, size, "GIU"); 631 if (res1 == NULL) 632 return -EBUSY; 633 634 base = ioremap(start, size); 635 if (base == NULL) { 636 release_resource(res1); 637 return -ENOMEM; 638 } 639 640 if (flags & GPIO_HAS_PULLUPDOWN_IO) { 641 res2 = request_mem_region(GIU_PULLUPDOWN_START, GIU_PULLUPDOWN_SIZE, "GIU"); 642 if (res2 == NULL) { 643 iounmap(base); 644 release_resource(res1); 645 return -EBUSY; 646 } 647 } 648 649 retval = register_chrdev(major, "GIU", &gpio_fops); 650 if (retval < 0) { 651 iounmap(base); 652 release_resource(res1); 653 release_resource(res2); 654 return retval; 655 } 656 657 if (major == 0) { 658 major = retval; 659 printk(KERN_INFO "GIU: major number %d\n", major); 660 } 661 662 spin_lock_init(&giu_lock); 663 giu_base = base; 664 giu_resource1 = res1; 665 giu_resource2 = res2; 666 giu_flags = flags; 667 giu_nr_pins = nr_pins; 668 669 giu_write(GIUINTENL, 0); 670 giu_write(GIUINTENH, 0); 671 672 trigger = giu_read(GIUINTTYPH) << 16; 673 trigger |= giu_read(GIUINTTYPL); 674 for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { 675 pin = GPIO_PIN_OF_IRQ(i); 676 if (pin < GIUINT_HIGH_OFFSET) 677 chip = &giuint_low_irq_chip; 678 else 679 chip = &giuint_high_irq_chip; 680 681 if (trigger & (1 << pin)) 682 set_irq_chip_and_handler(i, chip, handle_edge_irq); 683 else 684 set_irq_chip_and_handler(i, chip, handle_level_irq); 685 686 } 687 688 return cascade_irq(GIUINT_IRQ, giu_get_irq); 689} 690 691static int __devexit giu_remove(struct platform_device *dev) 692{ 693 iounmap(giu_base); 694 695 release_resource(giu_resource1); 696 if (giu_flags & GPIO_HAS_PULLUPDOWN_IO) 697 release_resource(giu_resource2); 698 699 return 0; 700} 701 702static struct platform_device *giu_platform_device; 703 704static struct platform_driver giu_device_driver = { 705 .probe = giu_probe, 706 .remove = __devexit_p(giu_remove), 707 .driver = { 708 .name = "GIU", 709 .owner = THIS_MODULE, 710 }, 711}; 712 713static int __init vr41xx_giu_init(void) 714{ 715 int retval; 716 717 giu_platform_device = platform_device_alloc("GIU", -1); 718 if (!giu_platform_device) 719 return -ENOMEM; 720 721 retval = platform_device_add(giu_platform_device); 722 if (retval < 0) { 723 platform_device_put(giu_platform_device); 724 return retval; 725 } 726 727 retval = platform_driver_register(&giu_device_driver); 728 if (retval < 0) 729 platform_device_unregister(giu_platform_device); 730 731 return retval; 732} 733 734static void __exit vr41xx_giu_exit(void) 735{ 736 platform_driver_unregister(&giu_device_driver); 737 738 platform_device_unregister(giu_platform_device); 739} 740 741module_init(vr41xx_giu_init); 742module_exit(vr41xx_giu_exit);