diff options
Diffstat (limited to 'drivers')
31 files changed, 1449 insertions, 883 deletions
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index af3969a9c963..e824b672e05a 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c | |||
| @@ -74,53 +74,9 @@ enum { | |||
| 74 | static DEFINE_SPINLOCK(viodasd_spinlock); | 74 | static DEFINE_SPINLOCK(viodasd_spinlock); |
| 75 | 75 | ||
| 76 | #define VIOMAXREQ 16 | 76 | #define VIOMAXREQ 16 |
| 77 | #define VIOMAXBLOCKDMA 12 | ||
| 78 | 77 | ||
| 79 | #define DEVICE_NO(cell) ((struct viodasd_device *)(cell) - &viodasd_devices[0]) | 78 | #define DEVICE_NO(cell) ((struct viodasd_device *)(cell) - &viodasd_devices[0]) |
| 80 | 79 | ||
| 81 | struct open_data { | ||
| 82 | u64 disk_size; | ||
| 83 | u16 max_disk; | ||
| 84 | u16 cylinders; | ||
| 85 | u16 tracks; | ||
| 86 | u16 sectors; | ||
| 87 | u16 bytes_per_sector; | ||
| 88 | }; | ||
| 89 | |||
| 90 | struct rw_data { | ||
| 91 | u64 offset; | ||
| 92 | struct { | ||
| 93 | u32 token; | ||
| 94 | u32 reserved; | ||
| 95 | u64 len; | ||
| 96 | } dma_info[VIOMAXBLOCKDMA]; | ||
| 97 | }; | ||
| 98 | |||
| 99 | struct vioblocklpevent { | ||
| 100 | struct HvLpEvent event; | ||
| 101 | u32 reserved; | ||
| 102 | u16 version; | ||
| 103 | u16 sub_result; | ||
| 104 | u16 disk; | ||
| 105 | u16 flags; | ||
| 106 | union { | ||
| 107 | struct open_data open_data; | ||
| 108 | struct rw_data rw_data; | ||
| 109 | u64 changed; | ||
| 110 | } u; | ||
| 111 | }; | ||
| 112 | |||
| 113 | #define vioblockflags_ro 0x0001 | ||
| 114 | |||
| 115 | enum vioblocksubtype { | ||
| 116 | vioblockopen = 0x0001, | ||
| 117 | vioblockclose = 0x0002, | ||
| 118 | vioblockread = 0x0003, | ||
| 119 | vioblockwrite = 0x0004, | ||
| 120 | vioblockflush = 0x0005, | ||
| 121 | vioblockcheck = 0x0007 | ||
| 122 | }; | ||
| 123 | |||
| 124 | struct viodasd_waitevent { | 80 | struct viodasd_waitevent { |
| 125 | struct completion com; | 81 | struct completion com; |
| 126 | int rc; | 82 | int rc; |
| @@ -429,7 +385,7 @@ static void do_viodasd_request(struct request_queue *q) | |||
| 429 | * Probe a single disk and fill in the viodasd_device structure | 385 | * Probe a single disk and fill in the viodasd_device structure |
| 430 | * for it. | 386 | * for it. |
| 431 | */ | 387 | */ |
| 432 | static void probe_disk(struct viodasd_device *d) | 388 | static int probe_disk(struct viodasd_device *d) |
| 433 | { | 389 | { |
| 434 | HvLpEvent_Rc hvrc; | 390 | HvLpEvent_Rc hvrc; |
| 435 | struct viodasd_waitevent we; | 391 | struct viodasd_waitevent we; |
| @@ -453,14 +409,14 @@ retry: | |||
| 453 | 0, 0, 0); | 409 | 0, 0, 0); |
| 454 | if (hvrc != 0) { | 410 | if (hvrc != 0) { |
| 455 | printk(VIOD_KERN_WARNING "bad rc on HV open %d\n", (int)hvrc); | 411 | printk(VIOD_KERN_WARNING "bad rc on HV open %d\n", (int)hvrc); |
| 456 | return; | 412 | return 0; |
| 457 | } | 413 | } |
| 458 | 414 | ||
| 459 | wait_for_completion(&we.com); | 415 | wait_for_completion(&we.com); |
| 460 | 416 | ||
| 461 | if (we.rc != 0) { | 417 | if (we.rc != 0) { |
| 462 | if (flags != 0) | 418 | if (flags != 0) |
| 463 | return; | 419 | return 0; |
| 464 | /* try again with read only flag set */ | 420 | /* try again with read only flag set */ |
| 465 | flags = vioblockflags_ro; | 421 | flags = vioblockflags_ro; |
| 466 | goto retry; | 422 | goto retry; |
| @@ -490,15 +446,32 @@ retry: | |||
| 490 | if (hvrc != 0) { | 446 | if (hvrc != 0) { |
| 491 | printk(VIOD_KERN_WARNING | 447 | printk(VIOD_KERN_WARNING |
| 492 | "bad rc sending event to OS/400 %d\n", (int)hvrc); | 448 | "bad rc sending event to OS/400 %d\n", (int)hvrc); |
| 493 | return; | 449 | return 0; |
| 494 | } | 450 | } |
| 451 | |||
| 452 | if (d->dev == NULL) { | ||
| 453 | /* this is when we reprobe for new disks */ | ||
| 454 | if (vio_create_viodasd(dev_no) == NULL) { | ||
| 455 | printk(VIOD_KERN_WARNING | ||
| 456 | "cannot allocate virtual device for disk %d\n", | ||
| 457 | dev_no); | ||
| 458 | return 0; | ||
| 459 | } | ||
| 460 | /* | ||
| 461 | * The vio_create_viodasd will have recursed into this | ||
| 462 | * routine with d->dev set to the new vio device and | ||
| 463 | * will finish the setup of the disk below. | ||
| 464 | */ | ||
| 465 | return 1; | ||
| 466 | } | ||
| 467 | |||
| 495 | /* create the request queue for the disk */ | 468 | /* create the request queue for the disk */ |
| 496 | spin_lock_init(&d->q_lock); | 469 | spin_lock_init(&d->q_lock); |
| 497 | q = blk_init_queue(do_viodasd_request, &d->q_lock); | 470 | q = blk_init_queue(do_viodasd_request, &d->q_lock); |
| 498 | if (q == NULL) { | 471 | if (q == NULL) { |
| 499 | printk(VIOD_KERN_WARNING "cannot allocate queue for disk %d\n", | 472 | printk(VIOD_KERN_WARNING "cannot allocate queue for disk %d\n", |
| 500 | dev_no); | 473 | dev_no); |
| 501 | return; | 474 | return 0; |
| 502 | } | 475 | } |
| 503 | g = alloc_disk(1 << PARTITION_SHIFT); | 476 | g = alloc_disk(1 << PARTITION_SHIFT); |
| 504 | if (g == NULL) { | 477 | if (g == NULL) { |
| @@ -506,7 +479,7 @@ retry: | |||
| 506 | "cannot allocate disk structure for disk %d\n", | 479 | "cannot allocate disk structure for disk %d\n", |
| 507 | dev_no); | 480 | dev_no); |
| 508 | blk_cleanup_queue(q); | 481 | blk_cleanup_queue(q); |
| 509 | return; | 482 | return 0; |
| 510 | } | 483 | } |
| 511 | 484 | ||
| 512 | d->disk = g; | 485 | d->disk = g; |
| @@ -538,6 +511,7 @@ retry: | |||
| 538 | 511 | ||
| 539 | /* register us in the global list */ | 512 | /* register us in the global list */ |
| 540 | add_disk(g); | 513 | add_disk(g); |
| 514 | return 1; | ||
| 541 | } | 515 | } |
| 542 | 516 | ||
| 543 | /* returns the total number of scatterlist elements converted */ | 517 | /* returns the total number of scatterlist elements converted */ |
| @@ -718,8 +692,7 @@ static int viodasd_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
| 718 | struct viodasd_device *d = &viodasd_devices[vdev->unit_address]; | 692 | struct viodasd_device *d = &viodasd_devices[vdev->unit_address]; |
| 719 | 693 | ||
| 720 | d->dev = &vdev->dev; | 694 | d->dev = &vdev->dev; |
| 721 | probe_disk(d); | 695 | if (!probe_disk(d)) |
| 722 | if (d->disk == NULL) | ||
| 723 | return -ENODEV; | 696 | return -ENODEV; |
| 724 | return 0; | 697 | return 0; |
| 725 | } | 698 | } |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index e51550db1575..880b5dce3a62 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
| @@ -56,30 +56,6 @@ | |||
| 56 | #define VIOCD_KERN_WARNING KERN_WARNING "viocd: " | 56 | #define VIOCD_KERN_WARNING KERN_WARNING "viocd: " |
| 57 | #define VIOCD_KERN_INFO KERN_INFO "viocd: " | 57 | #define VIOCD_KERN_INFO KERN_INFO "viocd: " |
| 58 | 58 | ||
| 59 | struct viocdlpevent { | ||
| 60 | struct HvLpEvent event; | ||
| 61 | u32 reserved; | ||
| 62 | u16 version; | ||
| 63 | u16 sub_result; | ||
| 64 | u16 disk; | ||
| 65 | u16 flags; | ||
| 66 | u32 token; | ||
| 67 | u64 offset; /* On open, max number of disks */ | ||
| 68 | u64 len; /* On open, size of the disk */ | ||
| 69 | u32 block_size; /* Only set on open */ | ||
| 70 | u32 media_size; /* Only set on open */ | ||
| 71 | }; | ||
| 72 | |||
| 73 | enum viocdsubtype { | ||
| 74 | viocdopen = 0x0001, | ||
| 75 | viocdclose = 0x0002, | ||
| 76 | viocdread = 0x0003, | ||
| 77 | viocdwrite = 0x0004, | ||
| 78 | viocdlockdoor = 0x0005, | ||
| 79 | viocdgetinfo = 0x0006, | ||
| 80 | viocdcheck = 0x0007 | ||
| 81 | }; | ||
| 82 | |||
| 83 | /* | 59 | /* |
| 84 | * Should probably make this a module parameter....sigh | 60 | * Should probably make this a module parameter....sigh |
| 85 | */ | 61 | */ |
| @@ -131,22 +107,13 @@ static struct capability_entry capability_table[] __initdata = { | |||
| 131 | /* These are our internal structures for keeping track of devices */ | 107 | /* These are our internal structures for keeping track of devices */ |
| 132 | static int viocd_numdev; | 108 | static int viocd_numdev; |
| 133 | 109 | ||
| 134 | struct cdrom_info { | ||
| 135 | char rsrcname[10]; | ||
| 136 | char type[4]; | ||
| 137 | char model[3]; | ||
| 138 | }; | ||
| 139 | /* | ||
| 140 | * This needs to be allocated since it is passed to the | ||
| 141 | * Hypervisor and we may be a module. | ||
| 142 | */ | ||
| 143 | static struct cdrom_info *viocd_unitinfo; | ||
| 144 | static dma_addr_t unitinfo_dmaaddr; | ||
| 145 | |||
| 146 | struct disk_info { | 110 | struct disk_info { |
| 147 | struct gendisk *viocd_disk; | 111 | struct gendisk *viocd_disk; |
| 148 | struct cdrom_device_info viocd_info; | 112 | struct cdrom_device_info viocd_info; |
| 149 | struct device *dev; | 113 | struct device *dev; |
| 114 | const char *rsrcname; | ||
| 115 | const char *type; | ||
| 116 | const char *model; | ||
| 150 | }; | 117 | }; |
| 151 | static struct disk_info viocd_diskinfo[VIOCD_MAX_CD]; | 118 | static struct disk_info viocd_diskinfo[VIOCD_MAX_CD]; |
| 152 | 119 | ||
| @@ -164,9 +131,9 @@ static int proc_viocd_show(struct seq_file *m, void *v) | |||
| 164 | for (i = 0; i < viocd_numdev; i++) { | 131 | for (i = 0; i < viocd_numdev; i++) { |
| 165 | seq_printf(m, "viocd device %d is iSeries resource %10.10s" | 132 | seq_printf(m, "viocd device %d is iSeries resource %10.10s" |
| 166 | "type %4.4s, model %3.3s\n", | 133 | "type %4.4s, model %3.3s\n", |
| 167 | i, viocd_unitinfo[i].rsrcname, | 134 | i, viocd_diskinfo[i].rsrcname, |
| 168 | viocd_unitinfo[i].type, | 135 | viocd_diskinfo[i].type, |
| 169 | viocd_unitinfo[i].model); | 136 | viocd_diskinfo[i].model); |
| 170 | } | 137 | } |
| 171 | return 0; | 138 | return 0; |
| 172 | } | 139 | } |
| @@ -216,61 +183,6 @@ struct block_device_operations viocd_fops = { | |||
| 216 | .media_changed = viocd_blk_media_changed, | 183 | .media_changed = viocd_blk_media_changed, |
| 217 | }; | 184 | }; |
| 218 | 185 | ||
| 219 | /* Get info on CD devices from OS/400 */ | ||
| 220 | static void __init get_viocd_info(void) | ||
| 221 | { | ||
| 222 | HvLpEvent_Rc hvrc; | ||
| 223 | int i; | ||
| 224 | struct viocd_waitevent we; | ||
| 225 | |||
| 226 | viocd_unitinfo = dma_alloc_coherent(iSeries_vio_dev, | ||
| 227 | sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, | ||
| 228 | &unitinfo_dmaaddr, GFP_ATOMIC); | ||
| 229 | if (viocd_unitinfo == NULL) { | ||
| 230 | printk(VIOCD_KERN_WARNING "error allocating unitinfo\n"); | ||
| 231 | return; | ||
| 232 | } | ||
| 233 | |||
| 234 | memset(viocd_unitinfo, 0, sizeof(*viocd_unitinfo) * VIOCD_MAX_CD); | ||
| 235 | |||
| 236 | init_completion(&we.com); | ||
| 237 | |||
| 238 | hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, | ||
| 239 | HvLpEvent_Type_VirtualIo, | ||
| 240 | viomajorsubtype_cdio | viocdgetinfo, | ||
| 241 | HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, | ||
| 242 | viopath_sourceinst(viopath_hostLp), | ||
| 243 | viopath_targetinst(viopath_hostLp), | ||
| 244 | (u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0, | ||
| 245 | sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, 0); | ||
| 246 | if (hvrc != HvLpEvent_Rc_Good) { | ||
| 247 | printk(VIOCD_KERN_WARNING "cdrom error sending event. rc %d\n", | ||
| 248 | (int)hvrc); | ||
| 249 | goto error_ret; | ||
| 250 | } | ||
| 251 | |||
| 252 | wait_for_completion(&we.com); | ||
| 253 | |||
| 254 | if (we.rc) { | ||
| 255 | const struct vio_error_entry *err = | ||
| 256 | vio_lookup_rc(viocd_err_table, we.sub_result); | ||
| 257 | printk(VIOCD_KERN_WARNING "bad rc %d:0x%04X on getinfo: %s\n", | ||
| 258 | we.rc, we.sub_result, err->msg); | ||
| 259 | goto error_ret; | ||
| 260 | } | ||
| 261 | |||
| 262 | for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++) | ||
| 263 | viocd_numdev++; | ||
| 264 | |||
| 265 | error_ret: | ||
| 266 | if (viocd_numdev == 0) { | ||
| 267 | dma_free_coherent(iSeries_vio_dev, | ||
| 268 | sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, | ||
| 269 | viocd_unitinfo, unitinfo_dmaaddr); | ||
| 270 | viocd_unitinfo = NULL; | ||
| 271 | } | ||
| 272 | } | ||
| 273 | |||
| 274 | static int viocd_open(struct cdrom_device_info *cdi, int purpose) | 186 | static int viocd_open(struct cdrom_device_info *cdi, int purpose) |
| 275 | { | 187 | { |
| 276 | struct disk_info *diskinfo = cdi->handle; | 188 | struct disk_info *diskinfo = cdi->handle; |
| @@ -581,7 +493,6 @@ static void vio_handle_cd_event(struct HvLpEvent *event) | |||
| 581 | bevent->block_size / 512); | 493 | bevent->block_size / 512); |
| 582 | } | 494 | } |
| 583 | /* FALLTHROUGH !! */ | 495 | /* FALLTHROUGH !! */ |
| 584 | case viocdgetinfo: | ||
| 585 | case viocdlockdoor: | 496 | case viocdlockdoor: |
| 586 | pwe = (struct viocd_waitevent *)event->xCorrelationToken; | 497 | pwe = (struct viocd_waitevent *)event->xCorrelationToken; |
| 587 | return_complete: | 498 | return_complete: |
| @@ -665,22 +576,30 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
| 665 | int deviceno; | 576 | int deviceno; |
| 666 | struct disk_info *d; | 577 | struct disk_info *d; |
| 667 | struct cdrom_device_info *c; | 578 | struct cdrom_device_info *c; |
| 668 | struct cdrom_info *ci; | ||
| 669 | struct request_queue *q; | 579 | struct request_queue *q; |
| 580 | struct device_node *node = vdev->dev.archdata.of_node; | ||
| 670 | 581 | ||
| 671 | deviceno = vdev->unit_address; | 582 | deviceno = vdev->unit_address; |
| 672 | if (deviceno >= viocd_numdev) | 583 | if (deviceno > VIOCD_MAX_CD) |
| 673 | return -ENODEV; | 584 | return -ENODEV; |
| 585 | if (!node) | ||
| 586 | return -ENODEV; | ||
| 587 | |||
| 588 | if (deviceno >= viocd_numdev) | ||
| 589 | viocd_numdev = deviceno + 1; | ||
| 674 | 590 | ||
| 675 | d = &viocd_diskinfo[deviceno]; | 591 | d = &viocd_diskinfo[deviceno]; |
| 592 | d->rsrcname = of_get_property(node, "linux,vio_rsrcname", NULL); | ||
| 593 | d->type = of_get_property(node, "linux,vio_type", NULL); | ||
| 594 | d->model = of_get_property(node, "linux,vio_model", NULL); | ||
| 595 | |||
| 676 | c = &d->viocd_info; | 596 | c = &d->viocd_info; |
| 677 | ci = &viocd_unitinfo[deviceno]; | ||
| 678 | 597 | ||
| 679 | c->ops = &viocd_dops; | 598 | c->ops = &viocd_dops; |
| 680 | c->speed = 4; | 599 | c->speed = 4; |
| 681 | c->capacity = 1; | 600 | c->capacity = 1; |
| 682 | c->handle = d; | 601 | c->handle = d; |
| 683 | c->mask = ~find_capability(ci->type); | 602 | c->mask = ~find_capability(d->type); |
| 684 | sprintf(c->name, VIOCD_DEVICE "%c", 'a' + deviceno); | 603 | sprintf(c->name, VIOCD_DEVICE "%c", 'a' + deviceno); |
| 685 | 604 | ||
| 686 | if (register_cdrom(c) != 0) { | 605 | if (register_cdrom(c) != 0) { |
| @@ -690,7 +609,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
| 690 | } | 609 | } |
| 691 | printk(VIOCD_KERN_INFO "cd %s is iSeries resource %10.10s " | 610 | printk(VIOCD_KERN_INFO "cd %s is iSeries resource %10.10s " |
| 692 | "type %4.4s, model %3.3s\n", | 611 | "type %4.4s, model %3.3s\n", |
| 693 | c->name, ci->rsrcname, ci->type, ci->model); | 612 | c->name, d->rsrcname, d->type, d->model); |
| 694 | q = blk_init_queue(do_viocd_request, &viocd_reqlock); | 613 | q = blk_init_queue(do_viocd_request, &viocd_reqlock); |
| 695 | if (q == NULL) { | 614 | if (q == NULL) { |
| 696 | printk(VIOCD_KERN_WARNING "Cannot allocate queue for %s!\n", | 615 | printk(VIOCD_KERN_WARNING "Cannot allocate queue for %s!\n", |
| @@ -799,8 +718,6 @@ static int __init viocd_init(void) | |||
| 799 | /* Initialize our request handler */ | 718 | /* Initialize our request handler */ |
| 800 | vio_setHandler(viomajorsubtype_cdio, vio_handle_cd_event); | 719 | vio_setHandler(viomajorsubtype_cdio, vio_handle_cd_event); |
| 801 | 720 | ||
| 802 | get_viocd_info(); | ||
| 803 | |||
| 804 | spin_lock_init(&viocd_reqlock); | 721 | spin_lock_init(&viocd_reqlock); |
| 805 | 722 | ||
| 806 | ret = vio_register_driver(&viocd_driver); | 723 | ret = vio_register_driver(&viocd_driver); |
| @@ -816,9 +733,6 @@ static int __init viocd_init(void) | |||
| 816 | return 0; | 733 | return 0; |
| 817 | 734 | ||
| 818 | out_free_info: | 735 | out_free_info: |
| 819 | dma_free_coherent(iSeries_vio_dev, | ||
| 820 | sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, | ||
| 821 | viocd_unitinfo, unitinfo_dmaaddr); | ||
| 822 | vio_clearHandler(viomajorsubtype_cdio); | 736 | vio_clearHandler(viomajorsubtype_cdio); |
| 823 | viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2); | 737 | viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2); |
| 824 | out_unregister: | 738 | out_unregister: |
| @@ -830,10 +744,6 @@ static void __exit viocd_exit(void) | |||
| 830 | { | 744 | { |
| 831 | remove_proc_entry("iSeries/viocd", NULL); | 745 | remove_proc_entry("iSeries/viocd", NULL); |
| 832 | vio_unregister_driver(&viocd_driver); | 746 | vio_unregister_driver(&viocd_driver); |
| 833 | if (viocd_unitinfo != NULL) | ||
| 834 | dma_free_coherent(iSeries_vio_dev, | ||
| 835 | sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, | ||
| 836 | viocd_unitinfo, unitinfo_dmaaddr); | ||
| 837 | viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2); | 747 | viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2); |
| 838 | vio_clearHandler(viomajorsubtype_cdio); | 748 | vio_clearHandler(viomajorsubtype_cdio); |
| 839 | unregister_blkdev(VIOCD_MAJOR, VIOCD_DEVICE); | 749 | unregister_blkdev(VIOCD_MAJOR, VIOCD_DEVICE); |
diff --git a/drivers/char/hvc_beat.c b/drivers/char/hvc_beat.c index 6f019f19be71..e74bb949c289 100644 --- a/drivers/char/hvc_beat.c +++ b/drivers/char/hvc_beat.c | |||
| @@ -97,7 +97,7 @@ static int hvc_beat_config(char *p) | |||
| 97 | return 0; | 97 | return 0; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static int hvc_beat_console_init(void) | 100 | static int __init hvc_beat_console_init(void) |
| 101 | { | 101 | { |
| 102 | if (hvc_beat_useit && machine_is_compatible("Beat")) { | 102 | if (hvc_beat_useit && machine_is_compatible("Beat")) { |
| 103 | hvc_instantiate(0, 0, &hvc_beat_get_put_ops); | 103 | hvc_instantiate(0, 0, &hvc_beat_get_put_ops); |
| @@ -106,7 +106,7 @@ static int hvc_beat_console_init(void) | |||
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | /* temp */ | 108 | /* temp */ |
| 109 | static int hvc_beat_init(void) | 109 | static int __init hvc_beat_init(void) |
| 110 | { | 110 | { |
| 111 | struct hvc_struct *hp; | 111 | struct hvc_struct *hp; |
| 112 | 112 | ||
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 7901d5f218ec..a2894d425153 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
| @@ -2253,19 +2253,19 @@ static int __devinit ipmi_of_probe(struct of_device *dev, | |||
| 2253 | return ret; | 2253 | return ret; |
| 2254 | } | 2254 | } |
| 2255 | 2255 | ||
| 2256 | regsize = get_property(np, "reg-size", &proplen); | 2256 | regsize = of_get_property(np, "reg-size", &proplen); |
| 2257 | if (regsize && proplen != 4) { | 2257 | if (regsize && proplen != 4) { |
| 2258 | dev_warn(&dev->dev, PFX "invalid regsize from OF\n"); | 2258 | dev_warn(&dev->dev, PFX "invalid regsize from OF\n"); |
| 2259 | return -EINVAL; | 2259 | return -EINVAL; |
| 2260 | } | 2260 | } |
| 2261 | 2261 | ||
| 2262 | regspacing = get_property(np, "reg-spacing", &proplen); | 2262 | regspacing = of_get_property(np, "reg-spacing", &proplen); |
| 2263 | if (regspacing && proplen != 4) { | 2263 | if (regspacing && proplen != 4) { |
| 2264 | dev_warn(&dev->dev, PFX "invalid regspacing from OF\n"); | 2264 | dev_warn(&dev->dev, PFX "invalid regspacing from OF\n"); |
| 2265 | return -EINVAL; | 2265 | return -EINVAL; |
| 2266 | } | 2266 | } |
| 2267 | 2267 | ||
| 2268 | regshift = get_property(np, "reg-shift", &proplen); | 2268 | regshift = of_get_property(np, "reg-shift", &proplen); |
| 2269 | if (regshift && proplen != 4) { | 2269 | if (regshift && proplen != 4) { |
| 2270 | dev_warn(&dev->dev, PFX "invalid regshift from OF\n"); | 2270 | dev_warn(&dev->dev, PFX "invalid regshift from OF\n"); |
| 2271 | return -EINVAL; | 2271 | return -EINVAL; |
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index e12275df6ea2..f1d60f0cef8f 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
| @@ -92,47 +92,6 @@ struct viot_devinfo_struct { | |||
| 92 | #define VIOTAPOP_SETPART 14 | 92 | #define VIOTAPOP_SETPART 14 |
| 93 | #define VIOTAPOP_UNLOAD 15 | 93 | #define VIOTAPOP_UNLOAD 15 |
| 94 | 94 | ||
| 95 | struct viotapelpevent { | ||
| 96 | struct HvLpEvent event; | ||
| 97 | u32 reserved; | ||
| 98 | u16 version; | ||
| 99 | u16 sub_type_result; | ||
| 100 | u16 tape; | ||
| 101 | u16 flags; | ||
| 102 | u32 token; | ||
| 103 | u64 len; | ||
| 104 | union { | ||
| 105 | struct { | ||
| 106 | u32 tape_op; | ||
| 107 | u32 count; | ||
| 108 | } op; | ||
| 109 | struct { | ||
| 110 | u32 type; | ||
| 111 | u32 resid; | ||
| 112 | u32 dsreg; | ||
| 113 | u32 gstat; | ||
| 114 | u32 erreg; | ||
| 115 | u32 file_no; | ||
| 116 | u32 block_no; | ||
| 117 | } get_status; | ||
| 118 | struct { | ||
| 119 | u32 block_no; | ||
| 120 | } get_pos; | ||
| 121 | } u; | ||
| 122 | }; | ||
| 123 | |||
| 124 | enum viotapesubtype { | ||
| 125 | viotapeopen = 0x0001, | ||
| 126 | viotapeclose = 0x0002, | ||
| 127 | viotaperead = 0x0003, | ||
| 128 | viotapewrite = 0x0004, | ||
| 129 | viotapegetinfo = 0x0005, | ||
| 130 | viotapeop = 0x0006, | ||
| 131 | viotapegetpos = 0x0007, | ||
| 132 | viotapesetpos = 0x0008, | ||
| 133 | viotapegetstatus = 0x0009 | ||
| 134 | }; | ||
| 135 | |||
| 136 | enum viotaperc { | 95 | enum viotaperc { |
| 137 | viotape_InvalidRange = 0x0601, | 96 | viotape_InvalidRange = 0x0601, |
| 138 | viotape_InvalidToken = 0x0602, | 97 | viotape_InvalidToken = 0x0602, |
| @@ -223,14 +182,11 @@ static const struct vio_error_entry viotape_err_table[] = { | |||
| 223 | #define VIOT_WRITING 2 | 182 | #define VIOT_WRITING 2 |
| 224 | 183 | ||
| 225 | /* Our info on the tapes */ | 184 | /* Our info on the tapes */ |
| 226 | struct tape_descr { | 185 | static struct { |
| 227 | char rsrcname[10]; | 186 | const char *rsrcname; |
| 228 | char type[4]; | 187 | const char *type; |
| 229 | char model[3]; | 188 | const char *model; |
| 230 | }; | 189 | } viotape_unitinfo[VIOTAPE_MAX_TAPE]; |
| 231 | |||
| 232 | static struct tape_descr *viotape_unitinfo; | ||
| 233 | static dma_addr_t viotape_unitinfo_token; | ||
| 234 | 190 | ||
| 235 | static struct mtget viomtget[VIOTAPE_MAX_TAPE]; | 191 | static struct mtget viomtget[VIOTAPE_MAX_TAPE]; |
| 236 | 192 | ||
| @@ -381,53 +337,6 @@ int tape_rc_to_errno(int tape_rc, char *operation, int tapeno) | |||
| 381 | return -err->errno; | 337 | return -err->errno; |
| 382 | } | 338 | } |
| 383 | 339 | ||
| 384 | /* Get info on all tapes from OS/400 */ | ||
| 385 | static int get_viotape_info(void) | ||
| 386 | { | ||
| 387 | HvLpEvent_Rc hvrc; | ||
| 388 | int i; | ||
| 389 | size_t len = sizeof(*viotape_unitinfo) * VIOTAPE_MAX_TAPE; | ||
| 390 | struct op_struct *op = get_op_struct(); | ||
| 391 | |||
| 392 | if (op == NULL) | ||
| 393 | return -ENOMEM; | ||
| 394 | |||
| 395 | viotape_unitinfo = dma_alloc_coherent(iSeries_vio_dev, len, | ||
| 396 | &viotape_unitinfo_token, GFP_ATOMIC); | ||
| 397 | if (viotape_unitinfo == NULL) { | ||
| 398 | free_op_struct(op); | ||
| 399 | return -ENOMEM; | ||
| 400 | } | ||
| 401 | |||
| 402 | memset(viotape_unitinfo, 0, len); | ||
| 403 | |||
| 404 | hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, | ||
| 405 | HvLpEvent_Type_VirtualIo, | ||
| 406 | viomajorsubtype_tape | viotapegetinfo, | ||
| 407 | HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, | ||
| 408 | viopath_sourceinst(viopath_hostLp), | ||
| 409 | viopath_targetinst(viopath_hostLp), | ||
| 410 | (u64) (unsigned long) op, VIOVERSION << 16, | ||
| 411 | viotape_unitinfo_token, len, 0, 0); | ||
| 412 | if (hvrc != HvLpEvent_Rc_Good) { | ||
| 413 | printk(VIOTAPE_KERN_WARN "hv error on op %d\n", | ||
| 414 | (int)hvrc); | ||
| 415 | free_op_struct(op); | ||
| 416 | return -EIO; | ||
| 417 | } | ||
| 418 | |||
| 419 | wait_for_completion(&op->com); | ||
| 420 | |||
| 421 | free_op_struct(op); | ||
| 422 | |||
| 423 | for (i = 0; | ||
| 424 | ((i < VIOTAPE_MAX_TAPE) && (viotape_unitinfo[i].rsrcname[0])); | ||
| 425 | i++) | ||
| 426 | viotape_numdev++; | ||
| 427 | return 0; | ||
| 428 | } | ||
| 429 | |||
| 430 | |||
| 431 | /* Write */ | 340 | /* Write */ |
| 432 | static ssize_t viotap_write(struct file *file, const char *buf, | 341 | static ssize_t viotap_write(struct file *file, const char *buf, |
| 433 | size_t count, loff_t * ppos) | 342 | size_t count, loff_t * ppos) |
| @@ -899,7 +808,6 @@ static void vioHandleTapeEvent(struct HvLpEvent *event) | |||
| 899 | tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK; | 808 | tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK; |
| 900 | op = (struct op_struct *)event->xCorrelationToken; | 809 | op = (struct op_struct *)event->xCorrelationToken; |
| 901 | switch (tapeminor) { | 810 | switch (tapeminor) { |
| 902 | case viotapegetinfo: | ||
| 903 | case viotapeopen: | 811 | case viotapeopen: |
| 904 | case viotapeclose: | 812 | case viotapeclose: |
| 905 | op->rc = tevent->sub_type_result; | 813 | op->rc = tevent->sub_type_result; |
| @@ -942,11 +850,23 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
| 942 | { | 850 | { |
| 943 | int i = vdev->unit_address; | 851 | int i = vdev->unit_address; |
| 944 | int j; | 852 | int j; |
| 853 | struct device_node *node = vdev->dev.archdata.of_node; | ||
| 945 | 854 | ||
| 946 | if (i >= viotape_numdev) | 855 | if (i > VIOTAPE_MAX_TAPE) |
| 856 | return -ENODEV; | ||
| 857 | if (!node) | ||
| 947 | return -ENODEV; | 858 | return -ENODEV; |
| 948 | 859 | ||
| 860 | if (i >= viotape_numdev) | ||
| 861 | viotape_numdev = i + 1; | ||
| 862 | |||
| 949 | tape_device[i] = &vdev->dev; | 863 | tape_device[i] = &vdev->dev; |
| 864 | viotape_unitinfo[i].rsrcname = of_get_property(node, | ||
| 865 | "linux,vio_rsrcname", NULL); | ||
| 866 | viotape_unitinfo[i].type = of_get_property(node, "linux,vio_type", | ||
| 867 | NULL); | ||
| 868 | viotape_unitinfo[i].model = of_get_property(node, "linux,vio_model", | ||
| 869 | NULL); | ||
| 950 | 870 | ||
| 951 | state[i].cur_part = 0; | 871 | state[i].cur_part = 0; |
| 952 | for (j = 0; j < MAX_PARTITIONS; ++j) | 872 | for (j = 0; j < MAX_PARTITIONS; ++j) |
| @@ -1044,11 +964,6 @@ int __init viotap_init(void) | |||
| 1044 | goto unreg_chrdev; | 964 | goto unreg_chrdev; |
| 1045 | } | 965 | } |
| 1046 | 966 | ||
| 1047 | if ((ret = get_viotape_info()) < 0) { | ||
| 1048 | printk(VIOTAPE_KERN_WARN "Unable to obtain virtual device information"); | ||
| 1049 | goto unreg_class; | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | ret = vio_register_driver(&viotape_driver); | 967 | ret = vio_register_driver(&viotape_driver); |
| 1053 | if (ret) | 968 | if (ret) |
| 1054 | goto unreg_class; | 969 | goto unreg_class; |
| @@ -1102,10 +1017,6 @@ static void __exit viotap_exit(void) | |||
| 1102 | vio_unregister_driver(&viotape_driver); | 1017 | vio_unregister_driver(&viotape_driver); |
| 1103 | class_destroy(tape_class); | 1018 | class_destroy(tape_class); |
| 1104 | unregister_chrdev(VIOTAPE_MAJOR, "viotape"); | 1019 | unregister_chrdev(VIOTAPE_MAJOR, "viotape"); |
| 1105 | if (viotape_unitinfo) | ||
| 1106 | dma_free_coherent(iSeries_vio_dev, | ||
| 1107 | sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE, | ||
| 1108 | viotape_unitinfo, viotape_unitinfo_token); | ||
| 1109 | viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2); | 1020 | viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2); |
| 1110 | vio_clearHandler(viomajorsubtype_tape); | 1021 | vio_clearHandler(viomajorsubtype_tape); |
| 1111 | clear_op_struct_pool(); | 1022 | clear_op_struct_pool(); |
diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c index 17ef5d3c01b4..444696625171 100644 --- a/drivers/macintosh/adb-iop.c +++ b/drivers/macintosh/adb-iop.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 20 | #include <linux/proc_fs.h> | 20 | #include <linux/proc_fs.h> |
| 21 | 21 | ||
| 22 | #include <asm/bootinfo.h> | ||
| 23 | #include <asm/macintosh.h> | 22 | #include <asm/macintosh.h> |
| 24 | #include <asm/macints.h> | 23 | #include <asm/macints.h> |
| 25 | #include <asm/mac_iop.h> | 24 | #include <asm/mac_iop.h> |
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index b46817f699f1..48d17bf6c927 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c | |||
| @@ -70,7 +70,7 @@ static struct notifier_block adbhid_adb_notifier = { | |||
| 70 | #define ADB_KEY_POWER_OLD 0x7e | 70 | #define ADB_KEY_POWER_OLD 0x7e |
| 71 | #define ADB_KEY_POWER 0x7f | 71 | #define ADB_KEY_POWER 0x7f |
| 72 | 72 | ||
| 73 | u8 adb_to_linux_keycodes[128] = { | 73 | u16 adb_to_linux_keycodes[128] = { |
| 74 | /* 0x00 */ KEY_A, /* 30 */ | 74 | /* 0x00 */ KEY_A, /* 30 */ |
| 75 | /* 0x01 */ KEY_S, /* 31 */ | 75 | /* 0x01 */ KEY_S, /* 31 */ |
| 76 | /* 0x02 */ KEY_D, /* 32 */ | 76 | /* 0x02 */ KEY_D, /* 32 */ |
| @@ -134,7 +134,7 @@ u8 adb_to_linux_keycodes[128] = { | |||
| 134 | /* 0x3c */ KEY_RIGHT, /* 106 */ | 134 | /* 0x3c */ KEY_RIGHT, /* 106 */ |
| 135 | /* 0x3d */ KEY_DOWN, /* 108 */ | 135 | /* 0x3d */ KEY_DOWN, /* 108 */ |
| 136 | /* 0x3e */ KEY_UP, /* 103 */ | 136 | /* 0x3e */ KEY_UP, /* 103 */ |
| 137 | /* 0x3f */ 0, | 137 | /* 0x3f */ KEY_FN, /* 0x1d0 */ |
| 138 | /* 0x40 */ 0, | 138 | /* 0x40 */ 0, |
| 139 | /* 0x41 */ KEY_KPDOT, /* 83 */ | 139 | /* 0x41 */ KEY_KPDOT, /* 83 */ |
| 140 | /* 0x42 */ 0, | 140 | /* 0x42 */ 0, |
| @@ -208,7 +208,7 @@ struct adbhid { | |||
| 208 | int original_handler_id; | 208 | int original_handler_id; |
| 209 | int current_handler_id; | 209 | int current_handler_id; |
| 210 | int mouse_kind; | 210 | int mouse_kind; |
| 211 | unsigned char *keycode; | 211 | u16 *keycode; |
| 212 | char name[64]; | 212 | char name[64]; |
| 213 | char phys[32]; | 213 | char phys[32]; |
| 214 | int flags; | 214 | int flags; |
| @@ -275,7 +275,7 @@ static void | |||
| 275 | adbhid_input_keycode(int id, int keycode, int repeat) | 275 | adbhid_input_keycode(int id, int keycode, int repeat) |
| 276 | { | 276 | { |
| 277 | struct adbhid *ahid = adbhid[id]; | 277 | struct adbhid *ahid = adbhid[id]; |
| 278 | int up_flag; | 278 | int up_flag, key; |
| 279 | 279 | ||
| 280 | up_flag = (keycode & 0x80); | 280 | up_flag = (keycode & 0x80); |
| 281 | keycode &= 0x7f; | 281 | keycode &= 0x7f; |
| @@ -321,8 +321,7 @@ adbhid_input_keycode(int id, int keycode, int repeat) | |||
| 321 | } | 321 | } |
| 322 | } else | 322 | } else |
| 323 | ahid->flags |= FLAG_FN_KEY_PRESSED; | 323 | ahid->flags |= FLAG_FN_KEY_PRESSED; |
| 324 | /* Swallow the key press */ | 324 | break; |
| 325 | return; | ||
| 326 | case ADB_KEY_DEL: | 325 | case ADB_KEY_DEL: |
| 327 | /* Emulate Fn+delete = forward delete */ | 326 | /* Emulate Fn+delete = forward delete */ |
| 328 | if (ahid->flags & FLAG_FN_KEY_PRESSED) { | 327 | if (ahid->flags & FLAG_FN_KEY_PRESSED) { |
| @@ -336,9 +335,9 @@ adbhid_input_keycode(int id, int keycode, int repeat) | |||
| 336 | #endif /* CONFIG_PPC_PMAC */ | 335 | #endif /* CONFIG_PPC_PMAC */ |
| 337 | } | 336 | } |
| 338 | 337 | ||
| 339 | if (adbhid[id]->keycode[keycode]) { | 338 | key = adbhid[id]->keycode[keycode]; |
| 340 | input_report_key(adbhid[id]->input, | 339 | if (key) { |
| 341 | adbhid[id]->keycode[keycode], !up_flag); | 340 | input_report_key(adbhid[id]->input, key, !up_flag); |
| 342 | input_sync(adbhid[id]->input); | 341 | input_sync(adbhid[id]->input); |
| 343 | } else | 342 | } else |
| 344 | printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode, | 343 | printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode, |
| @@ -757,8 +756,8 @@ adbhid_input_register(int id, int default_id, int original_handler_id, | |||
| 757 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); | 756 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); |
| 758 | input_dev->ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML); | 757 | input_dev->ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML); |
| 759 | input_dev->event = adbhid_kbd_event; | 758 | input_dev->event = adbhid_kbd_event; |
| 760 | input_dev->keycodemax = 127; | 759 | input_dev->keycodemax = KEY_FN; |
| 761 | input_dev->keycodesize = 1; | 760 | input_dev->keycodesize = sizeof(hid->keycode[0]); |
| 762 | break; | 761 | break; |
| 763 | 762 | ||
| 764 | case ADB_MOUSE: | 763 | case ADB_MOUSE: |
diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c index e54c4d9f6365..73c50bc02095 100644 --- a/drivers/macintosh/ans-lcd.c +++ b/drivers/macintosh/ans-lcd.c | |||
| @@ -14,9 +14,10 @@ | |||
| 14 | #include <asm/uaccess.h> | 14 | #include <asm/uaccess.h> |
| 15 | #include <asm/sections.h> | 15 | #include <asm/sections.h> |
| 16 | #include <asm/prom.h> | 16 | #include <asm/prom.h> |
| 17 | #include <asm/ans-lcd.h> | ||
| 18 | #include <asm/io.h> | 17 | #include <asm/io.h> |
| 19 | 18 | ||
| 19 | #include "ans-lcd.h" | ||
| 20 | |||
| 20 | #define ANSLCD_ADDR 0xf301c000 | 21 | #define ANSLCD_ADDR 0xf301c000 |
| 21 | #define ANSLCD_CTRL_IX 0x00 | 22 | #define ANSLCD_CTRL_IX 0x00 |
| 22 | #define ANSLCD_DATA_IX 0x10 | 23 | #define ANSLCD_DATA_IX 0x10 |
diff --git a/drivers/macintosh/ans-lcd.h b/drivers/macintosh/ans-lcd.h new file mode 100644 index 000000000000..d795b9fd2db6 --- /dev/null +++ b/drivers/macintosh/ans-lcd.h | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | #ifndef _PPC_ANS_LCD_H | ||
| 2 | #define _PPC_ANS_LCD_H | ||
| 3 | |||
| 4 | #define ANSLCD_MINOR 156 | ||
| 5 | |||
| 6 | #define ANSLCD_CLEAR 0x01 | ||
| 7 | #define ANSLCD_SENDCTRL 0x02 | ||
| 8 | #define ANSLCD_SETSHORTDELAY 0x03 | ||
| 9 | #define ANSLCD_SETLONGDELAY 0x04 | ||
| 10 | |||
| 11 | #endif | ||
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index f25685b9b7cf..276945d51513 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
| @@ -379,13 +379,10 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | |||
| 379 | if (thermostat) | 379 | if (thermostat) |
| 380 | return 0; | 380 | return 0; |
| 381 | 381 | ||
| 382 | th = (struct thermostat *) | 382 | th = kzalloc(sizeof(struct thermostat), GFP_KERNEL); |
| 383 | kmalloc(sizeof(struct thermostat), GFP_KERNEL); | ||
| 384 | |||
| 385 | if (!th) | 383 | if (!th) |
| 386 | return -ENOMEM; | 384 | return -ENOMEM; |
| 387 | 385 | ||
| 388 | memset(th, 0, sizeof(*th)); | ||
| 389 | th->clt.addr = addr; | 386 | th->clt.addr = addr; |
| 390 | th->clt.adapter = adapter; | 387 | th->clt.adapter = adapter; |
| 391 | th->clt.driver = &thermostat_driver; | 388 | th->clt.driver = &thermostat_driver; |
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 04f3973e3874..f7c509b7a8ea 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
| @@ -410,7 +410,7 @@ static int __init via_pmu_start(void) | |||
| 410 | 410 | ||
| 411 | irq = irq_of_parse_and_map(vias, 0); | 411 | irq = irq_of_parse_and_map(vias, 0); |
| 412 | if (irq == NO_IRQ) { | 412 | if (irq == NO_IRQ) { |
| 413 | printk(KERN_ERR "via-pmu: can't map interruptn"); | 413 | printk(KERN_ERR "via-pmu: can't map interrupt\n"); |
| 414 | return -ENODEV; | 414 | return -ENODEV; |
| 415 | } | 415 | } |
| 416 | if (request_irq(irq, via_pmu_interrupt, 0, "VIA-PMU", (void *)0)) { | 416 | if (request_irq(irq, via_pmu_interrupt, 0, "VIA-PMU", (void *)0)) { |
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index 351982bcec1b..f449d775cdf4 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c | |||
| @@ -380,10 +380,12 @@ static int __init sat_sensors_init(void) | |||
| 380 | return i2c_add_driver(&wf_sat_driver); | 380 | return i2c_add_driver(&wf_sat_driver); |
| 381 | } | 381 | } |
| 382 | 382 | ||
| 383 | #if 0 /* uncomment when module_exit() below is uncommented */ | ||
| 383 | static void __exit sat_sensors_exit(void) | 384 | static void __exit sat_sensors_exit(void) |
| 384 | { | 385 | { |
| 385 | i2c_del_driver(&wf_sat_driver); | 386 | i2c_del_driver(&wf_sat_driver); |
| 386 | } | 387 | } |
| 388 | #endif | ||
| 387 | 389 | ||
| 388 | module_init(sat_sensors_init); | 390 | module_init(sat_sensors_init); |
| 389 | /*module_exit(sat_sensors_exit); Uncomment when cleanup is implemented */ | 391 | /*module_exit(sat_sensors_exit); Uncomment when cleanup is implemented */ |
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c index 276ba3c5143f..aa8ce7abe922 100644 --- a/drivers/misc/hdpuftrs/hdpu_cpustate.c +++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c | |||
| @@ -19,16 +19,41 @@ | |||
| 19 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
| 20 | #include <linux/miscdevice.h> | 20 | #include <linux/miscdevice.h> |
| 21 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
| 22 | #include <linux/hdpu_features.h> | ||
| 22 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 23 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
| 24 | #include <linux/hdpu_features.h> | 25 | #include <linux/seq_file.h> |
| 26 | #include <asm/io.h> | ||
| 25 | 27 | ||
| 26 | #define SKY_CPUSTATE_VERSION "1.1" | 28 | #define SKY_CPUSTATE_VERSION "1.1" |
| 27 | 29 | ||
| 28 | static int hdpu_cpustate_probe(struct platform_device *pdev); | 30 | static int hdpu_cpustate_probe(struct platform_device *pdev); |
| 29 | static int hdpu_cpustate_remove(struct platform_device *pdev); | 31 | static int hdpu_cpustate_remove(struct platform_device *pdev); |
| 30 | 32 | ||
| 31 | struct cpustate_t cpustate; | 33 | static unsigned char cpustate_get_state(void); |
| 34 | static int cpustate_proc_open(struct inode *inode, struct file *file); | ||
| 35 | static int cpustate_proc_read(struct seq_file *seq, void *offset); | ||
| 36 | |||
| 37 | static struct cpustate_t cpustate; | ||
| 38 | |||
| 39 | static const struct file_operations proc_cpustate = { | ||
| 40 | .open = cpustate_proc_open, | ||
| 41 | .read = seq_read, | ||
| 42 | .llseek = seq_lseek, | ||
| 43 | .release = single_release, | ||
| 44 | .owner = THIS_MODULE, | ||
| 45 | }; | ||
| 46 | |||
| 47 | static int cpustate_proc_open(struct inode *inode, struct file *file) | ||
| 48 | { | ||
| 49 | return single_open(file, cpustate_proc_read, NULL); | ||
| 50 | } | ||
| 51 | |||
| 52 | static int cpustate_proc_read(struct seq_file *seq, void *offset) | ||
| 53 | { | ||
| 54 | seq_printf(seq, "CPU State: %04x\n", cpustate_get_state()); | ||
| 55 | return 0; | ||
| 56 | } | ||
| 32 | 57 | ||
| 33 | static int cpustate_get_ref(int excl) | 58 | static int cpustate_get_ref(int excl) |
| 34 | { | 59 | { |
| @@ -66,13 +91,13 @@ static int cpustate_free_ref(void) | |||
| 66 | return 0; | 91 | return 0; |
| 67 | } | 92 | } |
| 68 | 93 | ||
| 69 | unsigned char cpustate_get_state(void) | 94 | static unsigned char cpustate_get_state(void) |
| 70 | { | 95 | { |
| 71 | 96 | ||
| 72 | return cpustate.cached_val; | 97 | return cpustate.cached_val; |
| 73 | } | 98 | } |
| 74 | 99 | ||
| 75 | void cpustate_set_state(unsigned char new_state) | 100 | static void cpustate_set_state(unsigned char new_state) |
| 76 | { | 101 | { |
| 77 | unsigned int state = (new_state << 21); | 102 | unsigned int state = (new_state << 21); |
| 78 | 103 | ||
| @@ -134,29 +159,6 @@ static int cpustate_release(struct inode *inode, struct file *file) | |||
| 134 | return cpustate_free_ref(); | 159 | return cpustate_free_ref(); |
| 135 | } | 160 | } |
| 136 | 161 | ||
| 137 | /* | ||
| 138 | * Info exported via "/proc/sky_cpustate". | ||
| 139 | */ | ||
| 140 | static int cpustate_read_proc(char *page, char **start, off_t off, | ||
| 141 | int count, int *eof, void *data) | ||
| 142 | { | ||
| 143 | char *p = page; | ||
| 144 | int len = 0; | ||
| 145 | |||
| 146 | p += sprintf(p, "CPU State: %04x\n", cpustate_get_state()); | ||
| 147 | len = p - page; | ||
| 148 | |||
| 149 | if (len <= off + count) | ||
| 150 | *eof = 1; | ||
| 151 | *start = page + off; | ||
| 152 | len -= off; | ||
| 153 | if (len > count) | ||
| 154 | len = count; | ||
| 155 | if (len < 0) | ||
| 156 | len = 0; | ||
| 157 | return len; | ||
| 158 | } | ||
| 159 | |||
| 160 | static struct platform_driver hdpu_cpustate_driver = { | 162 | static struct platform_driver hdpu_cpustate_driver = { |
| 161 | .probe = hdpu_cpustate_probe, | 163 | .probe = hdpu_cpustate_probe, |
| 162 | .remove = hdpu_cpustate_remove, | 164 | .remove = hdpu_cpustate_remove, |
| @@ -169,22 +171,18 @@ static struct platform_driver hdpu_cpustate_driver = { | |||
| 169 | * The various file operations we support. | 171 | * The various file operations we support. |
| 170 | */ | 172 | */ |
| 171 | static const struct file_operations cpustate_fops = { | 173 | static const struct file_operations cpustate_fops = { |
| 172 | owner:THIS_MODULE, | 174 | .owner = THIS_MODULE, |
| 173 | open:cpustate_open, | 175 | .open = cpustate_open, |
| 174 | release:cpustate_release, | 176 | .release = cpustate_release, |
| 175 | read:cpustate_read, | 177 | .read = cpustate_read, |
| 176 | write:cpustate_write, | 178 | .write = cpustate_write, |
| 177 | fasync:NULL, | 179 | .llseek = no_llseek, |
| 178 | poll:NULL, | ||
| 179 | ioctl:NULL, | ||
| 180 | llseek:no_llseek, | ||
| 181 | |||
| 182 | }; | 180 | }; |
| 183 | 181 | ||
| 184 | static struct miscdevice cpustate_dev = { | 182 | static struct miscdevice cpustate_dev = { |
| 185 | MISC_DYNAMIC_MINOR, | 183 | .minor = MISC_DYNAMIC_MINOR, |
| 186 | "sky_cpustate", | 184 | .name = "sky_cpustate", |
| 187 | &cpustate_fops | 185 | .fops = &cpustate_fops, |
| 188 | }; | 186 | }; |
| 189 | 187 | ||
| 190 | static int hdpu_cpustate_probe(struct platform_device *pdev) | 188 | static int hdpu_cpustate_probe(struct platform_device *pdev) |
| @@ -194,23 +192,31 @@ static int hdpu_cpustate_probe(struct platform_device *pdev) | |||
| 194 | int ret; | 192 | int ret; |
| 195 | 193 | ||
| 196 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 194 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 195 | if (!res) { | ||
| 196 | printk(KERN_ERR "sky_cpustate: " | ||
| 197 | "Invalid memory resource.\n"); | ||
| 198 | return -EINVAL; | ||
| 199 | } | ||
| 197 | cpustate.set_addr = (unsigned long *)res->start; | 200 | cpustate.set_addr = (unsigned long *)res->start; |
| 198 | cpustate.clr_addr = (unsigned long *)res->end - 1; | 201 | cpustate.clr_addr = (unsigned long *)res->end - 1; |
| 199 | 202 | ||
| 200 | ret = misc_register(&cpustate_dev); | 203 | ret = misc_register(&cpustate_dev); |
| 201 | if (ret) { | 204 | if (ret) { |
| 202 | printk(KERN_WARNING "sky_cpustate: Unable to register misc " | 205 | printk(KERN_WARNING "sky_cpustate: " |
| 203 | "device.\n"); | 206 | "Unable to register misc device.\n"); |
| 204 | cpustate.set_addr = NULL; | 207 | cpustate.set_addr = NULL; |
| 205 | cpustate.clr_addr = NULL; | 208 | cpustate.clr_addr = NULL; |
| 206 | return ret; | 209 | return ret; |
| 207 | } | 210 | } |
| 208 | 211 | ||
| 209 | proc_de = create_proc_read_entry("sky_cpustate", 0, 0, | 212 | proc_de = create_proc_entry("sky_cpustate", 0666, &proc_root); |
| 210 | cpustate_read_proc, NULL); | 213 | if (!proc_de) { |
| 211 | if (proc_de == NULL) | 214 | printk(KERN_WARNING "sky_cpustate: " |
| 212 | printk(KERN_WARNING "sky_cpustate: Unable to create proc " | 215 | "Unable to create proc entry\n"); |
| 213 | "dir entry\n"); | 216 | } else { |
| 217 | proc_de->proc_fops = &proc_cpustate; | ||
| 218 | proc_de->owner = THIS_MODULE; | ||
| 219 | } | ||
| 214 | 220 | ||
| 215 | printk(KERN_INFO "Sky CPU State Driver v" SKY_CPUSTATE_VERSION "\n"); | 221 | printk(KERN_INFO "Sky CPU State Driver v" SKY_CPUSTATE_VERSION "\n"); |
| 216 | return 0; | 222 | return 0; |
| @@ -218,21 +224,18 @@ static int hdpu_cpustate_probe(struct platform_device *pdev) | |||
| 218 | 224 | ||
| 219 | static int hdpu_cpustate_remove(struct platform_device *pdev) | 225 | static int hdpu_cpustate_remove(struct platform_device *pdev) |
| 220 | { | 226 | { |
| 221 | |||
| 222 | cpustate.set_addr = NULL; | 227 | cpustate.set_addr = NULL; |
| 223 | cpustate.clr_addr = NULL; | 228 | cpustate.clr_addr = NULL; |
| 224 | 229 | ||
| 225 | remove_proc_entry("sky_cpustate", NULL); | 230 | remove_proc_entry("sky_cpustate", NULL); |
| 226 | misc_deregister(&cpustate_dev); | 231 | misc_deregister(&cpustate_dev); |
| 227 | return 0; | ||
| 228 | 232 | ||
| 233 | return 0; | ||
| 229 | } | 234 | } |
| 230 | 235 | ||
| 231 | static int __init cpustate_init(void) | 236 | static int __init cpustate_init(void) |
| 232 | { | 237 | { |
| 233 | int rc; | 238 | return platform_driver_register(&hdpu_cpustate_driver); |
| 234 | rc = platform_driver_register(&hdpu_cpustate_driver); | ||
| 235 | return rc; | ||
| 236 | } | 239 | } |
| 237 | 240 | ||
| 238 | static void __exit cpustate_exit(void) | 241 | static void __exit cpustate_exit(void) |
diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c index 60c8b26f0678..2887b2147980 100644 --- a/drivers/misc/hdpuftrs/hdpu_nexus.c +++ b/drivers/misc/hdpuftrs/hdpu_nexus.c | |||
| @@ -18,17 +18,38 @@ | |||
| 18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| 19 | #include <linux/proc_fs.h> | 19 | #include <linux/proc_fs.h> |
| 20 | #include <linux/hdpu_features.h> | 20 | #include <linux/hdpu_features.h> |
| 21 | |||
| 22 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/seq_file.h> | ||
| 23 | #include <asm/io.h> | ||
| 23 | 24 | ||
| 24 | static int hdpu_nexus_probe(struct platform_device *pdev); | 25 | static int hdpu_nexus_probe(struct platform_device *pdev); |
| 25 | static int hdpu_nexus_remove(struct platform_device *pdev); | 26 | static int hdpu_nexus_remove(struct platform_device *pdev); |
| 27 | static int hdpu_slot_id_open(struct inode *inode, struct file *file); | ||
| 28 | static int hdpu_slot_id_read(struct seq_file *seq, void *offset); | ||
| 29 | static int hdpu_chassis_id_open(struct inode *inode, struct file *file); | ||
| 30 | static int hdpu_chassis_id_read(struct seq_file *seq, void *offset); | ||
| 26 | 31 | ||
| 27 | static struct proc_dir_entry *hdpu_slot_id; | 32 | static struct proc_dir_entry *hdpu_slot_id; |
| 28 | static struct proc_dir_entry *hdpu_chassis_id; | 33 | static struct proc_dir_entry *hdpu_chassis_id; |
| 29 | static int slot_id = -1; | 34 | static int slot_id = -1; |
| 30 | static int chassis_id = -1; | 35 | static int chassis_id = -1; |
| 31 | 36 | ||
| 37 | static const struct file_operations proc_slot_id = { | ||
| 38 | .open = hdpu_slot_id_open, | ||
| 39 | .read = seq_read, | ||
| 40 | .llseek = seq_lseek, | ||
| 41 | .release = single_release, | ||
| 42 | .owner = THIS_MODULE, | ||
| 43 | }; | ||
| 44 | |||
| 45 | static const struct file_operations proc_chassis_id = { | ||
| 46 | .open = hdpu_chassis_id_open, | ||
| 47 | .read = seq_read, | ||
| 48 | .llseek = seq_lseek, | ||
| 49 | .release = single_release, | ||
| 50 | .owner = THIS_MODULE, | ||
| 51 | }; | ||
| 52 | |||
| 32 | static struct platform_driver hdpu_nexus_driver = { | 53 | static struct platform_driver hdpu_nexus_driver = { |
| 33 | .probe = hdpu_nexus_probe, | 54 | .probe = hdpu_nexus_probe, |
| 34 | .remove = hdpu_nexus_remove, | 55 | .remove = hdpu_nexus_remove, |
| @@ -37,43 +58,67 @@ static struct platform_driver hdpu_nexus_driver = { | |||
| 37 | }, | 58 | }, |
| 38 | }; | 59 | }; |
| 39 | 60 | ||
| 40 | int hdpu_slot_id_read(char *buffer, char **buffer_location, off_t offset, | 61 | static int hdpu_slot_id_open(struct inode *inode, struct file *file) |
| 41 | int buffer_length, int *zero, void *ptr) | ||
| 42 | { | 62 | { |
| 63 | return single_open(file, hdpu_slot_id_read, NULL); | ||
| 64 | } | ||
| 43 | 65 | ||
| 44 | if (offset > 0) | 66 | static int hdpu_slot_id_read(struct seq_file *seq, void *offset) |
| 45 | return 0; | 67 | { |
| 46 | return sprintf(buffer, "%d\n", slot_id); | 68 | seq_printf(seq, "%d\n", slot_id); |
| 69 | return 0; | ||
| 47 | } | 70 | } |
| 48 | 71 | ||
| 49 | int hdpu_chassis_id_read(char *buffer, char **buffer_location, off_t offset, | 72 | static int hdpu_chassis_id_open(struct inode *inode, struct file *file) |
| 50 | int buffer_length, int *zero, void *ptr) | ||
| 51 | { | 73 | { |
| 74 | return single_open(file, hdpu_chassis_id_read, NULL); | ||
| 75 | } | ||
| 52 | 76 | ||
| 53 | if (offset > 0) | 77 | static int hdpu_chassis_id_read(struct seq_file *seq, void *offset) |
| 54 | return 0; | 78 | { |
| 55 | return sprintf(buffer, "%d\n", chassis_id); | 79 | seq_printf(seq, "%d\n", chassis_id); |
| 80 | return 0; | ||
| 56 | } | 81 | } |
| 57 | 82 | ||
| 58 | static int hdpu_nexus_probe(struct platform_device *pdev) | 83 | static int hdpu_nexus_probe(struct platform_device *pdev) |
| 59 | { | 84 | { |
| 60 | struct resource *res; | 85 | struct resource *res; |
| 86 | int *nexus_id_addr; | ||
| 61 | 87 | ||
| 62 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 88 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 63 | int *nexus_id_addr; | 89 | if (!res) { |
| 64 | nexus_id_addr = | 90 | printk(KERN_ERR "sky_nexus: " |
| 65 | ioremap(res->start, (unsigned long)(res->end - res->start)); | 91 | "Invalid memory resource.\n"); |
| 92 | return -EINVAL; | ||
| 93 | } | ||
| 94 | nexus_id_addr = ioremap(res->start, | ||
| 95 | (unsigned long)(res->end - res->start)); | ||
| 66 | if (nexus_id_addr) { | 96 | if (nexus_id_addr) { |
| 67 | slot_id = (*nexus_id_addr >> 8) & 0x1f; | 97 | slot_id = (*nexus_id_addr >> 8) & 0x1f; |
| 68 | chassis_id = *nexus_id_addr & 0xff; | 98 | chassis_id = *nexus_id_addr & 0xff; |
| 69 | iounmap(nexus_id_addr); | 99 | iounmap(nexus_id_addr); |
| 70 | } else | 100 | } else { |
| 71 | printk("Could not map slot id\n"); | 101 | printk(KERN_ERR "sky_nexus: Could not map slot id\n"); |
| 102 | } | ||
| 103 | |||
| 72 | hdpu_slot_id = create_proc_entry("sky_slot_id", 0666, &proc_root); | 104 | hdpu_slot_id = create_proc_entry("sky_slot_id", 0666, &proc_root); |
| 73 | hdpu_slot_id->read_proc = hdpu_slot_id_read; | 105 | if (!hdpu_slot_id) { |
| 106 | printk(KERN_WARNING "sky_nexus: " | ||
| 107 | "Unable to create proc dir entry: sky_slot_id\n"); | ||
| 108 | } else { | ||
| 109 | hdpu_slot_id->proc_fops = &proc_slot_id; | ||
| 110 | hdpu_slot_id->owner = THIS_MODULE; | ||
| 111 | } | ||
| 74 | 112 | ||
| 75 | hdpu_chassis_id = create_proc_entry("sky_chassis_id", 0666, &proc_root); | 113 | hdpu_chassis_id = create_proc_entry("sky_chassis_id", 0666, &proc_root); |
| 76 | hdpu_chassis_id->read_proc = hdpu_chassis_id_read; | 114 | if (!hdpu_chassis_id) { |
| 115 | printk(KERN_WARNING "sky_nexus: " | ||
| 116 | "Unable to create proc dir entry: sky_chassis_id\n"); | ||
| 117 | } else { | ||
| 118 | hdpu_chassis_id->proc_fops = &proc_chassis_id; | ||
| 119 | hdpu_chassis_id->owner = THIS_MODULE; | ||
| 120 | } | ||
| 121 | |||
| 77 | return 0; | 122 | return 0; |
| 78 | } | 123 | } |
| 79 | 124 | ||
| @@ -81,18 +126,19 @@ static int hdpu_nexus_remove(struct platform_device *pdev) | |||
| 81 | { | 126 | { |
| 82 | slot_id = -1; | 127 | slot_id = -1; |
| 83 | chassis_id = -1; | 128 | chassis_id = -1; |
| 129 | |||
| 84 | remove_proc_entry("sky_slot_id", &proc_root); | 130 | remove_proc_entry("sky_slot_id", &proc_root); |
| 85 | remove_proc_entry("sky_chassis_id", &proc_root); | 131 | remove_proc_entry("sky_chassis_id", &proc_root); |
| 132 | |||
| 86 | hdpu_slot_id = 0; | 133 | hdpu_slot_id = 0; |
| 87 | hdpu_chassis_id = 0; | 134 | hdpu_chassis_id = 0; |
| 135 | |||
| 88 | return 0; | 136 | return 0; |
| 89 | } | 137 | } |
| 90 | 138 | ||
| 91 | static int __init nexus_init(void) | 139 | static int __init nexus_init(void) |
| 92 | { | 140 | { |
| 93 | int rc; | 141 | return platform_driver_register(&hdpu_nexus_driver); |
| 94 | rc = platform_driver_register(&hdpu_nexus_driver); | ||
| 95 | return rc; | ||
| 96 | } | 142 | } |
| 97 | 143 | ||
| 98 | static void __exit nexus_exit(void) | 144 | static void __exit nexus_exit(void) |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index cc6c73442435..6cd132c75187 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
| @@ -362,7 +362,7 @@ config MTD_WALNUT | |||
| 362 | 362 | ||
| 363 | config MTD_EBONY | 363 | config MTD_EBONY |
| 364 | tristate "Flash devices mapped on IBM 440GP Ebony" | 364 | tristate "Flash devices mapped on IBM 440GP Ebony" |
| 365 | depends on MTD_JEDECPROBE && EBONY | 365 | depends on MTD_JEDECPROBE && EBONY && !PPC_MERGE |
| 366 | help | 366 | help |
| 367 | This enables access routines for the flash chips on the IBM 440GP | 367 | This enables access routines for the flash chips on the IBM 440GP |
| 368 | Ebony board. If you have one of these boards and would like to | 368 | Ebony board. If you have one of these boards and would like to |
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index bbb42c35b69b..cf75a566442e 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c | |||
| @@ -1,9 +1,12 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Normal mappings of chips in physical memory for OF devices | 2 | * Flash mappings described by the OF (or flattened) device tree |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2006 MontaVista Software Inc. | 4 | * Copyright (C) 2006 MontaVista Software Inc. |
| 5 | * Author: Vitaly Wool <vwool@ru.mvista.com> | 5 | * Author: Vitaly Wool <vwool@ru.mvista.com> |
| 6 | * | 6 | * |
| 7 | * Revised to handle newer style flash binding by: | ||
| 8 | * Copyright (C) 2007 David Gibson, IBM Corporation. | ||
| 9 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
| 8 | * under the terms of the GNU General Public License as published by the | 11 | * under the terms of the GNU General Public License as published by the |
| 9 | * Free Software Foundation; either version 2 of the License, or (at your | 12 | * Free Software Foundation; either version 2 of the License, or (at your |
| @@ -12,102 +15,157 @@ | |||
| 12 | 15 | ||
| 13 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 14 | #include <linux/types.h> | 17 | #include <linux/types.h> |
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 17 | #include <linux/slab.h> | ||
| 18 | #include <linux/device.h> | 19 | #include <linux/device.h> |
| 19 | #include <linux/mtd/mtd.h> | 20 | #include <linux/mtd/mtd.h> |
| 20 | #include <linux/mtd/map.h> | 21 | #include <linux/mtd/map.h> |
| 21 | #include <linux/mtd/partitions.h> | 22 | #include <linux/mtd/partitions.h> |
| 22 | #include <linux/mtd/physmap.h> | 23 | #include <linux/of.h> |
| 23 | #include <asm/io.h> | 24 | #include <linux/of_platform.h> |
| 24 | #include <asm/prom.h> | ||
| 25 | #include <asm/of_device.h> | ||
| 26 | #include <asm/of_platform.h> | ||
| 27 | 25 | ||
| 28 | struct physmap_flash_info { | 26 | struct of_flash { |
| 29 | struct mtd_info *mtd; | 27 | struct mtd_info *mtd; |
| 30 | struct map_info map; | 28 | struct map_info map; |
| 31 | struct resource *res; | 29 | struct resource *res; |
| 32 | #ifdef CONFIG_MTD_PARTITIONS | 30 | #ifdef CONFIG_MTD_PARTITIONS |
| 33 | int nr_parts; | ||
| 34 | struct mtd_partition *parts; | 31 | struct mtd_partition *parts; |
| 35 | #endif | 32 | #endif |
| 36 | }; | 33 | }; |
| 37 | 34 | ||
| 38 | static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL }; | ||
| 39 | #ifdef CONFIG_MTD_PARTITIONS | 35 | #ifdef CONFIG_MTD_PARTITIONS |
| 40 | static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; | 36 | #define OF_FLASH_PARTS(info) ((info)->parts) |
| 41 | #endif | ||
| 42 | 37 | ||
| 43 | #ifdef CONFIG_MTD_PARTITIONS | 38 | static int parse_obsolete_partitions(struct of_device *dev, |
| 44 | static int parse_flash_partitions(struct device_node *node, | 39 | struct of_flash *info, |
| 45 | struct mtd_partition **parts) | 40 | struct device_node *dp) |
| 46 | { | 41 | { |
| 47 | int i, plen, retval = -ENOMEM; | 42 | int i, plen, nr_parts; |
| 48 | const u32 *part; | 43 | const struct { |
| 49 | const char *name; | 44 | u32 offset, len; |
| 50 | 45 | } *part; | |
| 51 | part = of_get_property(node, "partitions", &plen); | 46 | const char *names; |
| 52 | if (part == NULL) | 47 | |
| 53 | goto err; | 48 | part = of_get_property(dp, "partitions", &plen); |
| 54 | 49 | if (!part) | |
| 55 | retval = plen / (2 * sizeof(u32)); | 50 | return 0; /* No partitions found */ |
| 56 | *parts = kzalloc(retval * sizeof(struct mtd_partition), GFP_KERNEL); | 51 | |
| 57 | if (*parts == NULL) { | 52 | dev_warn(&dev->dev, "Device tree uses obsolete partition map binding\n"); |
| 58 | printk(KERN_ERR "Can't allocate the flash partition data!\n"); | 53 | |
| 59 | goto err; | 54 | nr_parts = plen / sizeof(part[0]); |
| 60 | } | 55 | |
| 56 | info->parts = kzalloc(nr_parts * sizeof(*info->parts), GFP_KERNEL); | ||
| 57 | if (!info->parts) | ||
| 58 | return -ENOMEM; | ||
| 61 | 59 | ||
| 62 | name = of_get_property(node, "partition-names", &plen); | 60 | names = of_get_property(dp, "partition-names", &plen); |
| 63 | 61 | ||
| 64 | for (i = 0; i < retval; i++) { | 62 | for (i = 0; i < nr_parts; i++) { |
| 65 | (*parts)[i].offset = *part++; | 63 | info->parts[i].offset = part->offset; |
| 66 | (*parts)[i].size = *part & ~1; | 64 | info->parts[i].size = part->len & ~1; |
| 67 | if (*part++ & 1) /* bit 0 set signifies read only partition */ | 65 | if (part->len & 1) /* bit 0 set signifies read only partition */ |
| 68 | (*parts)[i].mask_flags = MTD_WRITEABLE; | 66 | info->parts[i].mask_flags = MTD_WRITEABLE; |
| 69 | 67 | ||
| 70 | if (name != NULL && plen > 0) { | 68 | if (names && (plen > 0)) { |
| 71 | int len = strlen(name) + 1; | 69 | int len = strlen(names) + 1; |
| 72 | 70 | ||
| 73 | (*parts)[i].name = (char *)name; | 71 | info->parts[i].name = (char *)names; |
| 74 | plen -= len; | 72 | plen -= len; |
| 75 | name += len; | 73 | names += len; |
| 76 | } else | 74 | } else { |
| 77 | (*parts)[i].name = "unnamed"; | 75 | info->parts[i].name = "unnamed"; |
| 76 | } | ||
| 77 | |||
| 78 | part++; | ||
| 78 | } | 79 | } |
| 79 | err: | 80 | |
| 80 | return retval; | 81 | return nr_parts; |
| 81 | } | 82 | } |
| 82 | #endif | ||
| 83 | 83 | ||
| 84 | static int of_physmap_remove(struct of_device *dev) | 84 | static int __devinit parse_partitions(struct of_flash *info, |
| 85 | struct of_device *dev) | ||
| 86 | { | ||
| 87 | const char *partname; | ||
| 88 | static const char *part_probe_types[] | ||
| 89 | = { "cmdlinepart", "RedBoot", NULL }; | ||
| 90 | struct device_node *dp = dev->node, *pp; | ||
| 91 | int nr_parts, i; | ||
| 92 | |||
| 93 | /* First look for RedBoot table or partitions on the command | ||
| 94 | * line, these take precedence over device tree information */ | ||
| 95 | nr_parts = parse_mtd_partitions(info->mtd, part_probe_types, | ||
| 96 | &info->parts, 0); | ||
| 97 | if (nr_parts > 0) { | ||
| 98 | add_mtd_partitions(info->mtd, info->parts, nr_parts); | ||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | |||
| 102 | /* First count the subnodes */ | ||
| 103 | nr_parts = 0; | ||
| 104 | for (pp = dp->child; pp; pp = pp->sibling) | ||
| 105 | nr_parts++; | ||
| 106 | |||
| 107 | if (nr_parts == 0) | ||
| 108 | return parse_obsolete_partitions(dev, info, dp); | ||
| 109 | |||
| 110 | info->parts = kzalloc(nr_parts * sizeof(*info->parts), | ||
| 111 | GFP_KERNEL); | ||
| 112 | if (!info->parts) | ||
| 113 | return -ENOMEM; | ||
| 114 | |||
| 115 | for (pp = dp->child, i = 0; pp; pp = pp->sibling, i++) { | ||
| 116 | const u32 *reg; | ||
| 117 | int len; | ||
| 118 | |||
| 119 | reg = of_get_property(pp, "reg", &len); | ||
| 120 | if (!reg || (len != 2*sizeof(u32))) { | ||
| 121 | dev_err(&dev->dev, "Invalid 'reg' on %s\n", | ||
| 122 | dp->full_name); | ||
| 123 | kfree(info->parts); | ||
| 124 | info->parts = NULL; | ||
| 125 | return -EINVAL; | ||
| 126 | } | ||
| 127 | info->parts[i].offset = reg[0]; | ||
| 128 | info->parts[i].size = reg[1]; | ||
| 129 | |||
| 130 | partname = of_get_property(pp, "label", &len); | ||
| 131 | if (!partname) | ||
| 132 | partname = of_get_property(pp, "name", &len); | ||
| 133 | info->parts[i].name = (char *)partname; | ||
| 134 | |||
| 135 | if (of_get_property(pp, "read-only", &len)) | ||
| 136 | info->parts[i].mask_flags = MTD_WRITEABLE; | ||
| 137 | } | ||
| 138 | |||
| 139 | return nr_parts; | ||
| 140 | } | ||
| 141 | #else /* MTD_PARTITIONS */ | ||
| 142 | #define OF_FLASH_PARTS(info) (0) | ||
| 143 | #define parse_partitions(info, dev) (0) | ||
| 144 | #endif /* MTD_PARTITIONS */ | ||
| 145 | |||
| 146 | static int of_flash_remove(struct of_device *dev) | ||
| 85 | { | 147 | { |
| 86 | struct physmap_flash_info *info; | 148 | struct of_flash *info; |
| 87 | 149 | ||
| 88 | info = dev_get_drvdata(&dev->dev); | 150 | info = dev_get_drvdata(&dev->dev); |
| 89 | if (info == NULL) | 151 | if (!info) |
| 90 | return 0; | 152 | return 0; |
| 91 | dev_set_drvdata(&dev->dev, NULL); | 153 | dev_set_drvdata(&dev->dev, NULL); |
| 92 | 154 | ||
| 93 | if (info->mtd != NULL) { | 155 | if (info->mtd) { |
| 94 | #ifdef CONFIG_MTD_PARTITIONS | 156 | if (OF_FLASH_PARTS(info)) { |
| 95 | if (info->nr_parts) { | ||
| 96 | del_mtd_partitions(info->mtd); | 157 | del_mtd_partitions(info->mtd); |
| 97 | kfree(info->parts); | 158 | kfree(OF_FLASH_PARTS(info)); |
| 98 | } else { | 159 | } else { |
| 99 | del_mtd_device(info->mtd); | 160 | del_mtd_device(info->mtd); |
| 100 | } | 161 | } |
| 101 | #else | ||
| 102 | del_mtd_device(info->mtd); | ||
| 103 | #endif | ||
| 104 | map_destroy(info->mtd); | 162 | map_destroy(info->mtd); |
| 105 | } | 163 | } |
| 106 | 164 | ||
| 107 | if (info->map.virt != NULL) | 165 | if (info->map.virt) |
| 108 | iounmap(info->map.virt); | 166 | iounmap(info->map.virt); |
| 109 | 167 | ||
| 110 | if (info->res != NULL) { | 168 | if (info->res) { |
| 111 | release_resource(info->res); | 169 | release_resource(info->res); |
| 112 | kfree(info->res); | 170 | kfree(info->res); |
| 113 | } | 171 | } |
| @@ -115,48 +173,79 @@ static int of_physmap_remove(struct of_device *dev) | |||
| 115 | return 0; | 173 | return 0; |
| 116 | } | 174 | } |
| 117 | 175 | ||
| 118 | static int __devinit of_physmap_probe(struct of_device *dev, const struct of_device_id *match) | 176 | /* Helper function to handle probing of the obsolete "direct-mapped" |
| 177 | * compatible binding, which has an extra "probe-type" property | ||
| 178 | * describing the type of flash probe necessary. */ | ||
| 179 | static struct mtd_info * __devinit obsolete_probe(struct of_device *dev, | ||
| 180 | struct map_info *map) | ||
| 119 | { | 181 | { |
| 120 | struct device_node *dp = dev->node; | 182 | struct device_node *dp = dev->node; |
| 121 | struct resource res; | ||
| 122 | struct physmap_flash_info *info; | ||
| 123 | const char **probe_type; | ||
| 124 | const char *of_probe; | 183 | const char *of_probe; |
| 184 | struct mtd_info *mtd; | ||
| 185 | static const char *rom_probe_types[] | ||
| 186 | = { "cfi_probe", "jedec_probe", "map_rom"}; | ||
| 187 | int i; | ||
| 188 | |||
| 189 | dev_warn(&dev->dev, "Device tree uses obsolete \"direct-mapped\" " | ||
| 190 | "flash binding\n"); | ||
| 191 | |||
| 192 | of_probe = of_get_property(dp, "probe-type", NULL); | ||
| 193 | if (!of_probe) { | ||
| 194 | for (i = 0; i < ARRAY_SIZE(rom_probe_types); i++) { | ||
| 195 | mtd = do_map_probe(rom_probe_types[i], map); | ||
| 196 | if (mtd) | ||
| 197 | return mtd; | ||
| 198 | } | ||
| 199 | return NULL; | ||
| 200 | } else if (strcmp(of_probe, "CFI") == 0) { | ||
| 201 | return do_map_probe("cfi_probe", map); | ||
| 202 | } else if (strcmp(of_probe, "JEDEC") == 0) { | ||
| 203 | return do_map_probe("jedec_probe", map); | ||
| 204 | } else { | ||
| 205 | if (strcmp(of_probe, "ROM") != 0) | ||
| 206 | dev_warn(&dev->dev, "obsolete_probe: don't know probe " | ||
| 207 | "type '%s', mapping as rom\n", of_probe); | ||
| 208 | return do_map_probe("mtd_rom", map); | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 212 | static int __devinit of_flash_probe(struct of_device *dev, | ||
| 213 | const struct of_device_id *match) | ||
| 214 | { | ||
| 215 | struct device_node *dp = dev->node; | ||
| 216 | struct resource res; | ||
| 217 | struct of_flash *info; | ||
| 218 | const char *probe_type = match->data; | ||
| 125 | const u32 *width; | 219 | const u32 *width; |
| 126 | int err; | 220 | int err; |
| 127 | 221 | ||
| 128 | 222 | err = -ENXIO; | |
| 129 | if (of_address_to_resource(dp, 0, &res)) { | 223 | if (of_address_to_resource(dp, 0, &res)) { |
| 130 | dev_err(&dev->dev, "Can't get the flash mapping!\n"); | 224 | dev_err(&dev->dev, "Can't get IO address from device tree\n"); |
| 131 | err = -EINVAL; | ||
| 132 | goto err_out; | 225 | goto err_out; |
| 133 | } | 226 | } |
| 134 | 227 | ||
| 135 | dev_dbg(&dev->dev, "physmap flash device: %.8llx at %.8llx\n", | 228 | dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n", |
| 136 | (unsigned long long)res.end - res.start + 1, | 229 | (unsigned long long)res.start, (unsigned long long)res.end); |
| 137 | (unsigned long long)res.start); | ||
| 138 | 230 | ||
| 139 | info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL); | 231 | err = -ENOMEM; |
| 140 | if (info == NULL) { | 232 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
| 141 | err = -ENOMEM; | 233 | if (!info) |
| 142 | goto err_out; | 234 | goto err_out; |
| 143 | } | ||
| 144 | memset(info, 0, sizeof(*info)); | 235 | memset(info, 0, sizeof(*info)); |
| 145 | 236 | ||
| 146 | dev_set_drvdata(&dev->dev, info); | 237 | dev_set_drvdata(&dev->dev, info); |
| 147 | 238 | ||
| 239 | err = -EBUSY; | ||
| 148 | info->res = request_mem_region(res.start, res.end - res.start + 1, | 240 | info->res = request_mem_region(res.start, res.end - res.start + 1, |
| 149 | dev->dev.bus_id); | 241 | dev->dev.bus_id); |
| 150 | if (info->res == NULL) { | 242 | if (!info->res) |
| 151 | dev_err(&dev->dev, "Could not reserve memory region\n"); | ||
| 152 | err = -ENOMEM; | ||
| 153 | goto err_out; | 243 | goto err_out; |
| 154 | } | ||
| 155 | 244 | ||
| 245 | err = -ENXIO; | ||
| 156 | width = of_get_property(dp, "bank-width", NULL); | 246 | width = of_get_property(dp, "bank-width", NULL); |
| 157 | if (width == NULL) { | 247 | if (!width) { |
| 158 | dev_err(&dev->dev, "Can't get the flash bank width!\n"); | 248 | dev_err(&dev->dev, "Can't get bank width from device tree\n"); |
| 159 | err = -EINVAL; | ||
| 160 | goto err_out; | 249 | goto err_out; |
| 161 | } | 250 | } |
| 162 | 251 | ||
| @@ -165,91 +254,87 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev | |||
| 165 | info->map.size = res.end - res.start + 1; | 254 | info->map.size = res.end - res.start + 1; |
| 166 | info->map.bankwidth = *width; | 255 | info->map.bankwidth = *width; |
| 167 | 256 | ||
| 257 | err = -ENOMEM; | ||
| 168 | info->map.virt = ioremap(info->map.phys, info->map.size); | 258 | info->map.virt = ioremap(info->map.phys, info->map.size); |
| 169 | if (info->map.virt == NULL) { | 259 | if (!info->map.virt) { |
| 170 | dev_err(&dev->dev, "Failed to ioremap flash region\n"); | 260 | dev_err(&dev->dev, "Failed to ioremap() flash region\n"); |
| 171 | err = EIO; | ||
| 172 | goto err_out; | 261 | goto err_out; |
| 173 | } | 262 | } |
| 174 | 263 | ||
| 175 | simple_map_init(&info->map); | 264 | simple_map_init(&info->map); |
| 176 | 265 | ||
| 177 | of_probe = of_get_property(dp, "probe-type", NULL); | 266 | if (probe_type) |
| 178 | if (of_probe == NULL) { | 267 | info->mtd = do_map_probe(probe_type, &info->map); |
| 179 | probe_type = rom_probe_types; | 268 | else |
| 180 | for (; info->mtd == NULL && *probe_type != NULL; probe_type++) | 269 | info->mtd = obsolete_probe(dev, &info->map); |
| 181 | info->mtd = do_map_probe(*probe_type, &info->map); | 270 | |
| 182 | } else if (!strcmp(of_probe, "CFI")) | 271 | err = -ENXIO; |
| 183 | info->mtd = do_map_probe("cfi_probe", &info->map); | 272 | if (!info->mtd) { |
| 184 | else if (!strcmp(of_probe, "JEDEC")) | 273 | dev_err(&dev->dev, "do_map_probe() failed\n"); |
| 185 | info->mtd = do_map_probe("jedec_probe", &info->map); | ||
| 186 | else { | ||
| 187 | if (strcmp(of_probe, "ROM")) | ||
| 188 | dev_dbg(&dev->dev, "map_probe: don't know probe type " | ||
| 189 | "'%s', mapping as rom\n", of_probe); | ||
| 190 | info->mtd = do_map_probe("mtd_rom", &info->map); | ||
| 191 | } | ||
| 192 | if (info->mtd == NULL) { | ||
| 193 | dev_err(&dev->dev, "map_probe failed\n"); | ||
| 194 | err = -ENXIO; | ||
| 195 | goto err_out; | 274 | goto err_out; |
| 196 | } | 275 | } |
| 197 | info->mtd->owner = THIS_MODULE; | 276 | info->mtd->owner = THIS_MODULE; |
| 198 | 277 | ||
| 199 | #ifdef CONFIG_MTD_PARTITIONS | 278 | err = parse_partitions(info, dev); |
| 200 | err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0); | 279 | if (err < 0) |
| 201 | if (err > 0) { | 280 | goto err_out; |
| 202 | add_mtd_partitions(info->mtd, info->parts, err); | 281 | |
| 203 | } else if ((err = parse_flash_partitions(dp, &info->parts)) > 0) { | 282 | if (err > 0) |
| 204 | dev_info(&dev->dev, "Using OF partition information\n"); | 283 | add_mtd_partitions(info->mtd, OF_FLASH_PARTS(info), err); |
| 205 | add_mtd_partitions(info->mtd, info->parts, err); | 284 | else |
| 206 | info->nr_parts = err; | 285 | add_mtd_device(info->mtd); |
| 207 | } else | ||
| 208 | #endif | ||
| 209 | 286 | ||
| 210 | add_mtd_device(info->mtd); | ||
| 211 | return 0; | 287 | return 0; |
| 212 | 288 | ||
| 213 | err_out: | 289 | err_out: |
| 214 | of_physmap_remove(dev); | 290 | of_flash_remove(dev); |
| 215 | return err; | 291 | return err; |
| 216 | |||
| 217 | return 0; | ||
| 218 | |||
| 219 | |||
| 220 | } | 292 | } |
| 221 | 293 | ||
| 222 | static struct of_device_id of_physmap_match[] = { | 294 | static struct of_device_id of_flash_match[] = { |
| 295 | { | ||
| 296 | .compatible = "cfi-flash", | ||
| 297 | .data = (void *)"cfi_probe", | ||
| 298 | }, | ||
| 299 | { | ||
| 300 | /* FIXME: JEDEC chips can't be safely and reliably | ||
| 301 | * probed, although the mtd code gets it right in | ||
| 302 | * practice most of the time. We should use the | ||
| 303 | * vendor and device ids specified by the binding to | ||
| 304 | * bypass the heuristic probe code, but the mtd layer | ||
| 305 | * provides, at present, no interface for doing so | ||
| 306 | * :(. */ | ||
| 307 | .compatible = "jedec-flash", | ||
| 308 | .data = (void *)"jedec_probe", | ||
| 309 | }, | ||
| 223 | { | 310 | { |
| 224 | .type = "rom", | 311 | .type = "rom", |
| 225 | .compatible = "direct-mapped" | 312 | .compatible = "direct-mapped" |
| 226 | }, | 313 | }, |
| 227 | { }, | 314 | { }, |
| 228 | }; | 315 | }; |
| 316 | MODULE_DEVICE_TABLE(of, of_flash_match); | ||
| 229 | 317 | ||
| 230 | MODULE_DEVICE_TABLE(of, of_physmap_match); | 318 | static struct of_platform_driver of_flash_driver = { |
| 231 | 319 | .name = "of-flash", | |
| 232 | 320 | .match_table = of_flash_match, | |
| 233 | static struct of_platform_driver of_physmap_flash_driver = { | 321 | .probe = of_flash_probe, |
| 234 | .name = "physmap-flash", | 322 | .remove = of_flash_remove, |
| 235 | .match_table = of_physmap_match, | ||
| 236 | .probe = of_physmap_probe, | ||
| 237 | .remove = of_physmap_remove, | ||
| 238 | }; | 323 | }; |
| 239 | 324 | ||
| 240 | static int __init of_physmap_init(void) | 325 | static int __init of_flash_init(void) |
| 241 | { | 326 | { |
| 242 | return of_register_platform_driver(&of_physmap_flash_driver); | 327 | return of_register_platform_driver(&of_flash_driver); |
| 243 | } | 328 | } |
| 244 | 329 | ||
| 245 | static void __exit of_physmap_exit(void) | 330 | static void __exit of_flash_exit(void) |
| 246 | { | 331 | { |
| 247 | of_unregister_platform_driver(&of_physmap_flash_driver); | 332 | of_unregister_platform_driver(&of_flash_driver); |
| 248 | } | 333 | } |
| 249 | 334 | ||
| 250 | module_init(of_physmap_init); | 335 | module_init(of_flash_init); |
| 251 | module_exit(of_physmap_exit); | 336 | module_exit(of_flash_exit); |
| 252 | 337 | ||
| 253 | MODULE_LICENSE("GPL"); | 338 | MODULE_LICENSE("GPL"); |
| 254 | MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>"); | 339 | MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>"); |
| 255 | MODULE_DESCRIPTION("Configurable MTD map driver for OF"); | 340 | MODULE_DESCRIPTION("Device tree based MTD map driver"); |
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 9667dac383f0..d00e7d41f6a5 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
| @@ -2919,7 +2919,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
| 2919 | test = in_be16(&ugeth->p_tx_glbl_pram->temoder); | 2919 | test = in_be16(&ugeth->p_tx_glbl_pram->temoder); |
| 2920 | 2920 | ||
| 2921 | /* Function code register value to be used later */ | 2921 | /* Function code register value to be used later */ |
| 2922 | function_code = QE_BMR_BYTE_ORDER_BO_MOT | UCC_FAST_FUNCTION_CODE_GBL; | 2922 | function_code = UCC_BMR_BO_BE | UCC_BMR_GBL; |
| 2923 | /* Required for QE */ | 2923 | /* Required for QE */ |
| 2924 | 2924 | ||
| 2925 | /* function code register */ | 2925 | /* function code register */ |
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index aaeb94877987..4fb95b3af948 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | 44 | ||
| 45 | struct ucc_geth { | 45 | struct ucc_geth { |
| 46 | struct ucc_fast uccf; | 46 | struct ucc_fast uccf; |
| 47 | u8 res0[0x100 - sizeof(struct ucc_fast)]; | ||
| 47 | 48 | ||
| 48 | u32 maccfg1; /* mac configuration reg. 1 */ | 49 | u32 maccfg1; /* mac configuration reg. 1 */ |
| 49 | u32 maccfg2; /* mac configuration reg. 2 */ | 50 | u32 maccfg2; /* mac configuration reg. 2 */ |
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c index 6c257b88ce51..df884f0ad8e5 100644 --- a/drivers/net/ucc_geth_mii.c +++ b/drivers/net/ucc_geth_mii.c | |||
| @@ -32,7 +32,6 @@ | |||
| 32 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
| 33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
| 34 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
| 35 | #include <asm/ocp.h> | ||
| 36 | #include <linux/crc32.h> | 35 | #include <linux/crc32.h> |
| 37 | #include <linux/mii.h> | 36 | #include <linux/mii.h> |
| 38 | #include <linux/phy.h> | 37 | #include <linux/phy.h> |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 81b52b7cca21..d6ae38e55d01 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
| @@ -986,6 +986,31 @@ config SERIAL_PMACZILOG | |||
| 986 | PowerMac machines. | 986 | PowerMac machines. |
| 987 | Say Y or M if you want to be able to these serial ports. | 987 | Say Y or M if you want to be able to these serial ports. |
| 988 | 988 | ||
| 989 | config SERIAL_PMACZILOG_TTYS | ||
| 990 | bool "Use ttySn device nodes for Zilog z85c30" | ||
| 991 | depends on SERIAL_PMACZILOG | ||
| 992 | help | ||
| 993 | The pmac_zilog driver for the z85C30 chip on many powermacs | ||
| 994 | historically used the device numbers for /dev/ttySn. The | ||
| 995 | 8250 serial port driver also uses these numbers, which means | ||
| 996 | the two drivers being unable to coexist; you could not use | ||
| 997 | both z85C30 and 8250 type ports at the same time. | ||
| 998 | |||
| 999 | If this option is not selected, the pmac_zilog driver will | ||
| 1000 | use the device numbers allocated for /dev/ttyPZn. This allows | ||
| 1001 | the pmac_zilog and 8250 drivers to co-exist, but may cause | ||
| 1002 | existing userspace setups to break. Programs that need to | ||
| 1003 | access the built-in serial ports on powermacs will need to | ||
| 1004 | be reconfigured to use /dev/ttyPZn instead of /dev/ttySn. | ||
| 1005 | |||
| 1006 | If you enable this option, any z85c30 ports in the system will | ||
| 1007 | be registered as ttyS0 onwards as in the past, and you will be | ||
| 1008 | unable to use the 8250 module for PCMCIA or other 16C550-style | ||
| 1009 | UARTs. | ||
| 1010 | |||
| 1011 | Say N unless you need the z85c30 ports on your powermac | ||
| 1012 | to appear as /dev/ttySn. | ||
| 1013 | |||
| 989 | config SERIAL_PMACZILOG_CONSOLE | 1014 | config SERIAL_PMACZILOG_CONSOLE |
| 990 | bool "Console on PowerMac z85c30 serial port" | 1015 | bool "Console on PowerMac z85c30 serial port" |
| 991 | depends on SERIAL_PMACZILOG=y | 1016 | depends on SERIAL_PMACZILOG=y |
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index a8f894c78194..32b9737759c4 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h | |||
| @@ -56,21 +56,21 @@ struct uart_cpm_port { | |||
| 56 | u16 rx_fifosize; | 56 | u16 rx_fifosize; |
| 57 | u16 tx_nrfifos; | 57 | u16 tx_nrfifos; |
| 58 | u16 tx_fifosize; | 58 | u16 tx_fifosize; |
| 59 | smc_t *smcp; | 59 | smc_t __iomem *smcp; |
| 60 | smc_uart_t *smcup; | 60 | smc_uart_t __iomem *smcup; |
| 61 | scc_t *sccp; | 61 | scc_t __iomem *sccp; |
| 62 | scc_uart_t *sccup; | 62 | scc_uart_t __iomem *sccup; |
| 63 | volatile cbd_t *rx_bd_base; | 63 | cbd_t __iomem *rx_bd_base; |
| 64 | volatile cbd_t *rx_cur; | 64 | cbd_t __iomem *rx_cur; |
| 65 | volatile cbd_t *tx_bd_base; | 65 | cbd_t __iomem *tx_bd_base; |
| 66 | volatile cbd_t *tx_cur; | 66 | cbd_t __iomem *tx_cur; |
| 67 | unsigned char *tx_buf; | 67 | unsigned char *tx_buf; |
| 68 | unsigned char *rx_buf; | 68 | unsigned char *rx_buf; |
| 69 | u32 flags; | 69 | u32 flags; |
| 70 | void (*set_lineif)(struct uart_cpm_port *); | 70 | void (*set_lineif)(struct uart_cpm_port *); |
| 71 | u8 brg; | 71 | u8 brg; |
| 72 | uint dp_addr; | 72 | uint dp_addr; |
| 73 | void *mem_addr; | 73 | void *mem_addr; |
| 74 | dma_addr_t dma_addr; | 74 | dma_addr_t dma_addr; |
| 75 | u32 mem_size; | 75 | u32 mem_size; |
| 76 | /* helpers */ | 76 | /* helpers */ |
| @@ -80,14 +80,18 @@ struct uart_cpm_port { | |||
| 80 | int is_portb; | 80 | int is_portb; |
| 81 | /* wait on close if needed */ | 81 | /* wait on close if needed */ |
| 82 | int wait_closing; | 82 | int wait_closing; |
| 83 | /* value to combine with opcode to form cpm command */ | ||
| 84 | u32 command; | ||
| 83 | }; | 85 | }; |
| 84 | 86 | ||
| 87 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
| 85 | extern int cpm_uart_port_map[UART_NR]; | 88 | extern int cpm_uart_port_map[UART_NR]; |
| 89 | #endif | ||
| 86 | extern int cpm_uart_nr; | 90 | extern int cpm_uart_nr; |
| 87 | extern struct uart_cpm_port cpm_uart_ports[UART_NR]; | 91 | extern struct uart_cpm_port cpm_uart_ports[UART_NR]; |
| 88 | 92 | ||
| 89 | /* these are located in their respective files */ | 93 | /* these are located in their respective files */ |
| 90 | void cpm_line_cr_cmd(int line, int cmd); | 94 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd); |
| 91 | int cpm_uart_init_portdesc(void); | 95 | int cpm_uart_init_portdesc(void); |
| 92 | int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con); | 96 | int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con); |
| 93 | void cpm_uart_freebuf(struct uart_cpm_port *pinfo); | 97 | void cpm_uart_freebuf(struct uart_cpm_port *pinfo); |
| @@ -102,34 +106,36 @@ void scc4_lineif(struct uart_cpm_port *pinfo); | |||
| 102 | /* | 106 | /* |
| 103 | virtual to phys transtalion | 107 | virtual to phys transtalion |
| 104 | */ | 108 | */ |
| 105 | static inline unsigned long cpu2cpm_addr(void* addr, struct uart_cpm_port *pinfo) | 109 | static inline unsigned long cpu2cpm_addr(void *addr, |
| 110 | struct uart_cpm_port *pinfo) | ||
| 106 | { | 111 | { |
| 107 | int offset; | 112 | int offset; |
| 108 | u32 val = (u32)addr; | 113 | u32 val = (u32)addr; |
| 114 | u32 mem = (u32)pinfo->mem_addr; | ||
| 109 | /* sane check */ | 115 | /* sane check */ |
| 110 | if (likely((val >= (u32)pinfo->mem_addr)) && | 116 | if (likely(val >= mem && val < mem + pinfo->mem_size)) { |
| 111 | (val<((u32)pinfo->mem_addr + pinfo->mem_size))) { | 117 | offset = val - mem; |
| 112 | offset = val - (u32)pinfo->mem_addr; | 118 | return pinfo->dma_addr + offset; |
| 113 | return pinfo->dma_addr+offset; | ||
| 114 | } | 119 | } |
| 115 | /* something nasty happened */ | 120 | /* something nasty happened */ |
| 116 | BUG(); | 121 | BUG(); |
| 117 | return 0; | 122 | return 0; |
| 118 | } | 123 | } |
| 119 | 124 | ||
| 120 | static inline void *cpm2cpu_addr(unsigned long addr, struct uart_cpm_port *pinfo) | 125 | static inline void *cpm2cpu_addr(unsigned long addr, |
| 126 | struct uart_cpm_port *pinfo) | ||
| 121 | { | 127 | { |
| 122 | int offset; | 128 | int offset; |
| 123 | u32 val = addr; | 129 | u32 val = addr; |
| 130 | u32 dma = (u32)pinfo->dma_addr; | ||
| 124 | /* sane check */ | 131 | /* sane check */ |
| 125 | if (likely((val >= pinfo->dma_addr) && | 132 | if (likely(val >= dma && val < dma + pinfo->mem_size)) { |
| 126 | (val<(pinfo->dma_addr + pinfo->mem_size)))) { | 133 | offset = val - dma; |
| 127 | offset = val - (u32)pinfo->dma_addr; | 134 | return pinfo->mem_addr + offset; |
| 128 | return (void*)(pinfo->mem_addr+offset); | ||
| 129 | } | 135 | } |
| 130 | /* something nasty happened */ | 136 | /* something nasty happened */ |
| 131 | BUG(); | 137 | BUG(); |
| 132 | return 0; | 138 | return NULL; |
| 133 | } | 139 | } |
| 134 | 140 | ||
| 135 | 141 | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index cefde58dbad2..b5e4478de0e3 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) | 10 | * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) |
| 11 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) | 11 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) |
| 12 | * | 12 | * |
| 13 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 13 | * Copyright (C) 2004, 2007 Freescale Semiconductor, Inc. |
| 14 | * (C) 2004 Intracom, S.A. | 14 | * (C) 2004 Intracom, S.A. |
| 15 | * (C) 2005-2006 MontaVista Software, Inc. | 15 | * (C) 2005-2006 MontaVista Software, Inc. |
| 16 | * Vitaly Bordug <vbordug@ru.mvista.com> | 16 | * Vitaly Bordug <vbordug@ru.mvista.com> |
| @@ -47,6 +47,11 @@ | |||
| 47 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
| 48 | #include <asm/delay.h> | 48 | #include <asm/delay.h> |
| 49 | #include <asm/fs_pd.h> | 49 | #include <asm/fs_pd.h> |
| 50 | #include <asm/udbg.h> | ||
| 51 | |||
| 52 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
| 53 | #include <linux/of_platform.h> | ||
| 54 | #endif | ||
| 50 | 55 | ||
| 51 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 56 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
| 52 | #define SUPPORT_SYSRQ | 57 | #define SUPPORT_SYSRQ |
| @@ -57,12 +62,6 @@ | |||
| 57 | 62 | ||
| 58 | #include "cpm_uart.h" | 63 | #include "cpm_uart.h" |
| 59 | 64 | ||
| 60 | /***********************************************************************/ | ||
| 61 | |||
| 62 | /* Track which ports are configured as uarts */ | ||
| 63 | int cpm_uart_port_map[UART_NR]; | ||
| 64 | /* How many ports did we config as uarts */ | ||
| 65 | int cpm_uart_nr = 0; | ||
| 66 | 65 | ||
| 67 | /**************************************************************/ | 66 | /**************************************************************/ |
| 68 | 67 | ||
| @@ -73,6 +72,11 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo); | |||
| 73 | 72 | ||
| 74 | /**************************************************************/ | 73 | /**************************************************************/ |
| 75 | 74 | ||
| 75 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
| 76 | /* Track which ports are configured as uarts */ | ||
| 77 | int cpm_uart_port_map[UART_NR]; | ||
| 78 | /* How many ports did we config as uarts */ | ||
| 79 | int cpm_uart_nr; | ||
| 76 | 80 | ||
| 77 | /* Place-holder for board-specific stuff */ | 81 | /* Place-holder for board-specific stuff */ |
| 78 | struct platform_device* __attribute__ ((weak)) __init | 82 | struct platform_device* __attribute__ ((weak)) __init |
| @@ -119,6 +123,7 @@ static int cpm_uart_id2nr(int id) | |||
| 119 | /* not found or invalid argument */ | 123 | /* not found or invalid argument */ |
| 120 | return -1; | 124 | return -1; |
| 121 | } | 125 | } |
| 126 | #endif | ||
| 122 | 127 | ||
| 123 | /* | 128 | /* |
| 124 | * Check, if transmit buffers are processed | 129 | * Check, if transmit buffers are processed |
| @@ -126,14 +131,14 @@ static int cpm_uart_id2nr(int id) | |||
| 126 | static unsigned int cpm_uart_tx_empty(struct uart_port *port) | 131 | static unsigned int cpm_uart_tx_empty(struct uart_port *port) |
| 127 | { | 132 | { |
| 128 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 133 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
| 129 | volatile cbd_t *bdp = pinfo->tx_bd_base; | 134 | cbd_t __iomem *bdp = pinfo->tx_bd_base; |
| 130 | int ret = 0; | 135 | int ret = 0; |
| 131 | 136 | ||
| 132 | while (1) { | 137 | while (1) { |
| 133 | if (bdp->cbd_sc & BD_SC_READY) | 138 | if (in_be16(&bdp->cbd_sc) & BD_SC_READY) |
| 134 | break; | 139 | break; |
| 135 | 140 | ||
| 136 | if (bdp->cbd_sc & BD_SC_WRAP) { | 141 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) { |
| 137 | ret = TIOCSER_TEMT; | 142 | ret = TIOCSER_TEMT; |
| 138 | break; | 143 | break; |
| 139 | } | 144 | } |
| @@ -162,15 +167,15 @@ static unsigned int cpm_uart_get_mctrl(struct uart_port *port) | |||
| 162 | static void cpm_uart_stop_tx(struct uart_port *port) | 167 | static void cpm_uart_stop_tx(struct uart_port *port) |
| 163 | { | 168 | { |
| 164 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 169 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
| 165 | volatile smc_t *smcp = pinfo->smcp; | 170 | smc_t __iomem *smcp = pinfo->smcp; |
| 166 | volatile scc_t *sccp = pinfo->sccp; | 171 | scc_t __iomem *sccp = pinfo->sccp; |
| 167 | 172 | ||
| 168 | pr_debug("CPM uart[%d]:stop tx\n", port->line); | 173 | pr_debug("CPM uart[%d]:stop tx\n", port->line); |
| 169 | 174 | ||
| 170 | if (IS_SMC(pinfo)) | 175 | if (IS_SMC(pinfo)) |
| 171 | smcp->smc_smcm &= ~SMCM_TX; | 176 | clrbits8(&smcp->smc_smcm, SMCM_TX); |
| 172 | else | 177 | else |
| 173 | sccp->scc_sccm &= ~UART_SCCM_TX; | 178 | clrbits16(&sccp->scc_sccm, UART_SCCM_TX); |
| 174 | } | 179 | } |
| 175 | 180 | ||
| 176 | /* | 181 | /* |
| @@ -179,24 +184,24 @@ static void cpm_uart_stop_tx(struct uart_port *port) | |||
| 179 | static void cpm_uart_start_tx(struct uart_port *port) | 184 | static void cpm_uart_start_tx(struct uart_port *port) |
| 180 | { | 185 | { |
| 181 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 186 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
| 182 | volatile smc_t *smcp = pinfo->smcp; | 187 | smc_t __iomem *smcp = pinfo->smcp; |
| 183 | volatile scc_t *sccp = pinfo->sccp; | 188 | scc_t __iomem *sccp = pinfo->sccp; |
| 184 | 189 | ||
| 185 | pr_debug("CPM uart[%d]:start tx\n", port->line); | 190 | pr_debug("CPM uart[%d]:start tx\n", port->line); |
| 186 | 191 | ||
| 187 | if (IS_SMC(pinfo)) { | 192 | if (IS_SMC(pinfo)) { |
| 188 | if (smcp->smc_smcm & SMCM_TX) | 193 | if (in_8(&smcp->smc_smcm) & SMCM_TX) |
| 189 | return; | 194 | return; |
| 190 | } else { | 195 | } else { |
| 191 | if (sccp->scc_sccm & UART_SCCM_TX) | 196 | if (in_be16(&sccp->scc_sccm) & UART_SCCM_TX) |
| 192 | return; | 197 | return; |
| 193 | } | 198 | } |
| 194 | 199 | ||
| 195 | if (cpm_uart_tx_pump(port) != 0) { | 200 | if (cpm_uart_tx_pump(port) != 0) { |
| 196 | if (IS_SMC(pinfo)) { | 201 | if (IS_SMC(pinfo)) { |
| 197 | smcp->smc_smcm |= SMCM_TX; | 202 | setbits8(&smcp->smc_smcm, SMCM_TX); |
| 198 | } else { | 203 | } else { |
| 199 | sccp->scc_sccm |= UART_SCCM_TX; | 204 | setbits16(&sccp->scc_sccm, UART_SCCM_TX); |
| 200 | } | 205 | } |
| 201 | } | 206 | } |
| 202 | } | 207 | } |
| @@ -207,15 +212,15 @@ static void cpm_uart_start_tx(struct uart_port *port) | |||
| 207 | static void cpm_uart_stop_rx(struct uart_port *port) | 212 | static void cpm_uart_stop_rx(struct uart_port *port) |
| 208 | { | 213 | { |
| 209 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 214 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
| 210 | volatile smc_t *smcp = pinfo->smcp; | 215 | smc_t __iomem *smcp = pinfo->smcp; |
| 211 | volatile scc_t *sccp = pinfo->sccp; | 216 | scc_t __iomem *sccp = pinfo->sccp; |
| 212 | 217 | ||
| 213 | pr_debug("CPM uart[%d]:stop rx\n", port->line); | 218 | pr_debug("CPM uart[%d]:stop rx\n", port->line); |
| 214 | 219 | ||
| 215 | if (IS_SMC(pinfo)) | 220 | if (IS_SMC(pinfo)) |
| 216 | smcp->smc_smcm &= ~SMCM_RX; | 221 | clrbits8(&smcp->smc_smcm, SMCM_RX); |
| 217 | else | 222 | else |
| 218 | sccp->scc_sccm &= ~UART_SCCM_RX; | 223 | clrbits16(&sccp->scc_sccm, UART_SCCM_RX); |
| 219 | } | 224 | } |
| 220 | 225 | ||
| 221 | /* | 226 | /* |
| @@ -232,15 +237,14 @@ static void cpm_uart_enable_ms(struct uart_port *port) | |||
| 232 | static void cpm_uart_break_ctl(struct uart_port *port, int break_state) | 237 | static void cpm_uart_break_ctl(struct uart_port *port, int break_state) |
| 233 | { | 238 | { |
| 234 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 239 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
| 235 | int line = pinfo - cpm_uart_ports; | ||
| 236 | 240 | ||
| 237 | pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line, | 241 | pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line, |
| 238 | break_state); | 242 | break_state); |
| 239 | 243 | ||
| 240 | if (break_state) | 244 | if (break_state) |
| 241 | cpm_line_cr_cmd(line, CPM_CR_STOP_TX); | 245 | cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); |
| 242 | else | 246 | else |
| 243 | cpm_line_cr_cmd(line, CPM_CR_RESTART_TX); | 247 | cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX); |
| 244 | } | 248 | } |
| 245 | 249 | ||
| 246 | /* | 250 | /* |
| @@ -259,10 +263,11 @@ static void cpm_uart_int_tx(struct uart_port *port) | |||
| 259 | static void cpm_uart_int_rx(struct uart_port *port) | 263 | static void cpm_uart_int_rx(struct uart_port *port) |
| 260 | { | 264 | { |
| 261 | int i; | 265 | int i; |
| 262 | unsigned char ch, *cp; | 266 | unsigned char ch; |
| 267 | u8 *cp; | ||
| 263 | struct tty_struct *tty = port->info->tty; | 268 | struct tty_struct *tty = port->info->tty; |
| 264 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 269 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
| 265 | volatile cbd_t *bdp; | 270 | cbd_t __iomem *bdp; |
| 266 | u16 status; | 271 | u16 status; |
| 267 | unsigned int flg; | 272 | unsigned int flg; |
| 268 | 273 | ||
| @@ -274,13 +279,13 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
| 274 | bdp = pinfo->rx_cur; | 279 | bdp = pinfo->rx_cur; |
| 275 | for (;;) { | 280 | for (;;) { |
| 276 | /* get status */ | 281 | /* get status */ |
| 277 | status = bdp->cbd_sc; | 282 | status = in_be16(&bdp->cbd_sc); |
| 278 | /* If this one is empty, return happy */ | 283 | /* If this one is empty, return happy */ |
| 279 | if (status & BD_SC_EMPTY) | 284 | if (status & BD_SC_EMPTY) |
| 280 | break; | 285 | break; |
| 281 | 286 | ||
| 282 | /* get number of characters, and check spce in flip-buffer */ | 287 | /* get number of characters, and check spce in flip-buffer */ |
| 283 | i = bdp->cbd_datlen; | 288 | i = in_be16(&bdp->cbd_datlen); |
| 284 | 289 | ||
| 285 | /* If we have not enough room in tty flip buffer, then we try | 290 | /* If we have not enough room in tty flip buffer, then we try |
| 286 | * later, which will be the next rx-interrupt or a timeout | 291 | * later, which will be the next rx-interrupt or a timeout |
| @@ -291,7 +296,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
| 291 | } | 296 | } |
| 292 | 297 | ||
| 293 | /* get pointer */ | 298 | /* get pointer */ |
| 294 | cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); | 299 | cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); |
| 295 | 300 | ||
| 296 | /* loop through the buffer */ | 301 | /* loop through the buffer */ |
| 297 | while (i-- > 0) { | 302 | while (i-- > 0) { |
| @@ -311,10 +316,11 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
| 311 | } /* End while (i--) */ | 316 | } /* End while (i--) */ |
| 312 | 317 | ||
| 313 | /* This BD is ready to be used again. Clear status. get next */ | 318 | /* This BD is ready to be used again. Clear status. get next */ |
| 314 | bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID); | 319 | clrbits16(&bdp->cbd_sc, BD_SC_BR | BD_SC_FR | BD_SC_PR | |
| 315 | bdp->cbd_sc |= BD_SC_EMPTY; | 320 | BD_SC_OV | BD_SC_ID); |
| 321 | setbits16(&bdp->cbd_sc, BD_SC_EMPTY); | ||
| 316 | 322 | ||
| 317 | if (bdp->cbd_sc & BD_SC_WRAP) | 323 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) |
| 318 | bdp = pinfo->rx_bd_base; | 324 | bdp = pinfo->rx_bd_base; |
| 319 | else | 325 | else |
| 320 | bdp++; | 326 | bdp++; |
| @@ -322,7 +328,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
| 322 | } /* End for (;;) */ | 328 | } /* End for (;;) */ |
| 323 | 329 | ||
| 324 | /* Write back buffer pointer */ | 330 | /* Write back buffer pointer */ |
| 325 | pinfo->rx_cur = (volatile cbd_t *) bdp; | 331 | pinfo->rx_cur = bdp; |
| 326 | 332 | ||
| 327 | /* activate BH processing */ | 333 | /* activate BH processing */ |
| 328 | tty_flip_buffer_push(tty); | 334 | tty_flip_buffer_push(tty); |
| @@ -376,14 +382,14 @@ static irqreturn_t cpm_uart_int(int irq, void *data) | |||
| 376 | u8 events; | 382 | u8 events; |
| 377 | struct uart_port *port = (struct uart_port *)data; | 383 | struct uart_port *port = (struct uart_port *)data; |
| 378 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 384 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
| 379 | volatile smc_t *smcp = pinfo->smcp; | 385 | smc_t __iomem *smcp = pinfo->smcp; |
| 380 | volatile scc_t *sccp = pinfo->sccp; | 386 | scc_t __iomem *sccp = pinfo->sccp; |
| 381 | 387 | ||
| 382 | pr_debug("CPM uart[%d]:IRQ\n", port->line); | 388 | pr_debug("CPM uart[%d]:IRQ\n", port->line); |
| 383 | 389 | ||
| 384 | if (IS_SMC(pinfo)) { | 390 | if (IS_SMC(pinfo)) { |
| 385 | events = smcp->smc_smce; | 391 | events = in_8(&smcp->smc_smce); |
| 386 | smcp->smc_smce = events; | 392 | out_8(&smcp->smc_smce, events); |
| 387 | if (events & SMCM_BRKE) | 393 | if (events & SMCM_BRKE) |
| 388 | uart_handle_break(port); | 394 | uart_handle_break(port); |
| 389 | if (events & SMCM_RX) | 395 | if (events & SMCM_RX) |
| @@ -391,8 +397,8 @@ static irqreturn_t cpm_uart_int(int irq, void *data) | |||
| 391 | if (events & SMCM_TX) | 397 | if (events & SMCM_TX) |
| 392 | cpm_uart_int_tx(port); | 398 | cpm_uart_int_tx(port); |
| 393 | } else { | 399 | } else { |
| 394 | events = sccp->scc_scce; | 400 | events = in_be16(&sccp->scc_scce); |
| 395 | sccp->scc_scce = events; | 401 | out_be16(&sccp->scc_scce, events); |
| 396 | if (events & UART_SCCM_BRKE) | 402 | if (events & UART_SCCM_BRKE) |
| 397 | uart_handle_break(port); | 403 | uart_handle_break(port); |
| 398 | if (events & UART_SCCM_RX) | 404 | if (events & UART_SCCM_RX) |
| @@ -407,7 +413,6 @@ static int cpm_uart_startup(struct uart_port *port) | |||
| 407 | { | 413 | { |
| 408 | int retval; | 414 | int retval; |
| 409 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 415 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
| 410 | int line = pinfo - cpm_uart_ports; | ||
| 411 | 416 | ||
| 412 | pr_debug("CPM uart[%d]:startup\n", port->line); | 417 | pr_debug("CPM uart[%d]:startup\n", port->line); |
| 413 | 418 | ||
| @@ -418,15 +423,15 @@ static int cpm_uart_startup(struct uart_port *port) | |||
| 418 | 423 | ||
| 419 | /* Startup rx-int */ | 424 | /* Startup rx-int */ |
| 420 | if (IS_SMC(pinfo)) { | 425 | if (IS_SMC(pinfo)) { |
| 421 | pinfo->smcp->smc_smcm |= SMCM_RX; | 426 | setbits8(&pinfo->smcp->smc_smcm, SMCM_RX); |
| 422 | pinfo->smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); | 427 | setbits16(&pinfo->smcp->smc_smcmr, (SMCMR_REN | SMCMR_TEN)); |
| 423 | } else { | 428 | } else { |
| 424 | pinfo->sccp->scc_sccm |= UART_SCCM_RX; | 429 | setbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); |
| 425 | pinfo->sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); | 430 | setbits32(&pinfo->sccp->scc_gsmrl, (SCC_GSMRL_ENR | SCC_GSMRL_ENT)); |
| 426 | } | 431 | } |
| 427 | 432 | ||
| 428 | if (!(pinfo->flags & FLAG_CONSOLE)) | 433 | if (!(pinfo->flags & FLAG_CONSOLE)) |
| 429 | cpm_line_cr_cmd(line,CPM_CR_INIT_TRX); | 434 | cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); |
| 430 | return 0; | 435 | return 0; |
| 431 | } | 436 | } |
| 432 | 437 | ||
| @@ -442,7 +447,6 @@ inline void cpm_uart_wait_until_send(struct uart_cpm_port *pinfo) | |||
| 442 | static void cpm_uart_shutdown(struct uart_port *port) | 447 | static void cpm_uart_shutdown(struct uart_port *port) |
| 443 | { | 448 | { |
| 444 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 449 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
| 445 | int line = pinfo - cpm_uart_ports; | ||
| 446 | 450 | ||
| 447 | pr_debug("CPM uart[%d]:shutdown\n", port->line); | 451 | pr_debug("CPM uart[%d]:shutdown\n", port->line); |
| 448 | 452 | ||
| @@ -462,20 +466,20 @@ static void cpm_uart_shutdown(struct uart_port *port) | |||
| 462 | 466 | ||
| 463 | /* Stop uarts */ | 467 | /* Stop uarts */ |
| 464 | if (IS_SMC(pinfo)) { | 468 | if (IS_SMC(pinfo)) { |
| 465 | volatile smc_t *smcp = pinfo->smcp; | 469 | smc_t __iomem *smcp = pinfo->smcp; |
| 466 | smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); | 470 | clrbits16(&smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); |
| 467 | smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); | 471 | clrbits8(&smcp->smc_smcm, SMCM_RX | SMCM_TX); |
| 468 | } else { | 472 | } else { |
| 469 | volatile scc_t *sccp = pinfo->sccp; | 473 | scc_t __iomem *sccp = pinfo->sccp; |
| 470 | sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | 474 | clrbits32(&sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); |
| 471 | sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); | 475 | clrbits16(&sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); |
| 472 | } | 476 | } |
| 473 | 477 | ||
| 474 | /* Shut them really down and reinit buffer descriptors */ | 478 | /* Shut them really down and reinit buffer descriptors */ |
| 475 | if (IS_SMC(pinfo)) | 479 | if (IS_SMC(pinfo)) |
| 476 | cpm_line_cr_cmd(line, CPM_CR_STOP_TX); | 480 | cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); |
| 477 | else | 481 | else |
| 478 | cpm_line_cr_cmd(line, CPM_CR_GRA_STOP_TX); | 482 | cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX); |
| 479 | 483 | ||
| 480 | cpm_uart_initbd(pinfo); | 484 | cpm_uart_initbd(pinfo); |
| 481 | } | 485 | } |
| @@ -490,8 +494,8 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
| 490 | u16 cval, scval, prev_mode; | 494 | u16 cval, scval, prev_mode; |
| 491 | int bits, sbits; | 495 | int bits, sbits; |
| 492 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 496 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
| 493 | volatile smc_t *smcp = pinfo->smcp; | 497 | smc_t __iomem *smcp = pinfo->smcp; |
| 494 | volatile scc_t *sccp = pinfo->sccp; | 498 | scc_t __iomem *sccp = pinfo->sccp; |
| 495 | 499 | ||
| 496 | pr_debug("CPM uart[%d]:set_termios\n", port->line); | 500 | pr_debug("CPM uart[%d]:set_termios\n", port->line); |
| 497 | 501 | ||
| @@ -586,16 +590,15 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
| 586 | * enables, because we want to put them back if they were | 590 | * enables, because we want to put them back if they were |
| 587 | * present. | 591 | * present. |
| 588 | */ | 592 | */ |
| 589 | prev_mode = smcp->smc_smcmr; | 593 | prev_mode = in_be16(&smcp->smc_smcmr); |
| 590 | smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART; | 594 | out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval | SMCMR_SM_UART); |
| 591 | smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN)); | 595 | setbits16(&smcp->smc_smcmr, (prev_mode & (SMCMR_REN | SMCMR_TEN))); |
| 592 | } else { | 596 | } else { |
| 593 | sccp->scc_psmr = (sbits << 12) | scval; | 597 | out_be16(&sccp->scc_psmr, (sbits << 12) | scval); |
| 594 | } | 598 | } |
| 595 | 599 | ||
| 596 | cpm_set_brg(pinfo->brg - 1, baud); | 600 | cpm_set_brg(pinfo->brg - 1, baud); |
| 597 | spin_unlock_irqrestore(&port->lock, flags); | 601 | spin_unlock_irqrestore(&port->lock, flags); |
| 598 | |||
| 599 | } | 602 | } |
| 600 | 603 | ||
| 601 | static const char *cpm_uart_type(struct uart_port *port) | 604 | static const char *cpm_uart_type(struct uart_port *port) |
| @@ -629,8 +632,8 @@ static int cpm_uart_verify_port(struct uart_port *port, | |||
| 629 | */ | 632 | */ |
| 630 | static int cpm_uart_tx_pump(struct uart_port *port) | 633 | static int cpm_uart_tx_pump(struct uart_port *port) |
| 631 | { | 634 | { |
| 632 | volatile cbd_t *bdp; | 635 | cbd_t __iomem *bdp; |
| 633 | unsigned char *p; | 636 | u8 *p; |
| 634 | int count; | 637 | int count; |
| 635 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 638 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
| 636 | struct circ_buf *xmit = &port->info->xmit; | 639 | struct circ_buf *xmit = &port->info->xmit; |
| @@ -640,13 +643,14 @@ static int cpm_uart_tx_pump(struct uart_port *port) | |||
| 640 | /* Pick next descriptor and fill from buffer */ | 643 | /* Pick next descriptor and fill from buffer */ |
| 641 | bdp = pinfo->tx_cur; | 644 | bdp = pinfo->tx_cur; |
| 642 | 645 | ||
| 643 | p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); | 646 | p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); |
| 644 | 647 | ||
| 645 | *p++ = port->x_char; | 648 | *p++ = port->x_char; |
| 646 | bdp->cbd_datlen = 1; | 649 | |
| 647 | bdp->cbd_sc |= BD_SC_READY; | 650 | out_be16(&bdp->cbd_datlen, 1); |
| 651 | setbits16(&bdp->cbd_sc, BD_SC_READY); | ||
| 648 | /* Get next BD. */ | 652 | /* Get next BD. */ |
| 649 | if (bdp->cbd_sc & BD_SC_WRAP) | 653 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) |
| 650 | bdp = pinfo->tx_bd_base; | 654 | bdp = pinfo->tx_bd_base; |
| 651 | else | 655 | else |
| 652 | bdp++; | 656 | bdp++; |
| @@ -665,9 +669,10 @@ static int cpm_uart_tx_pump(struct uart_port *port) | |||
| 665 | /* Pick next descriptor and fill from buffer */ | 669 | /* Pick next descriptor and fill from buffer */ |
| 666 | bdp = pinfo->tx_cur; | 670 | bdp = pinfo->tx_cur; |
| 667 | 671 | ||
| 668 | while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) { | 672 | while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) && |
| 673 | xmit->tail != xmit->head) { | ||
| 669 | count = 0; | 674 | count = 0; |
| 670 | p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); | 675 | p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); |
| 671 | while (count < pinfo->tx_fifosize) { | 676 | while (count < pinfo->tx_fifosize) { |
| 672 | *p++ = xmit->buf[xmit->tail]; | 677 | *p++ = xmit->buf[xmit->tail]; |
| 673 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 678 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
| @@ -676,11 +681,10 @@ static int cpm_uart_tx_pump(struct uart_port *port) | |||
| 676 | if (xmit->head == xmit->tail) | 681 | if (xmit->head == xmit->tail) |
| 677 | break; | 682 | break; |
| 678 | } | 683 | } |
| 679 | bdp->cbd_datlen = count; | 684 | out_be16(&bdp->cbd_datlen, count); |
| 680 | bdp->cbd_sc |= BD_SC_READY; | 685 | setbits16(&bdp->cbd_sc, BD_SC_READY); |
| 681 | eieio(); | ||
| 682 | /* Get next BD. */ | 686 | /* Get next BD. */ |
| 683 | if (bdp->cbd_sc & BD_SC_WRAP) | 687 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) |
| 684 | bdp = pinfo->tx_bd_base; | 688 | bdp = pinfo->tx_bd_base; |
| 685 | else | 689 | else |
| 686 | bdp++; | 690 | bdp++; |
| @@ -705,7 +709,7 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo) | |||
| 705 | { | 709 | { |
| 706 | int i; | 710 | int i; |
| 707 | u8 *mem_addr; | 711 | u8 *mem_addr; |
| 708 | volatile cbd_t *bdp; | 712 | cbd_t __iomem *bdp; |
| 709 | 713 | ||
| 710 | pr_debug("CPM uart[%d]:initbd\n", pinfo->port.line); | 714 | pr_debug("CPM uart[%d]:initbd\n", pinfo->port.line); |
| 711 | 715 | ||
| @@ -716,13 +720,13 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo) | |||
| 716 | mem_addr = pinfo->mem_addr; | 720 | mem_addr = pinfo->mem_addr; |
| 717 | bdp = pinfo->rx_cur = pinfo->rx_bd_base; | 721 | bdp = pinfo->rx_cur = pinfo->rx_bd_base; |
| 718 | for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { | 722 | for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { |
| 719 | bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo); | 723 | out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); |
| 720 | bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; | 724 | out_be16(&bdp->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT); |
| 721 | mem_addr += pinfo->rx_fifosize; | 725 | mem_addr += pinfo->rx_fifosize; |
| 722 | } | 726 | } |
| 723 | 727 | ||
| 724 | bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo); | 728 | out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); |
| 725 | bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; | 729 | out_be16(&bdp->cbd_sc, BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT); |
| 726 | 730 | ||
| 727 | /* Set the physical address of the host memory | 731 | /* Set the physical address of the host memory |
| 728 | * buffers in the buffer descriptors, and the | 732 | * buffers in the buffer descriptors, and the |
| @@ -731,20 +735,19 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo) | |||
| 731 | mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); | 735 | mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); |
| 732 | bdp = pinfo->tx_cur = pinfo->tx_bd_base; | 736 | bdp = pinfo->tx_cur = pinfo->tx_bd_base; |
| 733 | for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { | 737 | for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { |
| 734 | bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo); | 738 | out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); |
| 735 | bdp->cbd_sc = BD_SC_INTRPT; | 739 | out_be16(&bdp->cbd_sc, BD_SC_INTRPT); |
| 736 | mem_addr += pinfo->tx_fifosize; | 740 | mem_addr += pinfo->tx_fifosize; |
| 737 | } | 741 | } |
| 738 | 742 | ||
| 739 | bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo); | 743 | out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); |
| 740 | bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT; | 744 | out_be16(&bdp->cbd_sc, BD_SC_WRAP | BD_SC_INTRPT); |
| 741 | } | 745 | } |
| 742 | 746 | ||
| 743 | static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) | 747 | static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) |
| 744 | { | 748 | { |
| 745 | int line = pinfo - cpm_uart_ports; | 749 | scc_t __iomem *scp; |
| 746 | volatile scc_t *scp; | 750 | scc_uart_t __iomem *sup; |
| 747 | volatile scc_uart_t *sup; | ||
| 748 | 751 | ||
| 749 | pr_debug("CPM uart[%d]:init_scc\n", pinfo->port.line); | 752 | pr_debug("CPM uart[%d]:init_scc\n", pinfo->port.line); |
| 750 | 753 | ||
| @@ -752,8 +755,10 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) | |||
| 752 | sup = pinfo->sccup; | 755 | sup = pinfo->sccup; |
| 753 | 756 | ||
| 754 | /* Store address */ | 757 | /* Store address */ |
| 755 | pinfo->sccup->scc_genscc.scc_rbase = (unsigned char *)pinfo->rx_bd_base - DPRAM_BASE; | 758 | out_be16(&pinfo->sccup->scc_genscc.scc_rbase, |
| 756 | pinfo->sccup->scc_genscc.scc_tbase = (unsigned char *)pinfo->tx_bd_base - DPRAM_BASE; | 759 | (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE); |
| 760 | out_be16(&pinfo->sccup->scc_genscc.scc_tbase, | ||
| 761 | (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE); | ||
| 757 | 762 | ||
| 758 | /* Set up the uart parameters in the | 763 | /* Set up the uart parameters in the |
| 759 | * parameter ram. | 764 | * parameter ram. |
| @@ -761,51 +766,50 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) | |||
| 761 | 766 | ||
| 762 | cpm_set_scc_fcr(sup); | 767 | cpm_set_scc_fcr(sup); |
| 763 | 768 | ||
| 764 | sup->scc_genscc.scc_mrblr = pinfo->rx_fifosize; | 769 | out_be16(&sup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); |
| 765 | sup->scc_maxidl = pinfo->rx_fifosize; | 770 | out_be16(&sup->scc_maxidl, pinfo->rx_fifosize); |
| 766 | sup->scc_brkcr = 1; | 771 | out_be16(&sup->scc_brkcr, 1); |
| 767 | sup->scc_parec = 0; | 772 | out_be16(&sup->scc_parec, 0); |
| 768 | sup->scc_frmec = 0; | 773 | out_be16(&sup->scc_frmec, 0); |
| 769 | sup->scc_nosec = 0; | 774 | out_be16(&sup->scc_nosec, 0); |
| 770 | sup->scc_brkec = 0; | 775 | out_be16(&sup->scc_brkec, 0); |
| 771 | sup->scc_uaddr1 = 0; | 776 | out_be16(&sup->scc_uaddr1, 0); |
| 772 | sup->scc_uaddr2 = 0; | 777 | out_be16(&sup->scc_uaddr2, 0); |
| 773 | sup->scc_toseq = 0; | 778 | out_be16(&sup->scc_toseq, 0); |
| 774 | sup->scc_char1 = 0x8000; | 779 | out_be16(&sup->scc_char1, 0x8000); |
| 775 | sup->scc_char2 = 0x8000; | 780 | out_be16(&sup->scc_char2, 0x8000); |
| 776 | sup->scc_char3 = 0x8000; | 781 | out_be16(&sup->scc_char3, 0x8000); |
| 777 | sup->scc_char4 = 0x8000; | 782 | out_be16(&sup->scc_char4, 0x8000); |
| 778 | sup->scc_char5 = 0x8000; | 783 | out_be16(&sup->scc_char5, 0x8000); |
| 779 | sup->scc_char6 = 0x8000; | 784 | out_be16(&sup->scc_char6, 0x8000); |
| 780 | sup->scc_char7 = 0x8000; | 785 | out_be16(&sup->scc_char7, 0x8000); |
| 781 | sup->scc_char8 = 0x8000; | 786 | out_be16(&sup->scc_char8, 0x8000); |
| 782 | sup->scc_rccm = 0xc0ff; | 787 | out_be16(&sup->scc_rccm, 0xc0ff); |
| 783 | 788 | ||
| 784 | /* Send the CPM an initialize command. | 789 | /* Send the CPM an initialize command. |
| 785 | */ | 790 | */ |
| 786 | cpm_line_cr_cmd(line, CPM_CR_INIT_TRX); | 791 | cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); |
| 787 | 792 | ||
| 788 | /* Set UART mode, 8 bit, no parity, one stop. | 793 | /* Set UART mode, 8 bit, no parity, one stop. |
| 789 | * Enable receive and transmit. | 794 | * Enable receive and transmit. |
| 790 | */ | 795 | */ |
| 791 | scp->scc_gsmrh = 0; | 796 | out_be32(&scp->scc_gsmrh, 0); |
| 792 | scp->scc_gsmrl = | 797 | out_be32(&scp->scc_gsmrl, |
| 793 | (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); | 798 | SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); |
| 794 | 799 | ||
| 795 | /* Enable rx interrupts and clear all pending events. */ | 800 | /* Enable rx interrupts and clear all pending events. */ |
| 796 | scp->scc_sccm = 0; | 801 | out_be16(&scp->scc_sccm, 0); |
| 797 | scp->scc_scce = 0xffff; | 802 | out_be16(&scp->scc_scce, 0xffff); |
| 798 | scp->scc_dsr = 0x7e7e; | 803 | out_be16(&scp->scc_dsr, 0x7e7e); |
| 799 | scp->scc_psmr = 0x3000; | 804 | out_be16(&scp->scc_psmr, 0x3000); |
| 800 | 805 | ||
| 801 | scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); | 806 | setbits32(&scp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); |
| 802 | } | 807 | } |
| 803 | 808 | ||
| 804 | static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) | 809 | static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) |
| 805 | { | 810 | { |
| 806 | int line = pinfo - cpm_uart_ports; | 811 | smc_t __iomem *sp; |
| 807 | volatile smc_t *sp; | 812 | smc_uart_t __iomem *up; |
| 808 | volatile smc_uart_t *up; | ||
| 809 | 813 | ||
| 810 | pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line); | 814 | pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line); |
| 811 | 815 | ||
| @@ -813,19 +817,21 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) | |||
| 813 | up = pinfo->smcup; | 817 | up = pinfo->smcup; |
| 814 | 818 | ||
| 815 | /* Store address */ | 819 | /* Store address */ |
| 816 | pinfo->smcup->smc_rbase = (u_char *)pinfo->rx_bd_base - DPRAM_BASE; | 820 | out_be16(&pinfo->smcup->smc_rbase, |
| 817 | pinfo->smcup->smc_tbase = (u_char *)pinfo->tx_bd_base - DPRAM_BASE; | 821 | (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE); |
| 822 | out_be16(&pinfo->smcup->smc_tbase, | ||
| 823 | (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE); | ||
| 818 | 824 | ||
| 819 | /* | 825 | /* |
| 820 | * In case SMC1 is being relocated... | 826 | * In case SMC1 is being relocated... |
| 821 | */ | 827 | */ |
| 822 | #if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH) | 828 | #if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH) |
| 823 | up->smc_rbptr = pinfo->smcup->smc_rbase; | 829 | out_be16(&up->smc_rbptr, in_be16(&pinfo->smcup->smc_rbase)); |
| 824 | up->smc_tbptr = pinfo->smcup->smc_tbase; | 830 | out_be16(&up->smc_tbptr, in_be16(&pinfo->smcup->smc_tbase)); |
| 825 | up->smc_rstate = 0; | 831 | out_be32(&up->smc_rstate, 0); |
| 826 | up->smc_tstate = 0; | 832 | out_be32(&up->smc_tstate, 0); |
| 827 | up->smc_brkcr = 1; /* number of break chars */ | 833 | out_be16(&up->smc_brkcr, 1); /* number of break chars */ |
| 828 | up->smc_brkec = 0; | 834 | out_be16(&up->smc_brkec, 0); |
| 829 | #endif | 835 | #endif |
| 830 | 836 | ||
| 831 | /* Set up the uart parameters in the | 837 | /* Set up the uart parameters in the |
| @@ -834,24 +840,24 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) | |||
| 834 | cpm_set_smc_fcr(up); | 840 | cpm_set_smc_fcr(up); |
| 835 | 841 | ||
| 836 | /* Using idle charater time requires some additional tuning. */ | 842 | /* Using idle charater time requires some additional tuning. */ |
| 837 | up->smc_mrblr = pinfo->rx_fifosize; | 843 | out_be16(&up->smc_mrblr, pinfo->rx_fifosize); |
| 838 | up->smc_maxidl = pinfo->rx_fifosize; | 844 | out_be16(&up->smc_maxidl, pinfo->rx_fifosize); |
| 839 | up->smc_brklen = 0; | 845 | out_be16(&up->smc_brklen, 0); |
| 840 | up->smc_brkec = 0; | 846 | out_be16(&up->smc_brkec, 0); |
| 841 | up->smc_brkcr = 1; | 847 | out_be16(&up->smc_brkcr, 1); |
| 842 | 848 | ||
| 843 | cpm_line_cr_cmd(line, CPM_CR_INIT_TRX); | 849 | cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); |
| 844 | 850 | ||
| 845 | /* Set UART mode, 8 bit, no parity, one stop. | 851 | /* Set UART mode, 8 bit, no parity, one stop. |
| 846 | * Enable receive and transmit. | 852 | * Enable receive and transmit. |
| 847 | */ | 853 | */ |
| 848 | sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; | 854 | out_be16(&sp->smc_smcmr, smcr_mk_clen(9) | SMCMR_SM_UART); |
| 849 | 855 | ||
| 850 | /* Enable only rx interrupts clear all pending events. */ | 856 | /* Enable only rx interrupts clear all pending events. */ |
| 851 | sp->smc_smcm = 0; | 857 | out_8(&sp->smc_smcm, 0); |
| 852 | sp->smc_smce = 0xff; | 858 | out_8(&sp->smc_smce, 0xff); |
| 853 | 859 | ||
| 854 | sp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); | 860 | setbits16(&sp->smc_smcmr, SMCMR_REN | SMCMR_TEN); |
| 855 | } | 861 | } |
| 856 | 862 | ||
| 857 | /* | 863 | /* |
| @@ -869,11 +875,11 @@ static int cpm_uart_request_port(struct uart_port *port) | |||
| 869 | return 0; | 875 | return 0; |
| 870 | 876 | ||
| 871 | if (IS_SMC(pinfo)) { | 877 | if (IS_SMC(pinfo)) { |
| 872 | pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); | 878 | clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX); |
| 873 | pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); | 879 | clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); |
| 874 | } else { | 880 | } else { |
| 875 | pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); | 881 | clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); |
| 876 | pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | 882 | clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); |
| 877 | } | 883 | } |
| 878 | 884 | ||
| 879 | ret = cpm_uart_allocbuf(pinfo, 0); | 885 | ret = cpm_uart_allocbuf(pinfo, 0); |
| @@ -929,6 +935,86 @@ static struct uart_ops cpm_uart_pops = { | |||
| 929 | .verify_port = cpm_uart_verify_port, | 935 | .verify_port = cpm_uart_verify_port, |
| 930 | }; | 936 | }; |
| 931 | 937 | ||
| 938 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
| 939 | struct uart_cpm_port cpm_uart_ports[UART_NR]; | ||
| 940 | |||
| 941 | static int cpm_uart_init_port(struct device_node *np, | ||
| 942 | struct uart_cpm_port *pinfo) | ||
| 943 | { | ||
| 944 | const u32 *data; | ||
| 945 | void __iomem *mem, *pram; | ||
| 946 | int len; | ||
| 947 | int ret; | ||
| 948 | |||
| 949 | data = of_get_property(np, "fsl,cpm-brg", &len); | ||
| 950 | if (!data || len != 4) { | ||
| 951 | printk(KERN_ERR "CPM UART %s has no/invalid " | ||
| 952 | "fsl,cpm-brg property.\n", np->name); | ||
| 953 | return -EINVAL; | ||
| 954 | } | ||
| 955 | pinfo->brg = *data; | ||
| 956 | |||
| 957 | data = of_get_property(np, "fsl,cpm-command", &len); | ||
| 958 | if (!data || len != 4) { | ||
| 959 | printk(KERN_ERR "CPM UART %s has no/invalid " | ||
| 960 | "fsl,cpm-command property.\n", np->name); | ||
| 961 | return -EINVAL; | ||
| 962 | } | ||
| 963 | pinfo->command = *data; | ||
| 964 | |||
| 965 | mem = of_iomap(np, 0); | ||
| 966 | if (!mem) | ||
| 967 | return -ENOMEM; | ||
| 968 | |||
| 969 | pram = of_iomap(np, 1); | ||
| 970 | if (!pram) { | ||
| 971 | ret = -ENOMEM; | ||
| 972 | goto out_mem; | ||
| 973 | } | ||
| 974 | |||
| 975 | if (of_device_is_compatible(np, "fsl,cpm1-scc-uart") || | ||
| 976 | of_device_is_compatible(np, "fsl,cpm2-scc-uart")) { | ||
| 977 | pinfo->sccp = mem; | ||
| 978 | pinfo->sccup = pram; | ||
| 979 | } else if (of_device_is_compatible(np, "fsl,cpm1-smc-uart") || | ||
| 980 | of_device_is_compatible(np, "fsl,cpm2-smc-uart")) { | ||
| 981 | pinfo->flags |= FLAG_SMC; | ||
| 982 | pinfo->smcp = mem; | ||
| 983 | pinfo->smcup = pram; | ||
| 984 | } else { | ||
| 985 | ret = -ENODEV; | ||
| 986 | goto out_pram; | ||
| 987 | } | ||
| 988 | |||
| 989 | pinfo->tx_nrfifos = TX_NUM_FIFO; | ||
| 990 | pinfo->tx_fifosize = TX_BUF_SIZE; | ||
| 991 | pinfo->rx_nrfifos = RX_NUM_FIFO; | ||
| 992 | pinfo->rx_fifosize = RX_BUF_SIZE; | ||
| 993 | |||
| 994 | pinfo->port.uartclk = ppc_proc_freq; | ||
| 995 | pinfo->port.mapbase = (unsigned long)mem; | ||
| 996 | pinfo->port.type = PORT_CPM; | ||
| 997 | pinfo->port.ops = &cpm_uart_pops, | ||
| 998 | pinfo->port.iotype = UPIO_MEM; | ||
| 999 | spin_lock_init(&pinfo->port.lock); | ||
| 1000 | |||
| 1001 | pinfo->port.irq = of_irq_to_resource(np, 0, NULL); | ||
| 1002 | if (pinfo->port.irq == NO_IRQ) { | ||
| 1003 | ret = -EINVAL; | ||
| 1004 | goto out_pram; | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | return cpm_uart_request_port(&pinfo->port); | ||
| 1008 | |||
| 1009 | out_pram: | ||
| 1010 | iounmap(pram); | ||
| 1011 | out_mem: | ||
| 1012 | iounmap(mem); | ||
| 1013 | return ret; | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | #else | ||
| 1017 | |||
| 932 | struct uart_cpm_port cpm_uart_ports[UART_NR] = { | 1018 | struct uart_cpm_port cpm_uart_ports[UART_NR] = { |
| 933 | [UART_SMC1] = { | 1019 | [UART_SMC1] = { |
| 934 | .port = { | 1020 | .port = { |
| @@ -1072,6 +1158,7 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con) | |||
| 1072 | 1158 | ||
| 1073 | return 0; | 1159 | return 0; |
| 1074 | } | 1160 | } |
| 1161 | #endif | ||
| 1075 | 1162 | ||
| 1076 | #ifdef CONFIG_SERIAL_CPM_CONSOLE | 1163 | #ifdef CONFIG_SERIAL_CPM_CONSOLE |
| 1077 | /* | 1164 | /* |
| @@ -1083,11 +1170,15 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con) | |||
| 1083 | static void cpm_uart_console_write(struct console *co, const char *s, | 1170 | static void cpm_uart_console_write(struct console *co, const char *s, |
| 1084 | u_int count) | 1171 | u_int count) |
| 1085 | { | 1172 | { |
| 1173 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
| 1174 | struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; | ||
| 1175 | #else | ||
| 1086 | struct uart_cpm_port *pinfo = | 1176 | struct uart_cpm_port *pinfo = |
| 1087 | &cpm_uart_ports[cpm_uart_port_map[co->index]]; | 1177 | &cpm_uart_ports[cpm_uart_port_map[co->index]]; |
| 1178 | #endif | ||
| 1088 | unsigned int i; | 1179 | unsigned int i; |
| 1089 | volatile cbd_t *bdp, *bdbase; | 1180 | cbd_t __iomem *bdp, *bdbase; |
| 1090 | volatile unsigned char *cp; | 1181 | unsigned char *cp; |
| 1091 | 1182 | ||
| 1092 | /* Get the address of the host memory buffer. | 1183 | /* Get the address of the host memory buffer. |
| 1093 | */ | 1184 | */ |
| @@ -1105,37 +1196,36 @@ static void cpm_uart_console_write(struct console *co, const char *s, | |||
| 1105 | * Ready indicates output is ready, and xmt is doing | 1196 | * Ready indicates output is ready, and xmt is doing |
| 1106 | * that, not that it is ready for us to send. | 1197 | * that, not that it is ready for us to send. |
| 1107 | */ | 1198 | */ |
| 1108 | while ((bdp->cbd_sc & BD_SC_READY) != 0) | 1199 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) |
| 1109 | ; | 1200 | ; |
| 1110 | 1201 | ||
| 1111 | /* Send the character out. | 1202 | /* Send the character out. |
| 1112 | * If the buffer address is in the CPM DPRAM, don't | 1203 | * If the buffer address is in the CPM DPRAM, don't |
| 1113 | * convert it. | 1204 | * convert it. |
| 1114 | */ | 1205 | */ |
| 1115 | cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); | 1206 | cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); |
| 1116 | |||
| 1117 | *cp = *s; | 1207 | *cp = *s; |
| 1118 | 1208 | ||
| 1119 | bdp->cbd_datlen = 1; | 1209 | out_be16(&bdp->cbd_datlen, 1); |
| 1120 | bdp->cbd_sc |= BD_SC_READY; | 1210 | setbits16(&bdp->cbd_sc, BD_SC_READY); |
| 1121 | 1211 | ||
| 1122 | if (bdp->cbd_sc & BD_SC_WRAP) | 1212 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) |
| 1123 | bdp = bdbase; | 1213 | bdp = bdbase; |
| 1124 | else | 1214 | else |
| 1125 | bdp++; | 1215 | bdp++; |
| 1126 | 1216 | ||
| 1127 | /* if a LF, also do CR... */ | 1217 | /* if a LF, also do CR... */ |
| 1128 | if (*s == 10) { | 1218 | if (*s == 10) { |
| 1129 | while ((bdp->cbd_sc & BD_SC_READY) != 0) | 1219 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) |
| 1130 | ; | 1220 | ; |
| 1131 | 1221 | ||
| 1132 | cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); | 1222 | cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); |
| 1133 | |||
| 1134 | *cp = 13; | 1223 | *cp = 13; |
| 1135 | bdp->cbd_datlen = 1; | ||
| 1136 | bdp->cbd_sc |= BD_SC_READY; | ||
| 1137 | 1224 | ||
| 1138 | if (bdp->cbd_sc & BD_SC_WRAP) | 1225 | out_be16(&bdp->cbd_datlen, 1); |
| 1226 | setbits16(&bdp->cbd_sc, BD_SC_READY); | ||
| 1227 | |||
| 1228 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) | ||
| 1139 | bdp = bdbase; | 1229 | bdp = bdbase; |
| 1140 | else | 1230 | else |
| 1141 | bdp++; | 1231 | bdp++; |
| @@ -1146,22 +1236,56 @@ static void cpm_uart_console_write(struct console *co, const char *s, | |||
| 1146 | * Finally, Wait for transmitter & holding register to empty | 1236 | * Finally, Wait for transmitter & holding register to empty |
| 1147 | * and restore the IER | 1237 | * and restore the IER |
| 1148 | */ | 1238 | */ |
| 1149 | while ((bdp->cbd_sc & BD_SC_READY) != 0) | 1239 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) |
| 1150 | ; | 1240 | ; |
| 1151 | 1241 | ||
| 1152 | pinfo->tx_cur = (volatile cbd_t *) bdp; | 1242 | pinfo->tx_cur = bdp; |
| 1153 | } | 1243 | } |
| 1154 | 1244 | ||
| 1155 | 1245 | ||
| 1156 | static int __init cpm_uart_console_setup(struct console *co, char *options) | 1246 | static int __init cpm_uart_console_setup(struct console *co, char *options) |
| 1157 | { | 1247 | { |
| 1158 | struct uart_port *port; | ||
| 1159 | struct uart_cpm_port *pinfo; | ||
| 1160 | int baud = 38400; | 1248 | int baud = 38400; |
| 1161 | int bits = 8; | 1249 | int bits = 8; |
| 1162 | int parity = 'n'; | 1250 | int parity = 'n'; |
| 1163 | int flow = 'n'; | 1251 | int flow = 'n'; |
| 1164 | int ret; | 1252 | int ret; |
| 1253 | struct uart_cpm_port *pinfo; | ||
| 1254 | struct uart_port *port; | ||
| 1255 | |||
| 1256 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
| 1257 | struct device_node *np = NULL; | ||
| 1258 | int i = 0; | ||
| 1259 | |||
| 1260 | if (co->index >= UART_NR) { | ||
| 1261 | printk(KERN_ERR "cpm_uart: console index %d too high\n", | ||
| 1262 | co->index); | ||
| 1263 | return -ENODEV; | ||
| 1264 | } | ||
| 1265 | |||
| 1266 | do { | ||
| 1267 | np = of_find_node_by_type(np, "serial"); | ||
| 1268 | if (!np) | ||
| 1269 | return -ENODEV; | ||
| 1270 | |||
| 1271 | if (!of_device_is_compatible(np, "fsl,cpm1-smc-uart") && | ||
| 1272 | !of_device_is_compatible(np, "fsl,cpm1-scc-uart") && | ||
| 1273 | !of_device_is_compatible(np, "fsl,cpm2-smc-uart") && | ||
| 1274 | !of_device_is_compatible(np, "fsl,cpm2-scc-uart")) | ||
| 1275 | i--; | ||
| 1276 | } while (i++ != co->index); | ||
| 1277 | |||
| 1278 | pinfo = &cpm_uart_ports[co->index]; | ||
| 1279 | |||
| 1280 | pinfo->flags |= FLAG_CONSOLE; | ||
| 1281 | port = &pinfo->port; | ||
| 1282 | |||
| 1283 | ret = cpm_uart_init_port(np, pinfo); | ||
| 1284 | of_node_put(np); | ||
| 1285 | if (ret) | ||
| 1286 | return ret; | ||
| 1287 | |||
| 1288 | #else | ||
| 1165 | 1289 | ||
| 1166 | struct fs_uart_platform_info *pdata; | 1290 | struct fs_uart_platform_info *pdata; |
| 1167 | struct platform_device* pdev = early_uart_get_pdev(co->index); | 1291 | struct platform_device* pdev = early_uart_get_pdev(co->index); |
| @@ -1188,6 +1312,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) | |||
| 1188 | } | 1312 | } |
| 1189 | 1313 | ||
| 1190 | pinfo->flags |= FLAG_CONSOLE; | 1314 | pinfo->flags |= FLAG_CONSOLE; |
| 1315 | #endif | ||
| 1191 | 1316 | ||
| 1192 | if (options) { | 1317 | if (options) { |
| 1193 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1318 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
| @@ -1196,12 +1321,18 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) | |||
| 1196 | baud = 9600; | 1321 | baud = 9600; |
| 1197 | } | 1322 | } |
| 1198 | 1323 | ||
| 1324 | #ifdef CONFIG_PPC_EARLY_DEBUG_CPM | ||
| 1325 | udbg_putc = NULL; | ||
| 1326 | #endif | ||
| 1327 | |||
| 1328 | cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); | ||
| 1329 | |||
| 1199 | if (IS_SMC(pinfo)) { | 1330 | if (IS_SMC(pinfo)) { |
| 1200 | pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); | 1331 | clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX); |
| 1201 | pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); | 1332 | clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); |
| 1202 | } else { | 1333 | } else { |
| 1203 | pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); | 1334 | clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); |
| 1204 | pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | 1335 | clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); |
| 1205 | } | 1336 | } |
| 1206 | 1337 | ||
| 1207 | ret = cpm_uart_allocbuf(pinfo, 1); | 1338 | ret = cpm_uart_allocbuf(pinfo, 1); |
| @@ -1217,6 +1348,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) | |||
| 1217 | cpm_uart_init_scc(pinfo); | 1348 | cpm_uart_init_scc(pinfo); |
| 1218 | 1349 | ||
| 1219 | uart_set_options(port, co, baud, parity, bits, flow); | 1350 | uart_set_options(port, co, baud, parity, bits, flow); |
| 1351 | cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX); | ||
| 1220 | 1352 | ||
| 1221 | return 0; | 1353 | return 0; |
| 1222 | } | 1354 | } |
| @@ -1232,7 +1364,7 @@ static struct console cpm_scc_uart_console = { | |||
| 1232 | .data = &cpm_reg, | 1364 | .data = &cpm_reg, |
| 1233 | }; | 1365 | }; |
| 1234 | 1366 | ||
| 1235 | int __init cpm_uart_console_init(void) | 1367 | static int __init cpm_uart_console_init(void) |
| 1236 | { | 1368 | { |
| 1237 | register_console(&cpm_scc_uart_console); | 1369 | register_console(&cpm_scc_uart_console); |
| 1238 | return 0; | 1370 | return 0; |
| @@ -1252,7 +1384,81 @@ static struct uart_driver cpm_reg = { | |||
| 1252 | .major = SERIAL_CPM_MAJOR, | 1384 | .major = SERIAL_CPM_MAJOR, |
| 1253 | .minor = SERIAL_CPM_MINOR, | 1385 | .minor = SERIAL_CPM_MINOR, |
| 1254 | .cons = CPM_UART_CONSOLE, | 1386 | .cons = CPM_UART_CONSOLE, |
| 1387 | .nr = UART_NR, | ||
| 1255 | }; | 1388 | }; |
| 1389 | |||
| 1390 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
| 1391 | static int probe_index; | ||
| 1392 | |||
| 1393 | static int __devinit cpm_uart_probe(struct of_device *ofdev, | ||
| 1394 | const struct of_device_id *match) | ||
| 1395 | { | ||
| 1396 | int index = probe_index++; | ||
| 1397 | struct uart_cpm_port *pinfo = &cpm_uart_ports[index]; | ||
| 1398 | int ret; | ||
| 1399 | |||
| 1400 | pinfo->port.line = index; | ||
| 1401 | |||
| 1402 | if (index >= UART_NR) | ||
| 1403 | return -ENODEV; | ||
| 1404 | |||
| 1405 | dev_set_drvdata(&ofdev->dev, pinfo); | ||
| 1406 | |||
| 1407 | ret = cpm_uart_init_port(ofdev->node, pinfo); | ||
| 1408 | if (ret) | ||
| 1409 | return ret; | ||
| 1410 | |||
| 1411 | return uart_add_one_port(&cpm_reg, &pinfo->port); | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | static int __devexit cpm_uart_remove(struct of_device *ofdev) | ||
| 1415 | { | ||
| 1416 | struct uart_cpm_port *pinfo = dev_get_drvdata(&ofdev->dev); | ||
| 1417 | return uart_remove_one_port(&cpm_reg, &pinfo->port); | ||
| 1418 | } | ||
| 1419 | |||
| 1420 | static struct of_device_id cpm_uart_match[] = { | ||
| 1421 | { | ||
| 1422 | .compatible = "fsl,cpm1-smc-uart", | ||
| 1423 | }, | ||
| 1424 | { | ||
| 1425 | .compatible = "fsl,cpm1-scc-uart", | ||
| 1426 | }, | ||
| 1427 | { | ||
| 1428 | .compatible = "fsl,cpm2-smc-uart", | ||
| 1429 | }, | ||
| 1430 | { | ||
| 1431 | .compatible = "fsl,cpm2-scc-uart", | ||
| 1432 | }, | ||
| 1433 | {} | ||
| 1434 | }; | ||
| 1435 | |||
| 1436 | static struct of_platform_driver cpm_uart_driver = { | ||
| 1437 | .name = "cpm_uart", | ||
| 1438 | .match_table = cpm_uart_match, | ||
| 1439 | .probe = cpm_uart_probe, | ||
| 1440 | .remove = cpm_uart_remove, | ||
| 1441 | }; | ||
| 1442 | |||
| 1443 | static int __init cpm_uart_init(void) | ||
| 1444 | { | ||
| 1445 | int ret = uart_register_driver(&cpm_reg); | ||
| 1446 | if (ret) | ||
| 1447 | return ret; | ||
| 1448 | |||
| 1449 | ret = of_register_platform_driver(&cpm_uart_driver); | ||
| 1450 | if (ret) | ||
| 1451 | uart_unregister_driver(&cpm_reg); | ||
| 1452 | |||
| 1453 | return ret; | ||
| 1454 | } | ||
| 1455 | |||
| 1456 | static void __exit cpm_uart_exit(void) | ||
| 1457 | { | ||
| 1458 | of_unregister_platform_driver(&cpm_uart_driver); | ||
| 1459 | uart_unregister_driver(&cpm_reg); | ||
| 1460 | } | ||
| 1461 | #else | ||
| 1256 | static int cpm_uart_drv_probe(struct device *dev) | 1462 | static int cpm_uart_drv_probe(struct device *dev) |
| 1257 | { | 1463 | { |
| 1258 | struct platform_device *pdev = to_platform_device(dev); | 1464 | struct platform_device *pdev = to_platform_device(dev); |
| @@ -1380,6 +1586,7 @@ static void __exit cpm_uart_exit(void) | |||
| 1380 | driver_unregister(&cpm_smc_uart_driver); | 1586 | driver_unregister(&cpm_smc_uart_driver); |
| 1381 | uart_unregister_driver(&cpm_reg); | 1587 | uart_unregister_driver(&cpm_reg); |
| 1382 | } | 1588 | } |
| 1589 | #endif | ||
| 1383 | 1590 | ||
| 1384 | module_init(cpm_uart_init); | 1591 | module_init(cpm_uart_init); |
| 1385 | module_exit(cpm_uart_exit); | 1592 | module_exit(cpm_uart_exit); |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 8c6324ed0202..52fb044bb79a 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c | |||
| @@ -49,9 +49,20 @@ | |||
| 49 | 49 | ||
| 50 | /**************************************************************/ | 50 | /**************************************************************/ |
| 51 | 51 | ||
| 52 | void cpm_line_cr_cmd(int line, int cmd) | 52 | #ifdef CONFIG_PPC_CPM_NEW_BINDING |
| 53 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) | ||
| 54 | { | ||
| 55 | u16 __iomem *cpcr = &cpmp->cp_cpcr; | ||
| 56 | |||
| 57 | out_be16(cpcr, port->command | (cmd << 8) | CPM_CR_FLG); | ||
| 58 | while (in_be16(cpcr) & CPM_CR_FLG) | ||
| 59 | ; | ||
| 60 | } | ||
| 61 | #else | ||
| 62 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) | ||
| 53 | { | 63 | { |
| 54 | ushort val; | 64 | ushort val; |
| 65 | int line = port - cpm_uart_ports; | ||
| 55 | volatile cpm8xx_t *cp = cpmp; | 66 | volatile cpm8xx_t *cp = cpmp; |
| 56 | 67 | ||
| 57 | switch (line) { | 68 | switch (line) { |
| @@ -114,6 +125,7 @@ void scc4_lineif(struct uart_cpm_port *pinfo) | |||
| 114 | /* XXX SCC4: insert port configuration here */ | 125 | /* XXX SCC4: insert port configuration here */ |
| 115 | pinfo->brg = 4; | 126 | pinfo->brg = 4; |
| 116 | } | 127 | } |
| 128 | #endif | ||
| 117 | 129 | ||
| 118 | /* | 130 | /* |
| 119 | * Allocate DP-Ram and memory buffers. We need to allocate a transmit and | 131 | * Allocate DP-Ram and memory buffers. We need to allocate a transmit and |
| @@ -167,7 +179,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) | |||
| 167 | pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos | 179 | pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos |
| 168 | * pinfo->rx_fifosize); | 180 | * pinfo->rx_fifosize); |
| 169 | 181 | ||
| 170 | pinfo->rx_bd_base = (volatile cbd_t *)dp_mem; | 182 | pinfo->rx_bd_base = (cbd_t __iomem __force *)dp_mem; |
| 171 | pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; | 183 | pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; |
| 172 | 184 | ||
| 173 | return 0; | 185 | return 0; |
| @@ -184,6 +196,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) | |||
| 184 | cpm_dpfree(pinfo->dp_addr); | 196 | cpm_dpfree(pinfo->dp_addr); |
| 185 | } | 197 | } |
| 186 | 198 | ||
| 199 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
| 187 | /* Setup any dynamic params in the uart desc */ | 200 | /* Setup any dynamic params in the uart desc */ |
| 188 | int cpm_uart_init_portdesc(void) | 201 | int cpm_uart_init_portdesc(void) |
| 189 | { | 202 | { |
| @@ -279,3 +292,4 @@ int cpm_uart_init_portdesc(void) | |||
| 279 | #endif | 292 | #endif |
| 280 | return 0; | 293 | return 0; |
| 281 | } | 294 | } |
| 295 | #endif | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/serial/cpm_uart/cpm_uart_cpm1.h index 2a6477834c3e..9b5465fb0bbb 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.h +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.h | |||
| @@ -13,30 +13,32 @@ | |||
| 13 | #include <asm/commproc.h> | 13 | #include <asm/commproc.h> |
| 14 | 14 | ||
| 15 | /* defines for IRQs */ | 15 | /* defines for IRQs */ |
| 16 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
| 16 | #define SMC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC1) | 17 | #define SMC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC1) |
| 17 | #define SMC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC2) | 18 | #define SMC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC2) |
| 18 | #define SCC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC1) | 19 | #define SCC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC1) |
| 19 | #define SCC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC2) | 20 | #define SCC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC2) |
| 20 | #define SCC3_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC3) | 21 | #define SCC3_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC3) |
| 21 | #define SCC4_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC4) | 22 | #define SCC4_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC4) |
| 23 | #endif | ||
| 22 | 24 | ||
| 23 | static inline void cpm_set_brg(int brg, int baud) | 25 | static inline void cpm_set_brg(int brg, int baud) |
| 24 | { | 26 | { |
| 25 | cpm_setbrg(brg, baud); | 27 | cpm_setbrg(brg, baud); |
| 26 | } | 28 | } |
| 27 | 29 | ||
| 28 | static inline void cpm_set_scc_fcr(volatile scc_uart_t * sup) | 30 | static inline void cpm_set_scc_fcr(scc_uart_t __iomem * sup) |
| 29 | { | 31 | { |
| 30 | sup->scc_genscc.scc_rfcr = SMC_EB; | 32 | out_8(&sup->scc_genscc.scc_rfcr, SMC_EB); |
| 31 | sup->scc_genscc.scc_tfcr = SMC_EB; | 33 | out_8(&sup->scc_genscc.scc_tfcr, SMC_EB); |
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | static inline void cpm_set_smc_fcr(volatile smc_uart_t * up) | 36 | static inline void cpm_set_smc_fcr(smc_uart_t __iomem * up) |
| 35 | { | 37 | { |
| 36 | up->smc_rfcr = SMC_EB; | 38 | out_8(&up->smc_rfcr, SMC_EB); |
| 37 | up->smc_tfcr = SMC_EB; | 39 | out_8(&up->smc_tfcr, SMC_EB); |
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | #define DPRAM_BASE ((unsigned char *)cpm_dpram_addr(0)) | 42 | #define DPRAM_BASE ((u8 __iomem __force *)cpm_dpram_addr(0)) |
| 41 | 43 | ||
| 42 | #endif | 44 | #endif |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index 7b61d805ebe9..882dbc17d590 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c | |||
| @@ -49,9 +49,22 @@ | |||
| 49 | 49 | ||
| 50 | /**************************************************************/ | 50 | /**************************************************************/ |
| 51 | 51 | ||
| 52 | void cpm_line_cr_cmd(int line, int cmd) | 52 | #ifdef CONFIG_PPC_CPM_NEW_BINDING |
| 53 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) | ||
| 54 | { | ||
| 55 | cpm_cpm2_t __iomem *cp = cpm2_map(im_cpm); | ||
| 56 | |||
| 57 | out_be32(&cp->cp_cpcr, port->command | cmd | CPM_CR_FLG); | ||
| 58 | while (in_be32(&cp->cp_cpcr) & CPM_CR_FLG) | ||
| 59 | ; | ||
| 60 | |||
| 61 | cpm2_unmap(cp); | ||
| 62 | } | ||
| 63 | #else | ||
| 64 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) | ||
| 53 | { | 65 | { |
| 54 | ulong val; | 66 | ulong val; |
| 67 | int line = port - cpm_uart_ports; | ||
| 55 | volatile cpm_cpm2_t *cp = cpm2_map(im_cpm); | 68 | volatile cpm_cpm2_t *cp = cpm2_map(im_cpm); |
| 56 | 69 | ||
| 57 | 70 | ||
| @@ -211,6 +224,7 @@ void scc4_lineif(struct uart_cpm_port *pinfo) | |||
| 211 | cpm2_unmap(cpmux); | 224 | cpm2_unmap(cpmux); |
| 212 | cpm2_unmap(io); | 225 | cpm2_unmap(io); |
| 213 | } | 226 | } |
| 227 | #endif | ||
| 214 | 228 | ||
| 215 | /* | 229 | /* |
| 216 | * Allocate DP-Ram and memory buffers. We need to allocate a transmit and | 230 | * Allocate DP-Ram and memory buffers. We need to allocate a transmit and |
| @@ -221,7 +235,7 @@ void scc4_lineif(struct uart_cpm_port *pinfo) | |||
| 221 | int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) | 235 | int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) |
| 222 | { | 236 | { |
| 223 | int dpmemsz, memsz; | 237 | int dpmemsz, memsz; |
| 224 | u8 *dp_mem; | 238 | u8 __iomem *dp_mem; |
| 225 | unsigned long dp_offset; | 239 | unsigned long dp_offset; |
| 226 | u8 *mem_addr; | 240 | u8 *mem_addr; |
| 227 | dma_addr_t dma_addr = 0; | 241 | dma_addr_t dma_addr = 0; |
| @@ -264,7 +278,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) | |||
| 264 | pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos | 278 | pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos |
| 265 | * pinfo->rx_fifosize); | 279 | * pinfo->rx_fifosize); |
| 266 | 280 | ||
| 267 | pinfo->rx_bd_base = (volatile cbd_t *)dp_mem; | 281 | pinfo->rx_bd_base = (cbd_t __iomem *)dp_mem; |
| 268 | pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; | 282 | pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; |
| 269 | 283 | ||
| 270 | return 0; | 284 | return 0; |
| @@ -275,12 +289,13 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) | |||
| 275 | dma_free_coherent(NULL, L1_CACHE_ALIGN(pinfo->rx_nrfifos * | 289 | dma_free_coherent(NULL, L1_CACHE_ALIGN(pinfo->rx_nrfifos * |
| 276 | pinfo->rx_fifosize) + | 290 | pinfo->rx_fifosize) + |
| 277 | L1_CACHE_ALIGN(pinfo->tx_nrfifos * | 291 | L1_CACHE_ALIGN(pinfo->tx_nrfifos * |
| 278 | pinfo->tx_fifosize), pinfo->mem_addr, | 292 | pinfo->tx_fifosize), (void __force *)pinfo->mem_addr, |
| 279 | pinfo->dma_addr); | 293 | pinfo->dma_addr); |
| 280 | 294 | ||
| 281 | cpm_dpfree(pinfo->dp_addr); | 295 | cpm_dpfree(pinfo->dp_addr); |
| 282 | } | 296 | } |
| 283 | 297 | ||
| 298 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
| 284 | /* Setup any dynamic params in the uart desc */ | 299 | /* Setup any dynamic params in the uart desc */ |
| 285 | int cpm_uart_init_portdesc(void) | 300 | int cpm_uart_init_portdesc(void) |
| 286 | { | 301 | { |
| @@ -386,3 +401,4 @@ int cpm_uart_init_portdesc(void) | |||
| 386 | 401 | ||
| 387 | return 0; | 402 | return 0; |
| 388 | } | 403 | } |
| 404 | #endif | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h index 1b3219f56c81..40006a7dce46 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.h +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.h | |||
| @@ -13,30 +13,32 @@ | |||
| 13 | #include <asm/cpm2.h> | 13 | #include <asm/cpm2.h> |
| 14 | 14 | ||
| 15 | /* defines for IRQs */ | 15 | /* defines for IRQs */ |
| 16 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
| 16 | #define SMC1_IRQ SIU_INT_SMC1 | 17 | #define SMC1_IRQ SIU_INT_SMC1 |
| 17 | #define SMC2_IRQ SIU_INT_SMC2 | 18 | #define SMC2_IRQ SIU_INT_SMC2 |
| 18 | #define SCC1_IRQ SIU_INT_SCC1 | 19 | #define SCC1_IRQ SIU_INT_SCC1 |
| 19 | #define SCC2_IRQ SIU_INT_SCC2 | 20 | #define SCC2_IRQ SIU_INT_SCC2 |
| 20 | #define SCC3_IRQ SIU_INT_SCC3 | 21 | #define SCC3_IRQ SIU_INT_SCC3 |
| 21 | #define SCC4_IRQ SIU_INT_SCC4 | 22 | #define SCC4_IRQ SIU_INT_SCC4 |
| 23 | #endif | ||
| 22 | 24 | ||
| 23 | static inline void cpm_set_brg(int brg, int baud) | 25 | static inline void cpm_set_brg(int brg, int baud) |
| 24 | { | 26 | { |
| 25 | cpm_setbrg(brg, baud); | 27 | cpm_setbrg(brg, baud); |
| 26 | } | 28 | } |
| 27 | 29 | ||
| 28 | static inline void cpm_set_scc_fcr(volatile scc_uart_t * sup) | 30 | static inline void cpm_set_scc_fcr(scc_uart_t __iomem *sup) |
| 29 | { | 31 | { |
| 30 | sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; | 32 | out_8(&sup->scc_genscc.scc_rfcr, CPMFCR_GBL | CPMFCR_EB); |
| 31 | sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; | 33 | out_8(&sup->scc_genscc.scc_tfcr, CPMFCR_GBL | CPMFCR_EB); |
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | static inline void cpm_set_smc_fcr(volatile smc_uart_t * up) | 36 | static inline void cpm_set_smc_fcr(smc_uart_t __iomem *up) |
| 35 | { | 37 | { |
| 36 | up->smc_rfcr = CPMFCR_GBL | CPMFCR_EB; | 38 | out_8(&up->smc_rfcr, CPMFCR_GBL | CPMFCR_EB); |
| 37 | up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB; | 39 | out_8(&up->smc_tfcr, CPMFCR_GBL | CPMFCR_EB); |
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | #define DPRAM_BASE ((unsigned char *)cpm_dpram_addr(0)) | 42 | #define DPRAM_BASE ((u8 __iomem __force *)cpm_dpram_addr(0)) |
| 41 | 43 | ||
| 42 | #endif | 44 | #endif |
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 35f8b86cc78f..035cca028199 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
| @@ -1051,7 +1051,7 @@ mpc52xx_uart_of_assign(struct device_node *np, int idx) | |||
| 1051 | /* If the slot is already occupied, then swap slots */ | 1051 | /* If the slot is already occupied, then swap slots */ |
| 1052 | if (mpc52xx_uart_nodes[idx] && (free_idx != -1)) | 1052 | if (mpc52xx_uart_nodes[idx] && (free_idx != -1)) |
| 1053 | mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx]; | 1053 | mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx]; |
| 1054 | mpc52xx_uart_nodes[i] = np; | 1054 | mpc52xx_uart_nodes[idx] = np; |
| 1055 | } | 1055 | } |
| 1056 | 1056 | ||
| 1057 | static void | 1057 | static void |
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 0fa9f6761763..794bd0f50d73 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
| @@ -88,6 +88,16 @@ MODULE_LICENSE("GPL"); | |||
| 88 | 88 | ||
| 89 | #define PWRDBG(fmt, arg...) printk(KERN_DEBUG fmt , ## arg) | 89 | #define PWRDBG(fmt, arg...) printk(KERN_DEBUG fmt , ## arg) |
| 90 | 90 | ||
| 91 | #ifdef CONFIG_SERIAL_PMACZILOG_TTYS | ||
| 92 | #define PMACZILOG_MAJOR TTY_MAJOR | ||
| 93 | #define PMACZILOG_MINOR 64 | ||
| 94 | #define PMACZILOG_NAME "ttyS" | ||
| 95 | #else | ||
| 96 | #define PMACZILOG_MAJOR 204 | ||
| 97 | #define PMACZILOG_MINOR 192 | ||
| 98 | #define PMACZILOG_NAME "ttyPZ" | ||
| 99 | #endif | ||
| 100 | |||
| 91 | 101 | ||
| 92 | /* | 102 | /* |
| 93 | * For the sake of early serial console, we can do a pre-probe | 103 | * For the sake of early serial console, we can do a pre-probe |
| @@ -99,9 +109,10 @@ static DEFINE_MUTEX(pmz_irq_mutex); | |||
| 99 | 109 | ||
| 100 | static struct uart_driver pmz_uart_reg = { | 110 | static struct uart_driver pmz_uart_reg = { |
| 101 | .owner = THIS_MODULE, | 111 | .owner = THIS_MODULE, |
| 102 | .driver_name = "ttyS", | 112 | .driver_name = PMACZILOG_NAME, |
| 103 | .dev_name = "ttyS", | 113 | .dev_name = PMACZILOG_NAME, |
| 104 | .major = TTY_MAJOR, | 114 | .major = PMACZILOG_MAJOR, |
| 115 | .minor = PMACZILOG_MINOR, | ||
| 105 | }; | 116 | }; |
| 106 | 117 | ||
| 107 | 118 | ||
| @@ -1587,7 +1598,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state) | |||
| 1587 | if (pm_state.event == mdev->ofdev.dev.power.power_state.event) | 1598 | if (pm_state.event == mdev->ofdev.dev.power.power_state.event) |
| 1588 | return 0; | 1599 | return 0; |
| 1589 | 1600 | ||
| 1590 | pmz_debug("suspend, switching to state %d\n", pm_state); | 1601 | pmz_debug("suspend, switching to state %d\n", pm_state.event); |
| 1591 | 1602 | ||
| 1592 | state = pmz_uart_reg.state + uap->port.line; | 1603 | state = pmz_uart_reg.state + uap->port.line; |
| 1593 | 1604 | ||
| @@ -1778,7 +1789,7 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int c | |||
| 1778 | static int __init pmz_console_setup(struct console *co, char *options); | 1789 | static int __init pmz_console_setup(struct console *co, char *options); |
| 1779 | 1790 | ||
| 1780 | static struct console pmz_console = { | 1791 | static struct console pmz_console = { |
| 1781 | .name = "ttyS", | 1792 | .name = PMACZILOG_NAME, |
| 1782 | .write = pmz_console_write, | 1793 | .write = pmz_console_write, |
| 1783 | .device = uart_console_device, | 1794 | .device = uart_console_device, |
| 1784 | .setup = pmz_console_setup, | 1795 | .setup = pmz_console_setup, |
| @@ -1802,7 +1813,6 @@ static int __init pmz_register(void) | |||
| 1802 | 1813 | ||
| 1803 | pmz_uart_reg.nr = pmz_ports_count; | 1814 | pmz_uart_reg.nr = pmz_ports_count; |
| 1804 | pmz_uart_reg.cons = PMACZILOG_CONSOLE; | 1815 | pmz_uart_reg.cons = PMACZILOG_CONSOLE; |
| 1805 | pmz_uart_reg.minor = 64; | ||
| 1806 | 1816 | ||
| 1807 | /* | 1817 | /* |
| 1808 | * Register this driver with the serial core | 1818 | * Register this driver with the serial core |
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index f5051cf1a0c8..dfef83f14960 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * uartlite.c: Serial driver for Xilinx uartlite serial controller | 2 | * uartlite.c: Serial driver for Xilinx uartlite serial controller |
| 3 | * | 3 | * |
| 4 | * Peter Korsgaard <jacmet@sunsite.dk> | 4 | * Copyright (C) 2006 Peter Korsgaard <jacmet@sunsite.dk> |
| 5 | * Copyright (C) 2007 Secret Lab Technologies Ltd. | ||
| 5 | * | 6 | * |
| 6 | * This file is licensed under the terms of the GNU General Public License | 7 | * This file is licensed under the terms of the GNU General Public License |
| 7 | * version 2. This program is licensed "as is" without any warranty of any | 8 | * version 2. This program is licensed "as is" without any warranty of any |
| @@ -17,14 +18,23 @@ | |||
| 17 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
| 18 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 19 | #include <asm/io.h> | 20 | #include <asm/io.h> |
| 21 | #if defined(CONFIG_OF) | ||
| 22 | #include <linux/of_device.h> | ||
| 23 | #include <linux/of_platform.h> | ||
| 24 | #endif | ||
| 20 | 25 | ||
| 26 | #define ULITE_NAME "ttyUL" | ||
| 21 | #define ULITE_MAJOR 204 | 27 | #define ULITE_MAJOR 204 |
| 22 | #define ULITE_MINOR 187 | 28 | #define ULITE_MINOR 187 |
| 23 | #define ULITE_NR_UARTS 4 | 29 | #define ULITE_NR_UARTS 4 |
| 24 | 30 | ||
| 25 | /* For register details see datasheet: | 31 | /* --------------------------------------------------------------------- |
| 26 | http://www.xilinx.com/bvdocs/ipcenter/data_sheet/opb_uartlite.pdf | 32 | * Register definitions |
| 27 | */ | 33 | * |
| 34 | * For register details see datasheet: | ||
| 35 | * http://www.xilinx.com/bvdocs/ipcenter/data_sheet/opb_uartlite.pdf | ||
| 36 | */ | ||
| 37 | |||
| 28 | #define ULITE_RX 0x00 | 38 | #define ULITE_RX 0x00 |
| 29 | #define ULITE_TX 0x04 | 39 | #define ULITE_TX 0x04 |
| 30 | #define ULITE_STATUS 0x08 | 40 | #define ULITE_STATUS 0x08 |
| @@ -46,7 +56,11 @@ | |||
| 46 | #define ULITE_CONTROL_IE 0x10 | 56 | #define ULITE_CONTROL_IE 0x10 |
| 47 | 57 | ||
| 48 | 58 | ||
| 49 | static struct uart_port ports[ULITE_NR_UARTS]; | 59 | static struct uart_port ulite_ports[ULITE_NR_UARTS]; |
| 60 | |||
| 61 | /* --------------------------------------------------------------------- | ||
| 62 | * Core UART driver operations | ||
| 63 | */ | ||
| 50 | 64 | ||
| 51 | static int ulite_receive(struct uart_port *port, int stat) | 65 | static int ulite_receive(struct uart_port *port, int stat) |
| 52 | { | 66 | { |
| @@ -307,6 +321,10 @@ static struct uart_ops ulite_ops = { | |||
| 307 | .verify_port = ulite_verify_port | 321 | .verify_port = ulite_verify_port |
| 308 | }; | 322 | }; |
| 309 | 323 | ||
| 324 | /* --------------------------------------------------------------------- | ||
| 325 | * Console driver operations | ||
| 326 | */ | ||
| 327 | |||
| 310 | #ifdef CONFIG_SERIAL_UARTLITE_CONSOLE | 328 | #ifdef CONFIG_SERIAL_UARTLITE_CONSOLE |
| 311 | static void ulite_console_wait_tx(struct uart_port *port) | 329 | static void ulite_console_wait_tx(struct uart_port *port) |
| 312 | { | 330 | { |
| @@ -329,7 +347,7 @@ static void ulite_console_putchar(struct uart_port *port, int ch) | |||
| 329 | static void ulite_console_write(struct console *co, const char *s, | 347 | static void ulite_console_write(struct console *co, const char *s, |
| 330 | unsigned int count) | 348 | unsigned int count) |
| 331 | { | 349 | { |
| 332 | struct uart_port *port = &ports[co->index]; | 350 | struct uart_port *port = &ulite_ports[co->index]; |
| 333 | unsigned long flags; | 351 | unsigned long flags; |
| 334 | unsigned int ier; | 352 | unsigned int ier; |
| 335 | int locked = 1; | 353 | int locked = 1; |
| @@ -355,6 +373,31 @@ static void ulite_console_write(struct console *co, const char *s, | |||
| 355 | spin_unlock_irqrestore(&port->lock, flags); | 373 | spin_unlock_irqrestore(&port->lock, flags); |
| 356 | } | 374 | } |
| 357 | 375 | ||
| 376 | #if defined(CONFIG_OF) | ||
| 377 | static inline void __init ulite_console_of_find_device(int id) | ||
| 378 | { | ||
| 379 | struct device_node *np; | ||
| 380 | struct resource res; | ||
| 381 | const unsigned int *of_id; | ||
| 382 | int rc; | ||
| 383 | |||
| 384 | for_each_compatible_node(np, NULL, "xilinx,uartlite") { | ||
| 385 | of_id = of_get_property(np, "port-number", NULL); | ||
| 386 | if ((!of_id) || (*of_id != id)) | ||
| 387 | continue; | ||
| 388 | |||
| 389 | rc = of_address_to_resource(np, 0, &res); | ||
| 390 | if (rc) | ||
| 391 | continue; | ||
| 392 | |||
| 393 | ulite_ports[id].mapbase = res.start; | ||
| 394 | return; | ||
| 395 | } | ||
| 396 | } | ||
| 397 | #else /* CONFIG_OF */ | ||
| 398 | static inline void __init ulite_console_of_find_device(int id) { /* do nothing */ } | ||
| 399 | #endif /* CONFIG_OF */ | ||
| 400 | |||
| 358 | static int __init ulite_console_setup(struct console *co, char *options) | 401 | static int __init ulite_console_setup(struct console *co, char *options) |
| 359 | { | 402 | { |
| 360 | struct uart_port *port; | 403 | struct uart_port *port; |
| @@ -366,11 +409,23 @@ static int __init ulite_console_setup(struct console *co, char *options) | |||
| 366 | if (co->index < 0 || co->index >= ULITE_NR_UARTS) | 409 | if (co->index < 0 || co->index >= ULITE_NR_UARTS) |
| 367 | return -EINVAL; | 410 | return -EINVAL; |
| 368 | 411 | ||
| 369 | port = &ports[co->index]; | 412 | port = &ulite_ports[co->index]; |
| 370 | 413 | ||
| 371 | /* not initialized yet? */ | 414 | /* Check if it is an OF device */ |
| 372 | if (!port->membase) | 415 | if (!port->mapbase) |
| 416 | ulite_console_of_find_device(co->index); | ||
| 417 | |||
| 418 | /* Do we have a device now? */ | ||
| 419 | if (!port->mapbase) { | ||
| 420 | pr_debug("console on ttyUL%i not present\n", co->index); | ||
| 373 | return -ENODEV; | 421 | return -ENODEV; |
| 422 | } | ||
| 423 | |||
| 424 | /* not initialized yet? */ | ||
| 425 | if (!port->membase) { | ||
| 426 | if (ulite_request_port(port)) | ||
| 427 | return -ENODEV; | ||
| 428 | } | ||
| 374 | 429 | ||
| 375 | if (options) | 430 | if (options) |
| 376 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 431 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
| @@ -381,7 +436,7 @@ static int __init ulite_console_setup(struct console *co, char *options) | |||
| 381 | static struct uart_driver ulite_uart_driver; | 436 | static struct uart_driver ulite_uart_driver; |
| 382 | 437 | ||
| 383 | static struct console ulite_console = { | 438 | static struct console ulite_console = { |
| 384 | .name = "ttyUL", | 439 | .name = ULITE_NAME, |
| 385 | .write = ulite_console_write, | 440 | .write = ulite_console_write, |
| 386 | .device = uart_console_device, | 441 | .device = uart_console_device, |
| 387 | .setup = ulite_console_setup, | 442 | .setup = ulite_console_setup, |
| @@ -403,7 +458,7 @@ console_initcall(ulite_console_init); | |||
| 403 | static struct uart_driver ulite_uart_driver = { | 458 | static struct uart_driver ulite_uart_driver = { |
| 404 | .owner = THIS_MODULE, | 459 | .owner = THIS_MODULE, |
| 405 | .driver_name = "uartlite", | 460 | .driver_name = "uartlite", |
| 406 | .dev_name = "ttyUL", | 461 | .dev_name = ULITE_NAME, |
| 407 | .major = ULITE_MAJOR, | 462 | .major = ULITE_MAJOR, |
| 408 | .minor = ULITE_MINOR, | 463 | .minor = ULITE_MINOR, |
| 409 | .nr = ULITE_NR_UARTS, | 464 | .nr = ULITE_NR_UARTS, |
| @@ -412,59 +467,111 @@ static struct uart_driver ulite_uart_driver = { | |||
| 412 | #endif | 467 | #endif |
| 413 | }; | 468 | }; |
| 414 | 469 | ||
| 415 | static int __devinit ulite_probe(struct platform_device *pdev) | 470 | /* --------------------------------------------------------------------- |
| 471 | * Port assignment functions (mapping devices to uart_port structures) | ||
| 472 | */ | ||
| 473 | |||
| 474 | /** ulite_assign: register a uartlite device with the driver | ||
| 475 | * | ||
| 476 | * @dev: pointer to device structure | ||
| 477 | * @id: requested id number. Pass -1 for automatic port assignment | ||
| 478 | * @base: base address of uartlite registers | ||
| 479 | * @irq: irq number for uartlite | ||
| 480 | * | ||
| 481 | * Returns: 0 on success, <0 otherwise | ||
| 482 | */ | ||
| 483 | static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq) | ||
| 416 | { | 484 | { |
| 417 | struct resource *res, *res2; | ||
| 418 | struct uart_port *port; | 485 | struct uart_port *port; |
| 486 | int rc; | ||
| 419 | 487 | ||
| 420 | if (pdev->id < 0 || pdev->id >= ULITE_NR_UARTS) | 488 | /* if id = -1; then scan for a free id and use that */ |
| 489 | if (id < 0) { | ||
| 490 | for (id = 0; id < ULITE_NR_UARTS; id++) | ||
| 491 | if (ulite_ports[id].mapbase == 0) | ||
| 492 | break; | ||
| 493 | } | ||
| 494 | if (id < 0 || id >= ULITE_NR_UARTS) { | ||
| 495 | dev_err(dev, "%s%i too large\n", ULITE_NAME, id); | ||
| 421 | return -EINVAL; | 496 | return -EINVAL; |
| 497 | } | ||
| 422 | 498 | ||
| 423 | if (ports[pdev->id].membase) | 499 | if ((ulite_ports[id].mapbase) && (ulite_ports[id].mapbase != base)) { |
| 500 | dev_err(dev, "cannot assign to %s%i; it is already in use\n", | ||
| 501 | ULITE_NAME, id); | ||
| 424 | return -EBUSY; | 502 | return -EBUSY; |
| 503 | } | ||
| 425 | 504 | ||
| 426 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 505 | port = &ulite_ports[id]; |
| 427 | if (!res) | ||
| 428 | return -ENODEV; | ||
| 429 | 506 | ||
| 430 | res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 507 | spin_lock_init(&port->lock); |
| 431 | if (!res2) | 508 | port->fifosize = 16; |
| 432 | return -ENODEV; | 509 | port->regshift = 2; |
| 510 | port->iotype = UPIO_MEM; | ||
| 511 | port->iobase = 1; /* mark port in use */ | ||
| 512 | port->mapbase = base; | ||
| 513 | port->membase = NULL; | ||
| 514 | port->ops = &ulite_ops; | ||
| 515 | port->irq = irq; | ||
| 516 | port->flags = UPF_BOOT_AUTOCONF; | ||
| 517 | port->dev = dev; | ||
| 518 | port->type = PORT_UNKNOWN; | ||
| 519 | port->line = id; | ||
| 520 | |||
| 521 | dev_set_drvdata(dev, port); | ||
| 522 | |||
| 523 | /* Register the port */ | ||
| 524 | rc = uart_add_one_port(&ulite_uart_driver, port); | ||
| 525 | if (rc) { | ||
| 526 | dev_err(dev, "uart_add_one_port() failed; err=%i\n", rc); | ||
| 527 | port->mapbase = 0; | ||
| 528 | dev_set_drvdata(dev, NULL); | ||
| 529 | return rc; | ||
| 530 | } | ||
| 433 | 531 | ||
| 434 | port = &ports[pdev->id]; | 532 | return 0; |
| 533 | } | ||
| 435 | 534 | ||
| 436 | port->fifosize = 16; | 535 | /** ulite_release: register a uartlite device with the driver |
| 437 | port->regshift = 2; | 536 | * |
| 438 | port->iotype = UPIO_MEM; | 537 | * @dev: pointer to device structure |
| 439 | port->iobase = 1; /* mark port in use */ | 538 | */ |
| 440 | port->mapbase = res->start; | 539 | static int __devinit ulite_release(struct device *dev) |
| 441 | port->membase = NULL; | 540 | { |
| 442 | port->ops = &ulite_ops; | 541 | struct uart_port *port = dev_get_drvdata(dev); |
| 443 | port->irq = res2->start; | 542 | int rc = 0; |
| 444 | port->flags = UPF_BOOT_AUTOCONF; | ||
| 445 | port->dev = &pdev->dev; | ||
| 446 | port->type = PORT_UNKNOWN; | ||
| 447 | port->line = pdev->id; | ||
| 448 | 543 | ||
| 449 | uart_add_one_port(&ulite_uart_driver, port); | 544 | if (port) { |
| 450 | platform_set_drvdata(pdev, port); | 545 | rc = uart_remove_one_port(&ulite_uart_driver, port); |
| 546 | dev_set_drvdata(dev, NULL); | ||
| 547 | port->mapbase = 0; | ||
| 548 | } | ||
| 451 | 549 | ||
| 452 | return 0; | 550 | return rc; |
| 453 | } | 551 | } |
| 454 | 552 | ||
| 455 | static int ulite_remove(struct platform_device *pdev) | 553 | /* --------------------------------------------------------------------- |
| 554 | * Platform bus binding | ||
| 555 | */ | ||
| 556 | |||
| 557 | static int __devinit ulite_probe(struct platform_device *pdev) | ||
| 456 | { | 558 | { |
| 457 | struct uart_port *port = platform_get_drvdata(pdev); | 559 | struct resource *res, *res2; |
| 458 | 560 | ||
| 459 | platform_set_drvdata(pdev, NULL); | 561 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 562 | if (!res) | ||
| 563 | return -ENODEV; | ||
| 460 | 564 | ||
| 461 | if (port) | 565 | res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
| 462 | uart_remove_one_port(&ulite_uart_driver, port); | 566 | if (!res2) |
| 567 | return -ENODEV; | ||
| 463 | 568 | ||
| 464 | /* mark port as free */ | 569 | return ulite_assign(&pdev->dev, pdev->id, res->start, res2->start); |
| 465 | port->membase = NULL; | 570 | } |
| 466 | 571 | ||
| 467 | return 0; | 572 | static int ulite_remove(struct platform_device *pdev) |
| 573 | { | ||
| 574 | return ulite_release(&pdev->dev); | ||
| 468 | } | 575 | } |
| 469 | 576 | ||
| 470 | static struct platform_driver ulite_platform_driver = { | 577 | static struct platform_driver ulite_platform_driver = { |
| @@ -476,24 +583,109 @@ static struct platform_driver ulite_platform_driver = { | |||
| 476 | }, | 583 | }, |
| 477 | }; | 584 | }; |
| 478 | 585 | ||
| 586 | /* --------------------------------------------------------------------- | ||
| 587 | * OF bus bindings | ||
| 588 | */ | ||
| 589 | #if defined(CONFIG_OF) | ||
| 590 | static int __devinit | ||
| 591 | ulite_of_probe(struct of_device *op, const struct of_device_id *match) | ||
| 592 | { | ||
| 593 | struct resource res; | ||
| 594 | const unsigned int *id; | ||
| 595 | int irq, rc; | ||
| 596 | |||
| 597 | dev_dbg(&op->dev, "%s(%p, %p)\n", __FUNCTION__, op, match); | ||
| 598 | |||
| 599 | rc = of_address_to_resource(op->node, 0, &res); | ||
| 600 | if (rc) { | ||
| 601 | dev_err(&op->dev, "invalid address\n"); | ||
| 602 | return rc; | ||
| 603 | } | ||
| 604 | |||
| 605 | irq = irq_of_parse_and_map(op->node, 0); | ||
| 606 | |||
| 607 | id = of_get_property(op->node, "port-number", NULL); | ||
| 608 | |||
| 609 | return ulite_assign(&op->dev, id ? *id : -1, res.start+3, irq); | ||
| 610 | } | ||
| 611 | |||
| 612 | static int __devexit ulite_of_remove(struct of_device *op) | ||
| 613 | { | ||
| 614 | return ulite_release(&op->dev); | ||
| 615 | } | ||
| 616 | |||
| 617 | /* Match table for of_platform binding */ | ||
| 618 | static struct of_device_id __devinit ulite_of_match[] = { | ||
| 619 | { .type = "serial", .compatible = "xilinx,uartlite", }, | ||
| 620 | {}, | ||
| 621 | }; | ||
| 622 | MODULE_DEVICE_TABLE(of, ulite_of_match); | ||
| 623 | |||
| 624 | static struct of_platform_driver ulite_of_driver = { | ||
| 625 | .owner = THIS_MODULE, | ||
| 626 | .name = "uartlite", | ||
| 627 | .match_table = ulite_of_match, | ||
| 628 | .probe = ulite_of_probe, | ||
| 629 | .remove = __devexit_p(ulite_of_remove), | ||
| 630 | .driver = { | ||
| 631 | .name = "uartlite", | ||
| 632 | }, | ||
| 633 | }; | ||
| 634 | |||
| 635 | /* Registration helpers to keep the number of #ifdefs to a minimum */ | ||
| 636 | static inline int __init ulite_of_register(void) | ||
| 637 | { | ||
| 638 | pr_debug("uartlite: calling of_register_platform_driver()\n"); | ||
| 639 | return of_register_platform_driver(&ulite_of_driver); | ||
| 640 | } | ||
| 641 | |||
| 642 | static inline void __exit ulite_of_unregister(void) | ||
| 643 | { | ||
| 644 | of_unregister_platform_driver(&ulite_of_driver); | ||
| 645 | } | ||
| 646 | #else /* CONFIG_OF */ | ||
| 647 | /* CONFIG_OF not enabled; do nothing helpers */ | ||
| 648 | static inline int __init ulite_of_register(void) { return 0; } | ||
| 649 | static inline void __exit ulite_of_unregister(void) { } | ||
| 650 | #endif /* CONFIG_OF */ | ||
| 651 | |||
| 652 | /* --------------------------------------------------------------------- | ||
| 653 | * Module setup/teardown | ||
| 654 | */ | ||
| 655 | |||
| 479 | int __init ulite_init(void) | 656 | int __init ulite_init(void) |
| 480 | { | 657 | { |
| 481 | int ret; | 658 | int ret; |
| 482 | 659 | ||
| 660 | pr_debug("uartlite: calling uart_register_driver()\n"); | ||
| 483 | ret = uart_register_driver(&ulite_uart_driver); | 661 | ret = uart_register_driver(&ulite_uart_driver); |
| 484 | if (ret) | 662 | if (ret) |
| 485 | return ret; | 663 | goto err_uart; |
| 486 | 664 | ||
| 665 | ret = ulite_of_register(); | ||
| 666 | if (ret) | ||
| 667 | goto err_of; | ||
| 668 | |||
| 669 | pr_debug("uartlite: calling platform_driver_register()\n"); | ||
| 487 | ret = platform_driver_register(&ulite_platform_driver); | 670 | ret = platform_driver_register(&ulite_platform_driver); |
| 488 | if (ret) | 671 | if (ret) |
| 489 | uart_unregister_driver(&ulite_uart_driver); | 672 | goto err_plat; |
| 490 | 673 | ||
| 674 | return 0; | ||
| 675 | |||
| 676 | err_plat: | ||
| 677 | ulite_of_unregister(); | ||
| 678 | err_of: | ||
| 679 | uart_unregister_driver(&ulite_uart_driver); | ||
| 680 | err_uart: | ||
| 681 | printk(KERN_ERR "registering uartlite driver failed: err=%i", ret); | ||
| 491 | return ret; | 682 | return ret; |
| 492 | } | 683 | } |
| 493 | 684 | ||
| 494 | void __exit ulite_exit(void) | 685 | void __exit ulite_exit(void) |
| 495 | { | 686 | { |
| 496 | platform_driver_unregister(&ulite_platform_driver); | 687 | platform_driver_unregister(&ulite_platform_driver); |
| 688 | ulite_of_unregister(); | ||
| 497 | uart_unregister_driver(&ulite_uart_driver); | 689 | uart_unregister_driver(&ulite_uart_driver); |
| 498 | } | 690 | } |
| 499 | 691 | ||
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 8503e733a172..cbe71a5338d0 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | * more details. | 17 | * more details. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #undef DEBUG | ||
| 21 | |||
| 20 | #include <linux/module.h> | 22 | #include <linux/module.h> |
| 21 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
| 22 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
| @@ -535,33 +537,35 @@ static int __devinit platinumfb_probe(struct of_device* odev, | |||
| 535 | volatile __u8 *fbuffer; | 537 | volatile __u8 *fbuffer; |
| 536 | int bank0, bank1, bank2, bank3, rc; | 538 | int bank0, bank1, bank2, bank3, rc; |
| 537 | 539 | ||
| 538 | printk(KERN_INFO "platinumfb: Found Apple Platinum video hardware\n"); | 540 | dev_info(&odev->dev, "Found Apple Platinum video hardware\n"); |
| 539 | 541 | ||
| 540 | info = framebuffer_alloc(sizeof(*pinfo), &odev->dev); | 542 | info = framebuffer_alloc(sizeof(*pinfo), &odev->dev); |
| 541 | if (info == NULL) | 543 | if (info == NULL) { |
| 544 | dev_err(&odev->dev, "Failed to allocate fbdev !\n"); | ||
| 542 | return -ENOMEM; | 545 | return -ENOMEM; |
| 546 | } | ||
| 543 | pinfo = info->par; | 547 | pinfo = info->par; |
| 544 | 548 | ||
| 545 | if (of_address_to_resource(dp, 0, &pinfo->rsrc_reg) || | 549 | if (of_address_to_resource(dp, 0, &pinfo->rsrc_reg) || |
| 546 | of_address_to_resource(dp, 1, &pinfo->rsrc_fb)) { | 550 | of_address_to_resource(dp, 1, &pinfo->rsrc_fb)) { |
| 547 | printk(KERN_ERR "platinumfb: Can't get resources\n"); | 551 | dev_err(&odev->dev, "Can't get resources\n"); |
| 548 | framebuffer_release(info); | ||
| 549 | return -ENXIO; | ||
| 550 | } | ||
| 551 | if (!request_mem_region(pinfo->rsrc_reg.start, | ||
| 552 | pinfo->rsrc_reg.start - | ||
| 553 | pinfo->rsrc_reg.end + 1, | ||
| 554 | "platinumfb registers")) { | ||
| 555 | framebuffer_release(info); | 552 | framebuffer_release(info); |
| 556 | return -ENXIO; | 553 | return -ENXIO; |
| 557 | } | 554 | } |
| 555 | dev_dbg(&odev->dev, " registers : 0x%llx...0x%llx\n", | ||
| 556 | (unsigned long long)pinfo->rsrc_reg.start, | ||
| 557 | (unsigned long long)pinfo->rsrc_reg.end); | ||
| 558 | dev_dbg(&odev->dev, " framebuffer: 0x%llx...0x%llx\n", | ||
| 559 | (unsigned long long)pinfo->rsrc_fb.start, | ||
| 560 | (unsigned long long)pinfo->rsrc_fb.end); | ||
| 561 | |||
| 562 | /* Do not try to request register space, they overlap with the | ||
| 563 | * northbridge and that can fail. Only request framebuffer | ||
| 564 | */ | ||
| 558 | if (!request_mem_region(pinfo->rsrc_fb.start, | 565 | if (!request_mem_region(pinfo->rsrc_fb.start, |
| 559 | pinfo->rsrc_fb.start | 566 | pinfo->rsrc_fb.end - pinfo->rsrc_fb.start + 1, |
| 560 | - pinfo->rsrc_fb.end + 1, | ||
| 561 | "platinumfb framebuffer")) { | 567 | "platinumfb framebuffer")) { |
| 562 | release_mem_region(pinfo->rsrc_reg.start, | 568 | printk(KERN_ERR "platinumfb: Can't request framebuffer !\n"); |
| 563 | pinfo->rsrc_reg.end - | ||
| 564 | pinfo->rsrc_reg.start + 1); | ||
| 565 | framebuffer_release(info); | 569 | framebuffer_release(info); |
| 566 | return -ENXIO; | 570 | return -ENXIO; |
| 567 | } | 571 | } |
| @@ -600,7 +604,8 @@ static int __devinit platinumfb_probe(struct of_device* odev, | |||
| 600 | bank2 = fbuffer[0x200000] == 0x56; | 604 | bank2 = fbuffer[0x200000] == 0x56; |
| 601 | bank3 = fbuffer[0x300000] == 0x78; | 605 | bank3 = fbuffer[0x300000] == 0x78; |
| 602 | pinfo->total_vram = (bank0 + bank1 + bank2 + bank3) * 0x100000; | 606 | pinfo->total_vram = (bank0 + bank1 + bank2 + bank3) * 0x100000; |
| 603 | printk(KERN_INFO "platinumfb: Total VRAM = %dMB (%d%d%d%d)\n", (int) (pinfo->total_vram / 1024 / 1024), | 607 | printk(KERN_INFO "platinumfb: Total VRAM = %dMB (%d%d%d%d)\n", |
| 608 | (unsigned int) (pinfo->total_vram / 1024 / 1024), | ||
| 604 | bank3, bank2, bank1, bank0); | 609 | bank3, bank2, bank1, bank0); |
| 605 | 610 | ||
| 606 | /* | 611 | /* |
| @@ -644,16 +649,15 @@ static int __devexit platinumfb_remove(struct of_device* odev) | |||
| 644 | unregister_framebuffer (info); | 649 | unregister_framebuffer (info); |
| 645 | 650 | ||
| 646 | /* Unmap frame buffer and registers */ | 651 | /* Unmap frame buffer and registers */ |
| 652 | iounmap(pinfo->frame_buffer); | ||
| 653 | iounmap(pinfo->platinum_regs); | ||
| 654 | iounmap(pinfo->cmap_regs); | ||
| 655 | |||
| 647 | release_mem_region(pinfo->rsrc_fb.start, | 656 | release_mem_region(pinfo->rsrc_fb.start, |
| 648 | pinfo->rsrc_fb.end - | 657 | pinfo->rsrc_fb.end - |
| 649 | pinfo->rsrc_fb.start + 1); | 658 | pinfo->rsrc_fb.start + 1); |
| 650 | release_mem_region(pinfo->rsrc_reg.start, | 659 | |
| 651 | pinfo->rsrc_reg.end - | ||
| 652 | pinfo->rsrc_reg.start + 1); | ||
| 653 | iounmap(pinfo->frame_buffer); | ||
| 654 | iounmap(pinfo->platinum_regs); | ||
| 655 | release_mem_region(pinfo->cmap_regs_phys, 0x1000); | 660 | release_mem_region(pinfo->cmap_regs_phys, 0x1000); |
| 656 | iounmap(pinfo->cmap_regs); | ||
| 657 | 661 | ||
| 658 | framebuffer_release(info); | 662 | framebuffer_release(info); |
| 659 | 663 | ||
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 6ef9733a18d4..6ef99b2d13ca 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c | |||
| @@ -6,9 +6,12 @@ | |||
| 6 | * Author: MontaVista Software, Inc. | 6 | * Author: MontaVista Software, Inc. |
| 7 | * source@mvista.com | 7 | * source@mvista.com |
| 8 | * | 8 | * |
| 9 | * 2002-2007 (c) MontaVista Software, Inc. This file is licensed under the | 9 | * 2002-2007 (c) MontaVista Software, Inc. |
| 10 | * terms of the GNU General Public License version 2. This program is licensed | 10 | * 2007 (c) Secret Lab Technologies, Ltd. |
| 11 | * "as is" without any warranty of any kind, whether express or implied. | 11 | * |
| 12 | * This file is licensed under the terms of the GNU General Public License | ||
| 13 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 14 | * kind, whether express or implied. | ||
| 12 | */ | 15 | */ |
| 13 | 16 | ||
| 14 | /* | 17 | /* |
| @@ -18,6 +21,7 @@ | |||
| 18 | * Geert Uytterhoeven. | 21 | * Geert Uytterhoeven. |
| 19 | */ | 22 | */ |
| 20 | 23 | ||
| 24 | #include <linux/device.h> | ||
| 21 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 22 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
| 23 | #include <linux/version.h> | 27 | #include <linux/version.h> |
| @@ -28,9 +32,12 @@ | |||
| 28 | #include <linux/init.h> | 32 | #include <linux/init.h> |
| 29 | #include <linux/dma-mapping.h> | 33 | #include <linux/dma-mapping.h> |
| 30 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
| 31 | 35 | #if defined(CONFIG_OF) | |
| 36 | #include <linux/of_device.h> | ||
| 37 | #include <linux/of_platform.h> | ||
| 38 | #endif | ||
| 32 | #include <asm/io.h> | 39 | #include <asm/io.h> |
| 33 | #include <syslib/virtex_devices.h> | 40 | #include <linux/xilinxfb.h> |
| 34 | 41 | ||
| 35 | #define DRIVER_NAME "xilinxfb" | 42 | #define DRIVER_NAME "xilinxfb" |
| 36 | #define DRIVER_DESCRIPTION "Xilinx TFT LCD frame buffer driver" | 43 | #define DRIVER_DESCRIPTION "Xilinx TFT LCD frame buffer driver" |
| @@ -63,12 +70,6 @@ | |||
| 63 | */ | 70 | */ |
| 64 | #define BYTES_PER_PIXEL 4 | 71 | #define BYTES_PER_PIXEL 4 |
| 65 | #define BITS_PER_PIXEL (BYTES_PER_PIXEL * 8) | 72 | #define BITS_PER_PIXEL (BYTES_PER_PIXEL * 8) |
| 66 | #define XRES 640 | ||
| 67 | #define YRES 480 | ||
| 68 | #define XRES_VIRTUAL 1024 | ||
| 69 | #define YRES_VIRTUAL YRES | ||
| 70 | #define LINE_LENGTH (XRES_VIRTUAL * BYTES_PER_PIXEL) | ||
| 71 | #define FB_SIZE (YRES_VIRTUAL * LINE_LENGTH) | ||
| 72 | 73 | ||
| 73 | #define RED_SHIFT 16 | 74 | #define RED_SHIFT 16 |
| 74 | #define GREEN_SHIFT 8 | 75 | #define GREEN_SHIFT 8 |
| @@ -77,23 +78,26 @@ | |||
| 77 | #define PALETTE_ENTRIES_NO 16 /* passed to fb_alloc_cmap() */ | 78 | #define PALETTE_ENTRIES_NO 16 /* passed to fb_alloc_cmap() */ |
| 78 | 79 | ||
| 79 | /* | 80 | /* |
| 81 | * Default xilinxfb configuration | ||
| 82 | */ | ||
| 83 | static struct xilinxfb_platform_data xilinx_fb_default_pdata = { | ||
| 84 | .xres = 640, | ||
| 85 | .yres = 480, | ||
| 86 | .xvirt = 1024, | ||
| 87 | .yvirt = 480; | ||
| 88 | }; | ||
| 89 | |||
| 90 | /* | ||
| 80 | * Here are the default fb_fix_screeninfo and fb_var_screeninfo structures | 91 | * Here are the default fb_fix_screeninfo and fb_var_screeninfo structures |
| 81 | */ | 92 | */ |
| 82 | static struct fb_fix_screeninfo xilinx_fb_fix = { | 93 | static struct fb_fix_screeninfo xilinx_fb_fix = { |
| 83 | .id = "Xilinx", | 94 | .id = "Xilinx", |
| 84 | .type = FB_TYPE_PACKED_PIXELS, | 95 | .type = FB_TYPE_PACKED_PIXELS, |
| 85 | .visual = FB_VISUAL_TRUECOLOR, | 96 | .visual = FB_VISUAL_TRUECOLOR, |
| 86 | .smem_len = FB_SIZE, | ||
| 87 | .line_length = LINE_LENGTH, | ||
| 88 | .accel = FB_ACCEL_NONE | 97 | .accel = FB_ACCEL_NONE |
| 89 | }; | 98 | }; |
| 90 | 99 | ||
| 91 | static struct fb_var_screeninfo xilinx_fb_var = { | 100 | static struct fb_var_screeninfo xilinx_fb_var = { |
| 92 | .xres = XRES, | ||
| 93 | .yres = YRES, | ||
| 94 | .xres_virtual = XRES_VIRTUAL, | ||
| 95 | .yres_virtual = YRES_VIRTUAL, | ||
| 96 | |||
| 97 | .bits_per_pixel = BITS_PER_PIXEL, | 101 | .bits_per_pixel = BITS_PER_PIXEL, |
| 98 | 102 | ||
| 99 | .red = { RED_SHIFT, 8, 0 }, | 103 | .red = { RED_SHIFT, 8, 0 }, |
| @@ -111,8 +115,9 @@ struct xilinxfb_drvdata { | |||
| 111 | u32 regs_phys; /* phys. address of the control registers */ | 115 | u32 regs_phys; /* phys. address of the control registers */ |
| 112 | u32 __iomem *regs; /* virt. address of the control registers */ | 116 | u32 __iomem *regs; /* virt. address of the control registers */ |
| 113 | 117 | ||
| 114 | unsigned char __iomem *fb_virt; /* virt. address of the frame buffer */ | 118 | void *fb_virt; /* virt. address of the frame buffer */ |
| 115 | dma_addr_t fb_phys; /* phys. address of the frame buffer */ | 119 | dma_addr_t fb_phys; /* phys. address of the frame buffer */ |
| 120 | int fb_alloced; /* Flag, was the fb memory alloced? */ | ||
| 116 | 121 | ||
| 117 | u32 reg_ctrl_default; | 122 | u32 reg_ctrl_default; |
| 118 | 123 | ||
| @@ -195,130 +200,136 @@ static struct fb_ops xilinxfb_ops = | |||
| 195 | .fb_imageblit = cfb_imageblit, | 200 | .fb_imageblit = cfb_imageblit, |
| 196 | }; | 201 | }; |
| 197 | 202 | ||
| 198 | /* === The device driver === */ | 203 | /* --------------------------------------------------------------------- |
| 204 | * Bus independent setup/teardown | ||
| 205 | */ | ||
| 199 | 206 | ||
| 200 | static int | 207 | static int xilinxfb_assign(struct device *dev, unsigned long physaddr, |
| 201 | xilinxfb_drv_probe(struct device *dev) | 208 | struct xilinxfb_platform_data *pdata) |
| 202 | { | 209 | { |
| 203 | struct platform_device *pdev; | ||
| 204 | struct xilinxfb_platform_data *pdata; | ||
| 205 | struct xilinxfb_drvdata *drvdata; | 210 | struct xilinxfb_drvdata *drvdata; |
| 206 | struct resource *regs_res; | 211 | int rc; |
| 207 | int retval; | 212 | int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL; |
| 208 | |||
| 209 | if (!dev) | ||
| 210 | return -EINVAL; | ||
| 211 | |||
| 212 | pdev = to_platform_device(dev); | ||
| 213 | pdata = pdev->dev.platform_data; | ||
| 214 | 213 | ||
| 214 | /* Allocate the driver data region */ | ||
| 215 | drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); | 215 | drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); |
| 216 | if (!drvdata) { | 216 | if (!drvdata) { |
| 217 | printk(KERN_ERR "Couldn't allocate device private record\n"); | 217 | dev_err(dev, "Couldn't allocate device private record\n"); |
| 218 | return -ENOMEM; | 218 | return -ENOMEM; |
| 219 | } | 219 | } |
| 220 | dev_set_drvdata(dev, drvdata); | 220 | dev_set_drvdata(dev, drvdata); |
| 221 | 221 | ||
| 222 | /* Map the control registers in */ | 222 | /* Map the control registers in */ |
| 223 | regs_res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 223 | if (!request_mem_region(physaddr, 8, DRIVER_NAME)) { |
| 224 | if (!regs_res || (regs_res->end - regs_res->start + 1 < 8)) { | 224 | dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", |
| 225 | printk(KERN_ERR "Couldn't get registers resource\n"); | 225 | physaddr); |
| 226 | retval = -EFAULT; | 226 | rc = -ENODEV; |
| 227 | goto failed1; | 227 | goto err_region; |
| 228 | } | 228 | } |
| 229 | 229 | drvdata->regs_phys = physaddr; | |
| 230 | if (!request_mem_region(regs_res->start, 8, DRIVER_NAME)) { | 230 | drvdata->regs = ioremap(physaddr, 8); |
| 231 | printk(KERN_ERR | 231 | if (!drvdata->regs) { |
| 232 | "Couldn't lock memory region at 0x%08X\n", | 232 | dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", |
| 233 | regs_res->start); | 233 | physaddr); |
| 234 | retval = -EBUSY; | 234 | rc = -ENODEV; |
| 235 | goto failed1; | 235 | goto err_map; |
| 236 | } | 236 | } |
| 237 | drvdata->regs = (u32 __iomem*) ioremap(regs_res->start, 8); | ||
| 238 | drvdata->regs_phys = regs_res->start; | ||
| 239 | 237 | ||
| 240 | /* Allocate the framebuffer memory */ | 238 | /* Allocate the framebuffer memory */ |
| 241 | drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(FB_SIZE), | 239 | if (pdata->fb_phys) { |
| 242 | &drvdata->fb_phys, GFP_KERNEL); | 240 | drvdata->fb_phys = pdata->fb_phys; |
| 241 | drvdata->fb_virt = ioremap(pdata->fb_phys, fbsize); | ||
| 242 | } else { | ||
| 243 | drvdata->fb_alloced = 1; | ||
| 244 | drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(fbsize), | ||
| 245 | &drvdata->fb_phys, GFP_KERNEL); | ||
| 246 | } | ||
| 247 | |||
| 243 | if (!drvdata->fb_virt) { | 248 | if (!drvdata->fb_virt) { |
| 244 | printk(KERN_ERR "Could not allocate frame buffer memory\n"); | 249 | dev_err(dev, "Could not allocate frame buffer memory\n"); |
| 245 | retval = -ENOMEM; | 250 | rc = -ENOMEM; |
| 246 | goto failed2; | 251 | goto err_fbmem; |
| 247 | } | 252 | } |
| 248 | 253 | ||
| 249 | /* Clear (turn to black) the framebuffer */ | 254 | /* Clear (turn to black) the framebuffer */ |
| 250 | memset_io((void *) drvdata->fb_virt, 0, FB_SIZE); | 255 | memset_io((void __iomem *)drvdata->fb_virt, 0, fbsize); |
| 251 | 256 | ||
| 252 | /* Tell the hardware where the frame buffer is */ | 257 | /* Tell the hardware where the frame buffer is */ |
| 253 | xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys); | 258 | xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys); |
| 254 | 259 | ||
| 255 | /* Turn on the display */ | 260 | /* Turn on the display */ |
| 256 | drvdata->reg_ctrl_default = REG_CTRL_ENABLE; | 261 | drvdata->reg_ctrl_default = REG_CTRL_ENABLE; |
| 257 | if (pdata && pdata->rotate_screen) | 262 | if (pdata->rotate_screen) |
| 258 | drvdata->reg_ctrl_default |= REG_CTRL_ROTATE; | 263 | drvdata->reg_ctrl_default |= REG_CTRL_ROTATE; |
| 259 | xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); | 264 | xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); |
| 260 | 265 | ||
| 261 | /* Fill struct fb_info */ | 266 | /* Fill struct fb_info */ |
| 262 | drvdata->info.device = dev; | 267 | drvdata->info.device = dev; |
| 263 | drvdata->info.screen_base = drvdata->fb_virt; | 268 | drvdata->info.screen_base = (void __iomem *)drvdata->fb_virt; |
| 264 | drvdata->info.fbops = &xilinxfb_ops; | 269 | drvdata->info.fbops = &xilinxfb_ops; |
| 265 | drvdata->info.fix = xilinx_fb_fix; | 270 | drvdata->info.fix = xilinx_fb_fix; |
| 266 | drvdata->info.fix.smem_start = drvdata->fb_phys; | 271 | drvdata->info.fix.smem_start = drvdata->fb_phys; |
| 267 | drvdata->info.pseudo_palette = drvdata->pseudo_palette; | 272 | drvdata->info.fix.smem_len = fbsize; |
| 268 | 273 | drvdata->info.fix.line_length = pdata->xvirt * BYTES_PER_PIXEL; | |
| 269 | if (fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0) < 0) { | ||
| 270 | printk(KERN_ERR "Fail to allocate colormap (%d entries)\n", | ||
| 271 | PALETTE_ENTRIES_NO); | ||
| 272 | retval = -EFAULT; | ||
| 273 | goto failed3; | ||
| 274 | } | ||
| 275 | 274 | ||
| 275 | drvdata->info.pseudo_palette = drvdata->pseudo_palette; | ||
| 276 | drvdata->info.flags = FBINFO_DEFAULT; | 276 | drvdata->info.flags = FBINFO_DEFAULT; |
| 277 | if (pdata) { | ||
| 278 | xilinx_fb_var.height = pdata->screen_height_mm; | ||
| 279 | xilinx_fb_var.width = pdata->screen_width_mm; | ||
| 280 | } | ||
| 281 | drvdata->info.var = xilinx_fb_var; | 277 | drvdata->info.var = xilinx_fb_var; |
| 278 | drvdata->info.var.height = pdata->screen_height_mm; | ||
| 279 | drvdata->info.var.width = pdata->screen_width_mm; | ||
| 280 | drvdata->info.var.xres = pdata->xres; | ||
| 281 | drvdata->info.var.yres = pdata->yres; | ||
| 282 | drvdata->info.var.xres_virtual = pdata->xvirt; | ||
| 283 | drvdata->info.var.yres_virtual = pdata->yvirt; | ||
| 284 | |||
| 285 | /* Allocate a colour map */ | ||
| 286 | rc = fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0); | ||
| 287 | if (rc) { | ||
| 288 | dev_err(dev, "Fail to allocate colormap (%d entries)\n", | ||
| 289 | PALETTE_ENTRIES_NO); | ||
| 290 | goto err_cmap; | ||
| 291 | } | ||
| 282 | 292 | ||
| 283 | /* Register new frame buffer */ | 293 | /* Register new frame buffer */ |
| 284 | if (register_framebuffer(&drvdata->info) < 0) { | 294 | rc = register_framebuffer(&drvdata->info); |
| 285 | printk(KERN_ERR "Could not register frame buffer\n"); | 295 | if (rc) { |
| 286 | retval = -EINVAL; | 296 | dev_err(dev, "Could not register frame buffer\n"); |
| 287 | goto failed4; | 297 | goto err_regfb; |
| 288 | } | 298 | } |
| 289 | 299 | ||
| 300 | /* Put a banner in the log (for DEBUG) */ | ||
| 301 | dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs); | ||
| 302 | dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n", | ||
| 303 | (void*)drvdata->fb_phys, drvdata->fb_virt, fbsize); | ||
| 304 | |||
| 290 | return 0; /* success */ | 305 | return 0; /* success */ |
| 291 | 306 | ||
| 292 | failed4: | 307 | err_regfb: |
| 293 | fb_dealloc_cmap(&drvdata->info.cmap); | 308 | fb_dealloc_cmap(&drvdata->info.cmap); |
| 294 | 309 | ||
| 295 | failed3: | 310 | err_cmap: |
| 296 | dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt, | 311 | if (drvdata->fb_alloced) |
| 297 | drvdata->fb_phys); | 312 | dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt, |
| 298 | 313 | drvdata->fb_phys); | |
| 299 | /* Turn off the display */ | 314 | /* Turn off the display */ |
| 300 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); | 315 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); |
| 316 | |||
| 317 | err_fbmem: | ||
| 301 | iounmap(drvdata->regs); | 318 | iounmap(drvdata->regs); |
| 302 | 319 | ||
| 303 | failed2: | 320 | err_map: |
| 304 | release_mem_region(regs_res->start, 8); | 321 | release_mem_region(physaddr, 8); |
| 305 | 322 | ||
| 306 | failed1: | 323 | err_region: |
| 307 | kfree(drvdata); | 324 | kfree(drvdata); |
| 308 | dev_set_drvdata(dev, NULL); | 325 | dev_set_drvdata(dev, NULL); |
| 309 | 326 | ||
| 310 | return retval; | 327 | return rc; |
| 311 | } | 328 | } |
| 312 | 329 | ||
| 313 | static int | 330 | static int xilinxfb_release(struct device *dev) |
| 314 | xilinxfb_drv_remove(struct device *dev) | ||
| 315 | { | 331 | { |
| 316 | struct xilinxfb_drvdata *drvdata; | 332 | struct xilinxfb_drvdata *drvdata = dev_get_drvdata(dev); |
| 317 | |||
| 318 | if (!dev) | ||
| 319 | return -ENODEV; | ||
| 320 | |||
| 321 | drvdata = (struct xilinxfb_drvdata *) dev_get_drvdata(dev); | ||
| 322 | 333 | ||
| 323 | #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) | 334 | #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) |
| 324 | xilinx_fb_blank(VESA_POWERDOWN, &drvdata->info); | 335 | xilinx_fb_blank(VESA_POWERDOWN, &drvdata->info); |
| @@ -328,8 +339,9 @@ xilinxfb_drv_remove(struct device *dev) | |||
| 328 | 339 | ||
| 329 | fb_dealloc_cmap(&drvdata->info.cmap); | 340 | fb_dealloc_cmap(&drvdata->info.cmap); |
| 330 | 341 | ||
| 331 | dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt, | 342 | if (drvdata->fb_alloced) |
| 332 | drvdata->fb_phys); | 343 | dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len), |
| 344 | drvdata->fb_virt, drvdata->fb_phys); | ||
| 333 | 345 | ||
| 334 | /* Turn off the display */ | 346 | /* Turn off the display */ |
| 335 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); | 347 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); |
| @@ -343,29 +355,168 @@ xilinxfb_drv_remove(struct device *dev) | |||
| 343 | return 0; | 355 | return 0; |
| 344 | } | 356 | } |
| 345 | 357 | ||
| 358 | /* --------------------------------------------------------------------- | ||
| 359 | * Platform bus binding | ||
| 360 | */ | ||
| 361 | |||
| 362 | static int | ||
| 363 | xilinxfb_platform_probe(struct platform_device *pdev) | ||
| 364 | { | ||
| 365 | struct xilinxfb_platform_data *pdata; | ||
| 366 | struct resource *res; | ||
| 346 | 367 | ||
| 347 | static struct device_driver xilinxfb_driver = { | 368 | /* Find the registers address */ |
| 348 | .name = DRIVER_NAME, | 369 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 349 | .bus = &platform_bus_type, | 370 | if (!res) { |
| 371 | dev_err(&pdev->dev, "Couldn't get registers resource\n"); | ||
| 372 | return -ENODEV; | ||
| 373 | } | ||
| 350 | 374 | ||
| 351 | .probe = xilinxfb_drv_probe, | 375 | /* If a pdata structure is provided, then extract the parameters */ |
| 352 | .remove = xilinxfb_drv_remove | 376 | pdata = &xilinx_fb_default_pdata; |
| 377 | if (pdev->dev.platform_data) { | ||
| 378 | pdata = pdev->dev.platform_data; | ||
| 379 | if (!pdata->xres) | ||
| 380 | pdata->xres = xilinx_fb_default_pdata.xres; | ||
| 381 | if (!pdata->yres) | ||
| 382 | pdata->yres = xilinx_fb_default_pdata.yres; | ||
| 383 | if (!pdata->xvirt) | ||
| 384 | pdata->xvirt = xilinx_fb_default_pdata.xvirt; | ||
| 385 | if (!pdata->yvirt) | ||
| 386 | pdata->yvirt = xilinx_fb_default_pdata.yvirt; | ||
| 387 | } | ||
| 388 | |||
| 389 | return xilinxfb_assign(&pdev->dev, res->start, pdata); | ||
| 390 | } | ||
| 391 | |||
| 392 | static int | ||
| 393 | xilinxfb_platform_remove(struct platform_device *pdev) | ||
| 394 | { | ||
| 395 | return xilinxfb_release(&pdev->dev); | ||
| 396 | } | ||
| 397 | |||
| 398 | |||
| 399 | static struct platform_driver xilinxfb_platform_driver = { | ||
| 400 | .probe = xilinxfb_platform_probe, | ||
| 401 | .remove = xilinxfb_platform_remove, | ||
| 402 | .driver = { | ||
| 403 | .owner = THIS_MODULE, | ||
| 404 | .name = DRIVER_NAME, | ||
| 405 | }, | ||
| 406 | }; | ||
| 407 | |||
| 408 | /* --------------------------------------------------------------------- | ||
| 409 | * OF bus binding | ||
| 410 | */ | ||
| 411 | |||
| 412 | #if defined(CONFIG_OF) | ||
| 413 | static int __devinit | ||
| 414 | xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) | ||
| 415 | { | ||
| 416 | struct resource res; | ||
| 417 | const u32 *prop; | ||
| 418 | struct xilinxfb_platform_data pdata; | ||
| 419 | int size, rc; | ||
| 420 | |||
| 421 | /* Copy with the default pdata (not a ptr reference!) */ | ||
| 422 | pdata = xilinx_fb_default_pdata; | ||
| 423 | |||
| 424 | dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match); | ||
| 425 | |||
| 426 | rc = of_address_to_resource(op->node, 0, &res); | ||
| 427 | if (rc) { | ||
| 428 | dev_err(&op->dev, "invalid address\n"); | ||
| 429 | return rc; | ||
| 430 | } | ||
| 431 | |||
| 432 | prop = of_get_property(op->node, "phys-size", &size); | ||
| 433 | if ((prop) && (size >= sizeof(u32)*2)) { | ||
| 434 | pdata.screen_width_mm = prop[0]; | ||
| 435 | pdata.screen_height_mm = prop[1]; | ||
| 436 | } | ||
| 437 | |||
| 438 | prop = of_get_property(op->node, "resolution", &size); | ||
| 439 | if ((prop) && (size >= sizeof(u32)*2)) { | ||
| 440 | pdata.xres = prop[0]; | ||
| 441 | pdata.yres = prop[1]; | ||
| 442 | } | ||
| 443 | |||
| 444 | prop = of_get_property(op->node, "virtual-resolution", &size); | ||
| 445 | if ((prop) && (size >= sizeof(u32)*2)) { | ||
| 446 | pdata.xvirt = prop[0]; | ||
| 447 | pdata.yvirt = prop[1]; | ||
| 448 | } | ||
| 449 | |||
| 450 | if (of_find_property(op->node, "rotate-display", NULL)) | ||
| 451 | pdata.rotate_screen = 1; | ||
| 452 | |||
| 453 | return xilinxfb_assign(&op->dev, res.start, &pdata); | ||
| 454 | } | ||
| 455 | |||
| 456 | static int __devexit xilinxfb_of_remove(struct of_device *op) | ||
| 457 | { | ||
| 458 | return xilinxfb_release(&op->dev); | ||
| 459 | } | ||
| 460 | |||
| 461 | /* Match table for of_platform binding */ | ||
| 462 | static struct of_device_id __devinit xilinxfb_of_match[] = { | ||
| 463 | { .compatible = "xilinx,ml300-fb", }, | ||
| 464 | {}, | ||
| 353 | }; | 465 | }; |
| 466 | MODULE_DEVICE_TABLE(of, xilinxfb_of_match); | ||
| 467 | |||
| 468 | static struct of_platform_driver xilinxfb_of_driver = { | ||
| 469 | .owner = THIS_MODULE, | ||
| 470 | .name = DRIVER_NAME, | ||
| 471 | .match_table = xilinxfb_of_match, | ||
| 472 | .probe = xilinxfb_of_probe, | ||
| 473 | .remove = __devexit_p(xilinxfb_of_remove), | ||
| 474 | .driver = { | ||
| 475 | .name = DRIVER_NAME, | ||
| 476 | }, | ||
| 477 | }; | ||
| 478 | |||
| 479 | /* Registration helpers to keep the number of #ifdefs to a minimum */ | ||
| 480 | static inline int __init xilinxfb_of_register(void) | ||
| 481 | { | ||
| 482 | pr_debug("xilinxfb: calling of_register_platform_driver()\n"); | ||
| 483 | return of_register_platform_driver(&xilinxfb_of_driver); | ||
| 484 | } | ||
| 485 | |||
| 486 | static inline void __exit xilinxfb_of_unregister(void) | ||
| 487 | { | ||
| 488 | of_unregister_platform_driver(&xilinxfb_of_driver); | ||
| 489 | } | ||
| 490 | #else /* CONFIG_OF */ | ||
| 491 | /* CONFIG_OF not enabled; do nothing helpers */ | ||
| 492 | static inline int __init xilinxfb_of_register(void) { return 0; } | ||
| 493 | static inline void __exit xilinxfb_of_unregister(void) { } | ||
| 494 | #endif /* CONFIG_OF */ | ||
| 495 | |||
| 496 | /* --------------------------------------------------------------------- | ||
| 497 | * Module setup and teardown | ||
| 498 | */ | ||
| 354 | 499 | ||
| 355 | static int __init | 500 | static int __init |
| 356 | xilinxfb_init(void) | 501 | xilinxfb_init(void) |
| 357 | { | 502 | { |
| 358 | /* | 503 | int rc; |
| 359 | * No kernel boot options used, | 504 | rc = xilinxfb_of_register(); |
| 360 | * so we just need to register the driver | 505 | if (rc) |
| 361 | */ | 506 | return rc; |
| 362 | return driver_register(&xilinxfb_driver); | 507 | |
| 508 | rc = platform_driver_register(&xilinxfb_platform_driver); | ||
| 509 | if (rc) | ||
| 510 | xilinxfb_of_unregister(); | ||
| 511 | |||
| 512 | return rc; | ||
| 363 | } | 513 | } |
| 364 | 514 | ||
| 365 | static void __exit | 515 | static void __exit |
| 366 | xilinxfb_cleanup(void) | 516 | xilinxfb_cleanup(void) |
| 367 | { | 517 | { |
| 368 | driver_unregister(&xilinxfb_driver); | 518 | platform_driver_unregister(&xilinxfb_platform_driver); |
| 519 | xilinxfb_of_unregister(); | ||
| 369 | } | 520 | } |
| 370 | 521 | ||
| 371 | module_init(xilinxfb_init); | 522 | module_init(xilinxfb_init); |
