diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/processor_idle.c | 15 | ||||
-rw-r--r-- | drivers/base/memory.c | 3 | ||||
-rw-r--r-- | drivers/char/pcmcia/ipwireless/hardware.c | 275 | ||||
-rw-r--r-- | drivers/char/pcmcia/ipwireless/hardware.h | 4 | ||||
-rw-r--r-- | drivers/char/pcmcia/ipwireless/main.c | 86 | ||||
-rw-r--r-- | drivers/char/pcmcia/ipwireless/main.h | 5 | ||||
-rw-r--r-- | drivers/char/pcmcia/ipwireless/network.c | 58 | ||||
-rw-r--r-- | drivers/char/pcmcia/ipwireless/network.h | 1 | ||||
-rw-r--r-- | drivers/char/pcmcia/ipwireless/tty.c | 2 | ||||
-rw-r--r-- | drivers/cpuidle/cpuidle.c | 2 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-bfin-twi.c | 35 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-gpio.c | 9 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-s3c2410.c | 129 |
13 files changed, 383 insertions, 241 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index b7f2963693a7..283c08f5f4d4 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -1332,9 +1332,15 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
1332 | if (!pr->flags.power_setup_done) | 1332 | if (!pr->flags.power_setup_done) |
1333 | return -ENODEV; | 1333 | return -ENODEV; |
1334 | 1334 | ||
1335 | /* Fall back to the default idle loop */ | 1335 | /* |
1336 | pm_idle = pm_idle_save; | 1336 | * Fall back to the default idle loop, when pm_idle_save had |
1337 | synchronize_sched(); /* Relies on interrupts forcing exit from idle. */ | 1337 | * been initialized. |
1338 | */ | ||
1339 | if (pm_idle_save) { | ||
1340 | pm_idle = pm_idle_save; | ||
1341 | /* Relies on interrupts forcing exit from idle. */ | ||
1342 | synchronize_sched(); | ||
1343 | } | ||
1338 | 1344 | ||
1339 | pr->flags.power = 0; | 1345 | pr->flags.power = 0; |
1340 | result = acpi_processor_get_power_info(pr); | 1346 | result = acpi_processor_get_power_info(pr); |
@@ -1896,7 +1902,8 @@ int acpi_processor_power_exit(struct acpi_processor *pr, | |||
1896 | 1902 | ||
1897 | /* Unregister the idle handler when processor #0 is removed. */ | 1903 | /* Unregister the idle handler when processor #0 is removed. */ |
1898 | if (pr->id == 0) { | 1904 | if (pr->id == 0) { |
1899 | pm_idle = pm_idle_save; | 1905 | if (pm_idle_save) |
1906 | pm_idle = pm_idle_save; | ||
1900 | 1907 | ||
1901 | /* | 1908 | /* |
1902 | * We are about to unload the current idle thread pm callback | 1909 | * We are about to unload the current idle thread pm callback |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 3ad49a00029f..af0d175c025d 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -103,7 +103,8 @@ static ssize_t show_mem_phys_index(struct sys_device *dev, | |||
103 | /* | 103 | /* |
104 | * Show whether the section of memory is likely to be hot-removable | 104 | * Show whether the section of memory is likely to be hot-removable |
105 | */ | 105 | */ |
106 | static ssize_t show_mem_removable(struct sys_device *dev, char *buf) | 106 | static ssize_t show_mem_removable(struct sys_device *dev, |
107 | struct sysdev_attribute *attr, char *buf) | ||
107 | { | 108 | { |
108 | unsigned long start_pfn; | 109 | unsigned long start_pfn; |
109 | int ret; | 110 | int ret; |
diff --git a/drivers/char/pcmcia/ipwireless/hardware.c b/drivers/char/pcmcia/ipwireless/hardware.c index 929101ecbae2..7d500f82195a 100644 --- a/drivers/char/pcmcia/ipwireless/hardware.c +++ b/drivers/char/pcmcia/ipwireless/hardware.c | |||
@@ -30,11 +30,11 @@ | |||
30 | static void ipw_send_setup_packet(struct ipw_hardware *hw); | 30 | static void ipw_send_setup_packet(struct ipw_hardware *hw); |
31 | static void handle_received_SETUP_packet(struct ipw_hardware *ipw, | 31 | static void handle_received_SETUP_packet(struct ipw_hardware *ipw, |
32 | unsigned int address, | 32 | unsigned int address, |
33 | unsigned char *data, int len, | 33 | const unsigned char *data, int len, |
34 | int is_last); | 34 | int is_last); |
35 | static void ipwireless_setup_timer(unsigned long data); | 35 | static void ipwireless_setup_timer(unsigned long data); |
36 | static void handle_received_CTRL_packet(struct ipw_hardware *hw, | 36 | static void handle_received_CTRL_packet(struct ipw_hardware *hw, |
37 | unsigned int channel_idx, unsigned char *data, int len); | 37 | unsigned int channel_idx, const unsigned char *data, int len); |
38 | 38 | ||
39 | /*#define TIMING_DIAGNOSTICS*/ | 39 | /*#define TIMING_DIAGNOSTICS*/ |
40 | 40 | ||
@@ -79,8 +79,7 @@ static void report_timing(void) | |||
79 | timing_stats.last_report_time = jiffies; | 79 | timing_stats.last_report_time = jiffies; |
80 | if (!first) | 80 | if (!first) |
81 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME | 81 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME |
82 | ": %u us elapsed - read %lu bytes in %u us, " | 82 | ": %u us elapsed - read %lu bytes in %u us, wrote %lu bytes in %u us\n", |
83 | "wrote %lu bytes in %u us\n", | ||
84 | jiffies_to_usecs(since), | 83 | jiffies_to_usecs(since), |
85 | timing_stats.read_bytes, | 84 | timing_stats.read_bytes, |
86 | jiffies_to_usecs(timing_stats.read_time), | 85 | jiffies_to_usecs(timing_stats.read_time), |
@@ -133,29 +132,17 @@ enum { | |||
133 | #define NL_FOLLOWING_PACKET_HEADER_SIZE 1 | 132 | #define NL_FOLLOWING_PACKET_HEADER_SIZE 1 |
134 | 133 | ||
135 | struct nl_first_packet_header { | 134 | struct nl_first_packet_header { |
136 | #if defined(__BIG_ENDIAN_BITFIELD) | ||
137 | unsigned char packet_rank:2; | ||
138 | unsigned char address:3; | ||
139 | unsigned char protocol:3; | ||
140 | #else | ||
141 | unsigned char protocol:3; | 135 | unsigned char protocol:3; |
142 | unsigned char address:3; | 136 | unsigned char address:3; |
143 | unsigned char packet_rank:2; | 137 | unsigned char packet_rank:2; |
144 | #endif | ||
145 | unsigned char length_lsb; | 138 | unsigned char length_lsb; |
146 | unsigned char length_msb; | 139 | unsigned char length_msb; |
147 | }; | 140 | }; |
148 | 141 | ||
149 | struct nl_packet_header { | 142 | struct nl_packet_header { |
150 | #if defined(__BIG_ENDIAN_BITFIELD) | ||
151 | unsigned char packet_rank:2; | ||
152 | unsigned char address:3; | ||
153 | unsigned char protocol:3; | ||
154 | #else | ||
155 | unsigned char protocol:3; | 143 | unsigned char protocol:3; |
156 | unsigned char address:3; | 144 | unsigned char address:3; |
157 | unsigned char packet_rank:2; | 145 | unsigned char packet_rank:2; |
158 | #endif | ||
159 | }; | 146 | }; |
160 | 147 | ||
161 | /* Value of 'packet_rank' above */ | 148 | /* Value of 'packet_rank' above */ |
@@ -227,15 +214,12 @@ struct MEMINFREG { | |||
227 | unsigned short memreg_tx_new; /* TX2 (new) Register (R/W) */ | 214 | unsigned short memreg_tx_new; /* TX2 (new) Register (R/W) */ |
228 | }; | 215 | }; |
229 | 216 | ||
230 | #define IODMADPR 0x00 /* DMA Data Port Register (R/W) */ | ||
231 | |||
232 | #define CARD_PRESENT_VALUE (0xBEEFCAFEUL) | 217 | #define CARD_PRESENT_VALUE (0xBEEFCAFEUL) |
233 | 218 | ||
234 | #define MEMTX_TX 0x0001 | 219 | #define MEMTX_TX 0x0001 |
235 | #define MEMRX_RX 0x0001 | 220 | #define MEMRX_RX 0x0001 |
236 | #define MEMRX_RX_DONE 0x0001 | 221 | #define MEMRX_RX_DONE 0x0001 |
237 | #define MEMRX_PCINTACKK 0x0001 | 222 | #define MEMRX_PCINTACKK 0x0001 |
238 | #define MEMRX_MEMSPURIOUSINT 0x0001 | ||
239 | 223 | ||
240 | #define NL_NUM_OF_PRIORITIES 3 | 224 | #define NL_NUM_OF_PRIORITIES 3 |
241 | #define NL_NUM_OF_PROTOCOLS 3 | 225 | #define NL_NUM_OF_PROTOCOLS 3 |
@@ -245,7 +229,7 @@ struct ipw_hardware { | |||
245 | unsigned int base_port; | 229 | unsigned int base_port; |
246 | short hw_version; | 230 | short hw_version; |
247 | unsigned short ll_mtu; | 231 | unsigned short ll_mtu; |
248 | spinlock_t spinlock; | 232 | spinlock_t lock; |
249 | 233 | ||
250 | int initializing; | 234 | int initializing; |
251 | int init_loops; | 235 | int init_loops; |
@@ -386,26 +370,52 @@ static void dump_data_bytes(const char *type, const unsigned char *data, | |||
386 | length < DUMP_MAX_BYTES ? length : DUMP_MAX_BYTES); | 370 | length < DUMP_MAX_BYTES ? length : DUMP_MAX_BYTES); |
387 | } | 371 | } |
388 | 372 | ||
389 | static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data, | 373 | static void swap_packet_bitfield_to_le(unsigned char *data) |
374 | { | ||
375 | #ifdef __BIG_ENDIAN_BITFIELD | ||
376 | unsigned char tmp = *data, ret = 0; | ||
377 | |||
378 | /* | ||
379 | * transform bits from aa.bbb.ccc to ccc.bbb.aa | ||
380 | */ | ||
381 | ret |= tmp & 0xc0 >> 6; | ||
382 | ret |= tmp & 0x38 >> 1; | ||
383 | ret |= tmp & 0x07 << 5; | ||
384 | *data = ret & 0xff; | ||
385 | #endif | ||
386 | } | ||
387 | |||
388 | static void swap_packet_bitfield_from_le(unsigned char *data) | ||
389 | { | ||
390 | #ifdef __BIG_ENDIAN_BITFIELD | ||
391 | unsigned char tmp = *data, ret = 0; | ||
392 | |||
393 | /* | ||
394 | * transform bits from ccc.bbb.aa to aa.bbb.ccc | ||
395 | */ | ||
396 | ret |= tmp & 0xe0 >> 5; | ||
397 | ret |= tmp & 0x1c << 1; | ||
398 | ret |= tmp & 0x03 << 6; | ||
399 | *data = ret & 0xff; | ||
400 | #endif | ||
401 | } | ||
402 | |||
403 | static void do_send_fragment(struct ipw_hardware *hw, unsigned char *data, | ||
390 | unsigned length) | 404 | unsigned length) |
391 | { | 405 | { |
392 | int i; | 406 | unsigned i; |
393 | unsigned long flags; | 407 | unsigned long flags; |
394 | 408 | ||
395 | start_timing(); | 409 | start_timing(); |
396 | 410 | BUG_ON(length > hw->ll_mtu); | |
397 | if (length == 0) | ||
398 | return 0; | ||
399 | |||
400 | if (length > hw->ll_mtu) | ||
401 | return -1; | ||
402 | 411 | ||
403 | if (ipwireless_debug) | 412 | if (ipwireless_debug) |
404 | dump_data_bytes("send", data, length); | 413 | dump_data_bytes("send", data, length); |
405 | 414 | ||
406 | spin_lock_irqsave(&hw->spinlock, flags); | 415 | spin_lock_irqsave(&hw->lock, flags); |
407 | 416 | ||
408 | hw->tx_ready = 0; | 417 | hw->tx_ready = 0; |
418 | swap_packet_bitfield_to_le(data); | ||
409 | 419 | ||
410 | if (hw->hw_version == HW_VERSION_1) { | 420 | if (hw->hw_version == HW_VERSION_1) { |
411 | outw((unsigned short) length, hw->base_port + IODWR); | 421 | outw((unsigned short) length, hw->base_port + IODWR); |
@@ -414,7 +424,7 @@ static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data, | |||
414 | unsigned short d = data[i]; | 424 | unsigned short d = data[i]; |
415 | __le16 raw_data; | 425 | __le16 raw_data; |
416 | 426 | ||
417 | if (likely(i + 1 < length)) | 427 | if (i + 1 < length) |
418 | d |= data[i + 1] << 8; | 428 | d |= data[i + 1] << 8; |
419 | raw_data = cpu_to_le16(d); | 429 | raw_data = cpu_to_le16(d); |
420 | outw(raw_data, hw->base_port + IODWR); | 430 | outw(raw_data, hw->base_port + IODWR); |
@@ -422,32 +432,30 @@ static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data, | |||
422 | 432 | ||
423 | outw(DCR_TXDONE, hw->base_port + IODCR); | 433 | outw(DCR_TXDONE, hw->base_port + IODCR); |
424 | } else if (hw->hw_version == HW_VERSION_2) { | 434 | } else if (hw->hw_version == HW_VERSION_2) { |
425 | outw((unsigned short) length, hw->base_port + IODMADPR); | 435 | outw((unsigned short) length, hw->base_port); |
426 | 436 | ||
427 | for (i = 0; i < length; i += 2) { | 437 | for (i = 0; i < length; i += 2) { |
428 | unsigned short d = data[i]; | 438 | unsigned short d = data[i]; |
429 | __le16 raw_data; | 439 | __le16 raw_data; |
430 | 440 | ||
431 | if ((i + 1 < length)) | 441 | if (i + 1 < length) |
432 | d |= data[i + 1] << 8; | 442 | d |= data[i + 1] << 8; |
433 | raw_data = cpu_to_le16(d); | 443 | raw_data = cpu_to_le16(d); |
434 | outw(raw_data, hw->base_port + IODMADPR); | 444 | outw(raw_data, hw->base_port); |
435 | } | 445 | } |
436 | while ((i & 3) != 2) { | 446 | while ((i & 3) != 2) { |
437 | outw((unsigned short) 0xDEAD, hw->base_port + IODMADPR); | 447 | outw((unsigned short) 0xDEAD, hw->base_port); |
438 | i += 2; | 448 | i += 2; |
439 | } | 449 | } |
440 | writew(MEMRX_RX, &hw->memory_info_regs->memreg_rx); | 450 | writew(MEMRX_RX, &hw->memory_info_regs->memreg_rx); |
441 | } | 451 | } |
442 | 452 | ||
443 | spin_unlock_irqrestore(&hw->spinlock, flags); | 453 | spin_unlock_irqrestore(&hw->lock, flags); |
444 | 454 | ||
445 | end_write_timing(length); | 455 | end_write_timing(length); |
446 | |||
447 | return 0; | ||
448 | } | 456 | } |
449 | 457 | ||
450 | static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet) | 458 | static void do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet) |
451 | { | 459 | { |
452 | unsigned short fragment_data_len; | 460 | unsigned short fragment_data_len; |
453 | unsigned short data_left = packet->length - packet->offset; | 461 | unsigned short data_left = packet->length - packet->offset; |
@@ -462,6 +470,10 @@ static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet) | |||
462 | if (data_left < fragment_data_len) | 470 | if (data_left < fragment_data_len) |
463 | fragment_data_len = data_left; | 471 | fragment_data_len = data_left; |
464 | 472 | ||
473 | /* | ||
474 | * hdr_first is now in machine bitfield order, which will be swapped | ||
475 | * to le just before it goes to hw | ||
476 | */ | ||
465 | pkt.hdr_first.protocol = packet->protocol; | 477 | pkt.hdr_first.protocol = packet->protocol; |
466 | pkt.hdr_first.address = packet->dest_addr; | 478 | pkt.hdr_first.address = packet->dest_addr; |
467 | pkt.hdr_first.packet_rank = 0; | 479 | pkt.hdr_first.packet_rank = 0; |
@@ -493,25 +505,23 @@ static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet) | |||
493 | */ | 505 | */ |
494 | unsigned long flags; | 506 | unsigned long flags; |
495 | 507 | ||
496 | spin_lock_irqsave(&hw->spinlock, flags); | 508 | spin_lock_irqsave(&hw->lock, flags); |
497 | list_add(&packet->queue, &hw->tx_queue[0]); | 509 | list_add(&packet->queue, &hw->tx_queue[0]); |
498 | hw->tx_queued++; | 510 | hw->tx_queued++; |
499 | spin_unlock_irqrestore(&hw->spinlock, flags); | 511 | spin_unlock_irqrestore(&hw->lock, flags); |
500 | } else { | 512 | } else { |
501 | if (packet->packet_callback) | 513 | if (packet->packet_callback) |
502 | packet->packet_callback(packet->callback_data, | 514 | packet->packet_callback(packet->callback_data, |
503 | packet->length); | 515 | packet->length); |
504 | kfree(packet); | 516 | kfree(packet); |
505 | } | 517 | } |
506 | |||
507 | return 0; | ||
508 | } | 518 | } |
509 | 519 | ||
510 | static void ipw_setup_hardware(struct ipw_hardware *hw) | 520 | static void ipw_setup_hardware(struct ipw_hardware *hw) |
511 | { | 521 | { |
512 | unsigned long flags; | 522 | unsigned long flags; |
513 | 523 | ||
514 | spin_lock_irqsave(&hw->spinlock, flags); | 524 | spin_lock_irqsave(&hw->lock, flags); |
515 | if (hw->hw_version == HW_VERSION_1) { | 525 | if (hw->hw_version == HW_VERSION_1) { |
516 | /* Reset RX FIFO */ | 526 | /* Reset RX FIFO */ |
517 | outw(DCR_RXRESET, hw->base_port + IODCR); | 527 | outw(DCR_RXRESET, hw->base_port + IODCR); |
@@ -530,7 +540,7 @@ static void ipw_setup_hardware(struct ipw_hardware *hw) | |||
530 | csr |= 1; | 540 | csr |= 1; |
531 | writew(csr, &hw->memregs_CCR->reg_config_and_status); | 541 | writew(csr, &hw->memregs_CCR->reg_config_and_status); |
532 | } | 542 | } |
533 | spin_unlock_irqrestore(&hw->spinlock, flags); | 543 | spin_unlock_irqrestore(&hw->lock, flags); |
534 | } | 544 | } |
535 | 545 | ||
536 | /* | 546 | /* |
@@ -549,28 +559,23 @@ static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw, | |||
549 | if (!packet) { | 559 | if (!packet) { |
550 | unsigned long flags; | 560 | unsigned long flags; |
551 | 561 | ||
552 | /* | 562 | spin_lock_irqsave(&hw->lock, flags); |
553 | * If this is the first fragment, then we will need to fetch a | ||
554 | * packet to put it in. | ||
555 | */ | ||
556 | spin_lock_irqsave(&hw->spinlock, flags); | ||
557 | /* If we have one in our pool, then pull it out. */ | ||
558 | if (!list_empty(&hw->rx_pool)) { | 563 | if (!list_empty(&hw->rx_pool)) { |
559 | packet = list_first_entry(&hw->rx_pool, | 564 | packet = list_first_entry(&hw->rx_pool, |
560 | struct ipw_rx_packet, queue); | 565 | struct ipw_rx_packet, queue); |
561 | list_del(&packet->queue); | ||
562 | hw->rx_pool_size--; | 566 | hw->rx_pool_size--; |
563 | spin_unlock_irqrestore(&hw->spinlock, flags); | 567 | spin_unlock_irqrestore(&hw->lock, flags); |
568 | list_del(&packet->queue); | ||
564 | } else { | 569 | } else { |
565 | /* Otherwise allocate a new one. */ | 570 | const int min_capacity = |
566 | static int min_capacity = 256; | 571 | ipwireless_ppp_mru(hw->network + 2); |
567 | int new_capacity; | 572 | int new_capacity; |
568 | 573 | ||
569 | spin_unlock_irqrestore(&hw->spinlock, flags); | 574 | spin_unlock_irqrestore(&hw->lock, flags); |
570 | new_capacity = | 575 | new_capacity = |
571 | minimum_free_space > min_capacity | 576 | (minimum_free_space > min_capacity |
572 | ? minimum_free_space | 577 | ? minimum_free_space |
573 | : min_capacity; | 578 | : min_capacity); |
574 | packet = kmalloc(sizeof(struct ipw_rx_packet) | 579 | packet = kmalloc(sizeof(struct ipw_rx_packet) |
575 | + new_capacity, GFP_ATOMIC); | 580 | + new_capacity, GFP_ATOMIC); |
576 | if (!packet) | 581 | if (!packet) |
@@ -580,10 +585,6 @@ static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw, | |||
580 | packet->length = 0; | 585 | packet->length = 0; |
581 | } | 586 | } |
582 | 587 | ||
583 | /* | ||
584 | * If this packet does not have sufficient capacity for the data we | ||
585 | * want to add, then make it bigger. | ||
586 | */ | ||
587 | if (packet->length + minimum_free_space > packet->capacity) { | 588 | if (packet->length + minimum_free_space > packet->capacity) { |
588 | struct ipw_rx_packet *old_packet = packet; | 589 | struct ipw_rx_packet *old_packet = packet; |
589 | 590 | ||
@@ -610,13 +611,15 @@ static void pool_free(struct ipw_hardware *hw, struct ipw_rx_packet *packet) | |||
610 | kfree(packet); | 611 | kfree(packet); |
611 | else { | 612 | else { |
612 | hw->rx_pool_size++; | 613 | hw->rx_pool_size++; |
613 | list_add_tail(&packet->queue, &hw->rx_pool); | 614 | list_add(&packet->queue, &hw->rx_pool); |
614 | } | 615 | } |
615 | } | 616 | } |
616 | 617 | ||
617 | static void queue_received_packet(struct ipw_hardware *hw, | 618 | static void queue_received_packet(struct ipw_hardware *hw, |
618 | unsigned int protocol, unsigned int address, | 619 | unsigned int protocol, |
619 | unsigned char *data, int length, int is_last) | 620 | unsigned int address, |
621 | const unsigned char *data, int length, | ||
622 | int is_last) | ||
620 | { | 623 | { |
621 | unsigned int channel_idx = address - 1; | 624 | unsigned int channel_idx = address - 1; |
622 | struct ipw_rx_packet *packet = NULL; | 625 | struct ipw_rx_packet *packet = NULL; |
@@ -658,9 +661,9 @@ static void queue_received_packet(struct ipw_hardware *hw, | |||
658 | packet = *assem; | 661 | packet = *assem; |
659 | *assem = NULL; | 662 | *assem = NULL; |
660 | /* Count queued DATA bytes only */ | 663 | /* Count queued DATA bytes only */ |
661 | spin_lock_irqsave(&hw->spinlock, flags); | 664 | spin_lock_irqsave(&hw->lock, flags); |
662 | hw->rx_bytes_queued += packet->length; | 665 | hw->rx_bytes_queued += packet->length; |
663 | spin_unlock_irqrestore(&hw->spinlock, flags); | 666 | spin_unlock_irqrestore(&hw->lock, flags); |
664 | } | 667 | } |
665 | } else { | 668 | } else { |
666 | /* If it's a CTRL packet, don't assemble, just queue it. */ | 669 | /* If it's a CTRL packet, don't assemble, just queue it. */ |
@@ -682,13 +685,13 @@ static void queue_received_packet(struct ipw_hardware *hw, | |||
682 | * network layer. | 685 | * network layer. |
683 | */ | 686 | */ |
684 | if (packet) { | 687 | if (packet) { |
685 | spin_lock_irqsave(&hw->spinlock, flags); | 688 | spin_lock_irqsave(&hw->lock, flags); |
686 | list_add_tail(&packet->queue, &hw->rx_queue); | 689 | list_add_tail(&packet->queue, &hw->rx_queue); |
687 | /* Block reception of incoming packets if queue is full. */ | 690 | /* Block reception of incoming packets if queue is full. */ |
688 | hw->blocking_rx = | 691 | hw->blocking_rx = |
689 | hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE; | 692 | (hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE); |
690 | 693 | ||
691 | spin_unlock_irqrestore(&hw->spinlock, flags); | 694 | spin_unlock_irqrestore(&hw->lock, flags); |
692 | schedule_work(&hw->work_rx); | 695 | schedule_work(&hw->work_rx); |
693 | } | 696 | } |
694 | } | 697 | } |
@@ -702,7 +705,7 @@ static void ipw_receive_data_work(struct work_struct *work_rx) | |||
702 | container_of(work_rx, struct ipw_hardware, work_rx); | 705 | container_of(work_rx, struct ipw_hardware, work_rx); |
703 | unsigned long flags; | 706 | unsigned long flags; |
704 | 707 | ||
705 | spin_lock_irqsave(&hw->spinlock, flags); | 708 | spin_lock_irqsave(&hw->lock, flags); |
706 | while (!list_empty(&hw->rx_queue)) { | 709 | while (!list_empty(&hw->rx_queue)) { |
707 | struct ipw_rx_packet *packet = | 710 | struct ipw_rx_packet *packet = |
708 | list_first_entry(&hw->rx_queue, | 711 | list_first_entry(&hw->rx_queue, |
@@ -720,7 +723,7 @@ static void ipw_receive_data_work(struct work_struct *work_rx) | |||
720 | if (packet->protocol == TL_PROTOCOLID_COM_DATA) { | 723 | if (packet->protocol == TL_PROTOCOLID_COM_DATA) { |
721 | if (hw->network != NULL) { | 724 | if (hw->network != NULL) { |
722 | /* If the network hasn't been disconnected. */ | 725 | /* If the network hasn't been disconnected. */ |
723 | spin_unlock_irqrestore(&hw->spinlock, flags); | 726 | spin_unlock_irqrestore(&hw->lock, flags); |
724 | /* | 727 | /* |
725 | * This must run unlocked due to tty processing | 728 | * This must run unlocked due to tty processing |
726 | * and mutex locking | 729 | * and mutex locking |
@@ -731,7 +734,7 @@ static void ipw_receive_data_work(struct work_struct *work_rx) | |||
731 | (unsigned char *)packet | 734 | (unsigned char *)packet |
732 | + sizeof(struct ipw_rx_packet), | 735 | + sizeof(struct ipw_rx_packet), |
733 | packet->length); | 736 | packet->length); |
734 | spin_lock_irqsave(&hw->spinlock, flags); | 737 | spin_lock_irqsave(&hw->lock, flags); |
735 | } | 738 | } |
736 | /* Count queued DATA bytes only */ | 739 | /* Count queued DATA bytes only */ |
737 | hw->rx_bytes_queued -= packet->length; | 740 | hw->rx_bytes_queued -= packet->length; |
@@ -755,15 +758,15 @@ static void ipw_receive_data_work(struct work_struct *work_rx) | |||
755 | if (hw->shutting_down) | 758 | if (hw->shutting_down) |
756 | break; | 759 | break; |
757 | } | 760 | } |
758 | spin_unlock_irqrestore(&hw->spinlock, flags); | 761 | spin_unlock_irqrestore(&hw->lock, flags); |
759 | } | 762 | } |
760 | 763 | ||
761 | static void handle_received_CTRL_packet(struct ipw_hardware *hw, | 764 | static void handle_received_CTRL_packet(struct ipw_hardware *hw, |
762 | unsigned int channel_idx, | 765 | unsigned int channel_idx, |
763 | unsigned char *data, int len) | 766 | const unsigned char *data, int len) |
764 | { | 767 | { |
765 | struct ipw_control_packet_body *body = | 768 | const struct ipw_control_packet_body *body = |
766 | (struct ipw_control_packet_body *) data; | 769 | (const struct ipw_control_packet_body *) data; |
767 | unsigned int changed_mask; | 770 | unsigned int changed_mask; |
768 | 771 | ||
769 | if (len != sizeof(struct ipw_control_packet_body)) { | 772 | if (len != sizeof(struct ipw_control_packet_body)) { |
@@ -805,13 +808,13 @@ static void handle_received_CTRL_packet(struct ipw_hardware *hw, | |||
805 | } | 808 | } |
806 | 809 | ||
807 | static void handle_received_packet(struct ipw_hardware *hw, | 810 | static void handle_received_packet(struct ipw_hardware *hw, |
808 | union nl_packet *packet, | 811 | const union nl_packet *packet, |
809 | unsigned short len) | 812 | unsigned short len) |
810 | { | 813 | { |
811 | unsigned int protocol = packet->hdr.protocol; | 814 | unsigned int protocol = packet->hdr.protocol; |
812 | unsigned int address = packet->hdr.address; | 815 | unsigned int address = packet->hdr.address; |
813 | unsigned int header_length; | 816 | unsigned int header_length; |
814 | unsigned char *data; | 817 | const unsigned char *data; |
815 | unsigned int data_len; | 818 | unsigned int data_len; |
816 | int is_last = packet->hdr.packet_rank & NL_LAST_PACKET; | 819 | int is_last = packet->hdr.packet_rank & NL_LAST_PACKET; |
817 | 820 | ||
@@ -850,7 +853,7 @@ static void acknowledge_data_read(struct ipw_hardware *hw) | |||
850 | static void do_receive_packet(struct ipw_hardware *hw) | 853 | static void do_receive_packet(struct ipw_hardware *hw) |
851 | { | 854 | { |
852 | unsigned len; | 855 | unsigned len; |
853 | unsigned int i; | 856 | unsigned i; |
854 | unsigned char pkt[LL_MTU_MAX]; | 857 | unsigned char pkt[LL_MTU_MAX]; |
855 | 858 | ||
856 | start_timing(); | 859 | start_timing(); |
@@ -859,8 +862,7 @@ static void do_receive_packet(struct ipw_hardware *hw) | |||
859 | len = inw(hw->base_port + IODRR); | 862 | len = inw(hw->base_port + IODRR); |
860 | if (len > hw->ll_mtu) { | 863 | if (len > hw->ll_mtu) { |
861 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME | 864 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME |
862 | ": received a packet of %u bytes - " | 865 | ": received a packet of %u bytes - longer than the MTU!\n", len); |
863 | "longer than the MTU!\n", len); | ||
864 | outw(DCR_RXDONE | DCR_RXRESET, hw->base_port + IODCR); | 866 | outw(DCR_RXDONE | DCR_RXRESET, hw->base_port + IODCR); |
865 | return; | 867 | return; |
866 | } | 868 | } |
@@ -873,18 +875,17 @@ static void do_receive_packet(struct ipw_hardware *hw) | |||
873 | pkt[i + 1] = (unsigned char) (data >> 8); | 875 | pkt[i + 1] = (unsigned char) (data >> 8); |
874 | } | 876 | } |
875 | } else { | 877 | } else { |
876 | len = inw(hw->base_port + IODMADPR); | 878 | len = inw(hw->base_port); |
877 | if (len > hw->ll_mtu) { | 879 | if (len > hw->ll_mtu) { |
878 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME | 880 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME |
879 | ": received a packet of %u bytes - " | 881 | ": received a packet of %u bytes - longer than the MTU!\n", len); |
880 | "longer than the MTU!\n", len); | ||
881 | writew(MEMRX_PCINTACKK, | 882 | writew(MEMRX_PCINTACKK, |
882 | &hw->memory_info_regs->memreg_pc_interrupt_ack); | 883 | &hw->memory_info_regs->memreg_pc_interrupt_ack); |
883 | return; | 884 | return; |
884 | } | 885 | } |
885 | 886 | ||
886 | for (i = 0; i < len; i += 2) { | 887 | for (i = 0; i < len; i += 2) { |
887 | __le16 raw_data = inw(hw->base_port + IODMADPR); | 888 | __le16 raw_data = inw(hw->base_port); |
888 | unsigned short data = le16_to_cpu(raw_data); | 889 | unsigned short data = le16_to_cpu(raw_data); |
889 | 890 | ||
890 | pkt[i] = (unsigned char) data; | 891 | pkt[i] = (unsigned char) data; |
@@ -892,13 +893,15 @@ static void do_receive_packet(struct ipw_hardware *hw) | |||
892 | } | 893 | } |
893 | 894 | ||
894 | while ((i & 3) != 2) { | 895 | while ((i & 3) != 2) { |
895 | inw(hw->base_port + IODMADPR); | 896 | inw(hw->base_port); |
896 | i += 2; | 897 | i += 2; |
897 | } | 898 | } |
898 | } | 899 | } |
899 | 900 | ||
900 | acknowledge_data_read(hw); | 901 | acknowledge_data_read(hw); |
901 | 902 | ||
903 | swap_packet_bitfield_from_le(pkt); | ||
904 | |||
902 | if (ipwireless_debug) | 905 | if (ipwireless_debug) |
903 | dump_data_bytes("recv", pkt, len); | 906 | dump_data_bytes("recv", pkt, len); |
904 | 907 | ||
@@ -916,8 +919,7 @@ static int get_current_packet_priority(struct ipw_hardware *hw) | |||
916 | * until setup is complete. | 919 | * until setup is complete. |
917 | */ | 920 | */ |
918 | return (hw->to_setup || hw->initializing | 921 | return (hw->to_setup || hw->initializing |
919 | ? PRIO_SETUP + 1 : | 922 | ? PRIO_SETUP + 1 : NL_NUM_OF_PRIORITIES); |
920 | NL_NUM_OF_PRIORITIES); | ||
921 | } | 923 | } |
922 | 924 | ||
923 | /* | 925 | /* |
@@ -928,17 +930,17 @@ static int get_packets_from_hw(struct ipw_hardware *hw) | |||
928 | int received = 0; | 930 | int received = 0; |
929 | unsigned long flags; | 931 | unsigned long flags; |
930 | 932 | ||
931 | spin_lock_irqsave(&hw->spinlock, flags); | 933 | spin_lock_irqsave(&hw->lock, flags); |
932 | while (hw->rx_ready && !hw->blocking_rx) { | 934 | while (hw->rx_ready && !hw->blocking_rx) { |
933 | received = 1; | 935 | received = 1; |
934 | hw->rx_ready--; | 936 | hw->rx_ready--; |
935 | spin_unlock_irqrestore(&hw->spinlock, flags); | 937 | spin_unlock_irqrestore(&hw->lock, flags); |
936 | 938 | ||
937 | do_receive_packet(hw); | 939 | do_receive_packet(hw); |
938 | 940 | ||
939 | spin_lock_irqsave(&hw->spinlock, flags); | 941 | spin_lock_irqsave(&hw->lock, flags); |
940 | } | 942 | } |
941 | spin_unlock_irqrestore(&hw->spinlock, flags); | 943 | spin_unlock_irqrestore(&hw->lock, flags); |
942 | 944 | ||
943 | return received; | 945 | return received; |
944 | } | 946 | } |
@@ -954,7 +956,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) | |||
954 | int more_to_send = 0; | 956 | int more_to_send = 0; |
955 | unsigned long flags; | 957 | unsigned long flags; |
956 | 958 | ||
957 | spin_lock_irqsave(&hw->spinlock, flags); | 959 | spin_lock_irqsave(&hw->lock, flags); |
958 | if (hw->tx_queued && hw->tx_ready) { | 960 | if (hw->tx_queued && hw->tx_ready) { |
959 | int priority; | 961 | int priority; |
960 | struct ipw_tx_packet *packet = NULL; | 962 | struct ipw_tx_packet *packet = NULL; |
@@ -975,17 +977,17 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) | |||
975 | } | 977 | } |
976 | if (!packet) { | 978 | if (!packet) { |
977 | hw->tx_queued = 0; | 979 | hw->tx_queued = 0; |
978 | spin_unlock_irqrestore(&hw->spinlock, flags); | 980 | spin_unlock_irqrestore(&hw->lock, flags); |
979 | return 0; | 981 | return 0; |
980 | } | 982 | } |
981 | 983 | ||
982 | spin_unlock_irqrestore(&hw->spinlock, flags); | 984 | spin_unlock_irqrestore(&hw->lock, flags); |
983 | 985 | ||
984 | /* Send */ | 986 | /* Send */ |
985 | do_send_packet(hw, packet); | 987 | do_send_packet(hw, packet); |
986 | 988 | ||
987 | /* Check if more to send */ | 989 | /* Check if more to send */ |
988 | spin_lock_irqsave(&hw->spinlock, flags); | 990 | spin_lock_irqsave(&hw->lock, flags); |
989 | for (priority = 0; priority < priority_limit; priority++) | 991 | for (priority = 0; priority < priority_limit; priority++) |
990 | if (!list_empty(&hw->tx_queue[priority])) { | 992 | if (!list_empty(&hw->tx_queue[priority])) { |
991 | more_to_send = 1; | 993 | more_to_send = 1; |
@@ -995,7 +997,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) | |||
995 | if (!more_to_send) | 997 | if (!more_to_send) |
996 | hw->tx_queued = 0; | 998 | hw->tx_queued = 0; |
997 | } | 999 | } |
998 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1000 | spin_unlock_irqrestore(&hw->lock, flags); |
999 | 1001 | ||
1000 | return more_to_send; | 1002 | return more_to_send; |
1001 | } | 1003 | } |
@@ -1008,9 +1010,9 @@ static void ipwireless_do_tasklet(unsigned long hw_) | |||
1008 | struct ipw_hardware *hw = (struct ipw_hardware *) hw_; | 1010 | struct ipw_hardware *hw = (struct ipw_hardware *) hw_; |
1009 | unsigned long flags; | 1011 | unsigned long flags; |
1010 | 1012 | ||
1011 | spin_lock_irqsave(&hw->spinlock, flags); | 1013 | spin_lock_irqsave(&hw->lock, flags); |
1012 | if (hw->shutting_down) { | 1014 | if (hw->shutting_down) { |
1013 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1015 | spin_unlock_irqrestore(&hw->lock, flags); |
1014 | return; | 1016 | return; |
1015 | } | 1017 | } |
1016 | 1018 | ||
@@ -1019,7 +1021,7 @@ static void ipwireless_do_tasklet(unsigned long hw_) | |||
1019 | * Initial setup data sent to hardware | 1021 | * Initial setup data sent to hardware |
1020 | */ | 1022 | */ |
1021 | hw->to_setup = 2; | 1023 | hw->to_setup = 2; |
1022 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1024 | spin_unlock_irqrestore(&hw->lock, flags); |
1023 | 1025 | ||
1024 | ipw_setup_hardware(hw); | 1026 | ipw_setup_hardware(hw); |
1025 | ipw_send_setup_packet(hw); | 1027 | ipw_send_setup_packet(hw); |
@@ -1030,7 +1032,7 @@ static void ipwireless_do_tasklet(unsigned long hw_) | |||
1030 | int priority_limit = get_current_packet_priority(hw); | 1032 | int priority_limit = get_current_packet_priority(hw); |
1031 | int again; | 1033 | int again; |
1032 | 1034 | ||
1033 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1035 | spin_unlock_irqrestore(&hw->lock, flags); |
1034 | 1036 | ||
1035 | do { | 1037 | do { |
1036 | again = send_pending_packet(hw, priority_limit); | 1038 | again = send_pending_packet(hw, priority_limit); |
@@ -1068,16 +1070,16 @@ static irqreturn_t ipwireless_handle_v1_interrupt(int irq, | |||
1068 | /* Transmit complete. */ | 1070 | /* Transmit complete. */ |
1069 | if (irqn & IR_TXINTR) { | 1071 | if (irqn & IR_TXINTR) { |
1070 | ack |= IR_TXINTR; | 1072 | ack |= IR_TXINTR; |
1071 | spin_lock_irqsave(&hw->spinlock, flags); | 1073 | spin_lock_irqsave(&hw->lock, flags); |
1072 | hw->tx_ready = 1; | 1074 | hw->tx_ready = 1; |
1073 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1075 | spin_unlock_irqrestore(&hw->lock, flags); |
1074 | } | 1076 | } |
1075 | /* Received data */ | 1077 | /* Received data */ |
1076 | if (irqn & IR_RXINTR) { | 1078 | if (irqn & IR_RXINTR) { |
1077 | ack |= IR_RXINTR; | 1079 | ack |= IR_RXINTR; |
1078 | spin_lock_irqsave(&hw->spinlock, flags); | 1080 | spin_lock_irqsave(&hw->lock, flags); |
1079 | hw->rx_ready++; | 1081 | hw->rx_ready++; |
1080 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1082 | spin_unlock_irqrestore(&hw->lock, flags); |
1081 | } | 1083 | } |
1082 | if (ack != 0) { | 1084 | if (ack != 0) { |
1083 | outw(ack, hw->base_port + IOIR); | 1085 | outw(ack, hw->base_port + IOIR); |
@@ -1128,9 +1130,8 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, | |||
1128 | } else { | 1130 | } else { |
1129 | return IRQ_NONE; | 1131 | return IRQ_NONE; |
1130 | } | 1132 | } |
1131 | } else { | 1133 | } else |
1132 | return IRQ_NONE; | 1134 | return IRQ_NONE; |
1133 | } | ||
1134 | } | 1135 | } |
1135 | 1136 | ||
1136 | /* | 1137 | /* |
@@ -1149,9 +1150,9 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, | |||
1149 | if (hw->serial_number_detected) { | 1150 | if (hw->serial_number_detected) { |
1150 | if (memtx_serial != hw->last_memtx_serial) { | 1151 | if (memtx_serial != hw->last_memtx_serial) { |
1151 | hw->last_memtx_serial = memtx_serial; | 1152 | hw->last_memtx_serial = memtx_serial; |
1152 | spin_lock_irqsave(&hw->spinlock, flags); | 1153 | spin_lock_irqsave(&hw->lock, flags); |
1153 | hw->rx_ready++; | 1154 | hw->rx_ready++; |
1154 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1155 | spin_unlock_irqrestore(&hw->lock, flags); |
1155 | rx = 1; | 1156 | rx = 1; |
1156 | } else | 1157 | } else |
1157 | /* Ignore 'Timer Recovery' duplicates. */ | 1158 | /* Ignore 'Timer Recovery' duplicates. */ |
@@ -1166,18 +1167,18 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, | |||
1166 | printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME | 1167 | printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME |
1167 | ": memreg_tx serial num detected\n"); | 1168 | ": memreg_tx serial num detected\n"); |
1168 | 1169 | ||
1169 | spin_lock_irqsave(&hw->spinlock, flags); | 1170 | spin_lock_irqsave(&hw->lock, flags); |
1170 | hw->rx_ready++; | 1171 | hw->rx_ready++; |
1171 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1172 | spin_unlock_irqrestore(&hw->lock, flags); |
1172 | } | 1173 | } |
1173 | rx = 1; | 1174 | rx = 1; |
1174 | } | 1175 | } |
1175 | } | 1176 | } |
1176 | if (memrxdone & MEMRX_RX_DONE) { | 1177 | if (memrxdone & MEMRX_RX_DONE) { |
1177 | writew(0, &hw->memory_info_regs->memreg_rx_done); | 1178 | writew(0, &hw->memory_info_regs->memreg_rx_done); |
1178 | spin_lock_irqsave(&hw->spinlock, flags); | 1179 | spin_lock_irqsave(&hw->lock, flags); |
1179 | hw->tx_ready = 1; | 1180 | hw->tx_ready = 1; |
1180 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1181 | spin_unlock_irqrestore(&hw->lock, flags); |
1181 | tx = 1; | 1182 | tx = 1; |
1182 | } | 1183 | } |
1183 | if (tx) | 1184 | if (tx) |
@@ -1195,8 +1196,7 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, | |||
1195 | ": spurious interrupt - new_tx mode\n"); | 1196 | ": spurious interrupt - new_tx mode\n"); |
1196 | else { | 1197 | else { |
1197 | printk(KERN_WARNING IPWIRELESS_PCCARD_NAME | 1198 | printk(KERN_WARNING IPWIRELESS_PCCARD_NAME |
1198 | ": no valid memreg_tx value - " | 1199 | ": no valid memreg_tx value - switching to the old memreg_tx\n"); |
1199 | "switching to the old memreg_tx\n"); | ||
1200 | hw->memreg_tx = | 1200 | hw->memreg_tx = |
1201 | &hw->memory_info_regs->memreg_tx_old; | 1201 | &hw->memory_info_regs->memreg_tx_old; |
1202 | try_mem_tx_old = 1; | 1202 | try_mem_tx_old = 1; |
@@ -1211,7 +1211,7 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, | |||
1211 | return IRQ_HANDLED; | 1211 | return IRQ_HANDLED; |
1212 | } | 1212 | } |
1213 | 1213 | ||
1214 | irqreturn_t ipwireless_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 1214 | irqreturn_t ipwireless_interrupt(int irq, void *dev_id) |
1215 | { | 1215 | { |
1216 | struct ipw_hardware *hw = dev_id; | 1216 | struct ipw_hardware *hw = dev_id; |
1217 | 1217 | ||
@@ -1226,9 +1226,9 @@ static void flush_packets_to_hw(struct ipw_hardware *hw) | |||
1226 | int priority_limit; | 1226 | int priority_limit; |
1227 | unsigned long flags; | 1227 | unsigned long flags; |
1228 | 1228 | ||
1229 | spin_lock_irqsave(&hw->spinlock, flags); | 1229 | spin_lock_irqsave(&hw->lock, flags); |
1230 | priority_limit = get_current_packet_priority(hw); | 1230 | priority_limit = get_current_packet_priority(hw); |
1231 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1231 | spin_unlock_irqrestore(&hw->lock, flags); |
1232 | 1232 | ||
1233 | while (send_pending_packet(hw, priority_limit)); | 1233 | while (send_pending_packet(hw, priority_limit)); |
1234 | } | 1234 | } |
@@ -1238,10 +1238,10 @@ static void send_packet(struct ipw_hardware *hw, int priority, | |||
1238 | { | 1238 | { |
1239 | unsigned long flags; | 1239 | unsigned long flags; |
1240 | 1240 | ||
1241 | spin_lock_irqsave(&hw->spinlock, flags); | 1241 | spin_lock_irqsave(&hw->lock, flags); |
1242 | list_add_tail(&packet->queue, &hw->tx_queue[priority]); | 1242 | list_add_tail(&packet->queue, &hw->tx_queue[priority]); |
1243 | hw->tx_queued++; | 1243 | hw->tx_queued++; |
1244 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1244 | spin_unlock_irqrestore(&hw->lock, flags); |
1245 | 1245 | ||
1246 | flush_packets_to_hw(hw); | 1246 | flush_packets_to_hw(hw); |
1247 | } | 1247 | } |
@@ -1291,21 +1291,20 @@ static void *alloc_ctrl_packet(int header_size, | |||
1291 | } | 1291 | } |
1292 | 1292 | ||
1293 | int ipwireless_send_packet(struct ipw_hardware *hw, unsigned int channel_idx, | 1293 | int ipwireless_send_packet(struct ipw_hardware *hw, unsigned int channel_idx, |
1294 | unsigned char *data, unsigned int length, | 1294 | const unsigned char *data, unsigned int length, |
1295 | void (*callback) (void *cb, unsigned int length), | 1295 | void (*callback) (void *cb, unsigned int length), |
1296 | void *callback_data) | 1296 | void *callback_data) |
1297 | { | 1297 | { |
1298 | struct ipw_tx_packet *packet; | 1298 | struct ipw_tx_packet *packet; |
1299 | 1299 | ||
1300 | packet = alloc_data_packet(length, | 1300 | packet = alloc_data_packet(length, (channel_idx + 1), |
1301 | (unsigned char) (channel_idx + 1), | 1301 | TL_PROTOCOLID_COM_DATA); |
1302 | TL_PROTOCOLID_COM_DATA); | ||
1303 | if (!packet) | 1302 | if (!packet) |
1304 | return -ENOMEM; | 1303 | return -ENOMEM; |
1305 | packet->packet_callback = callback; | 1304 | packet->packet_callback = callback; |
1306 | packet->callback_data = callback_data; | 1305 | packet->callback_data = callback_data; |
1307 | memcpy((unsigned char *) packet + | 1306 | memcpy((unsigned char *) packet + sizeof(struct ipw_tx_packet), data, |
1308 | sizeof(struct ipw_tx_packet), data, length); | 1307 | length); |
1309 | 1308 | ||
1310 | send_packet(hw, PRIO_DATA, packet); | 1309 | send_packet(hw, PRIO_DATA, packet); |
1311 | return 0; | 1310 | return 0; |
@@ -1321,12 +1320,11 @@ static int set_control_line(struct ipw_hardware *hw, int prio, | |||
1321 | protocolid = TL_PROTOCOLID_SETUP; | 1320 | protocolid = TL_PROTOCOLID_SETUP; |
1322 | 1321 | ||
1323 | packet = alloc_ctrl_packet(sizeof(struct ipw_control_packet), | 1322 | packet = alloc_ctrl_packet(sizeof(struct ipw_control_packet), |
1324 | (unsigned char) (channel_idx + 1), | 1323 | (channel_idx + 1), protocolid, line); |
1325 | protocolid, line); | ||
1326 | if (!packet) | 1324 | if (!packet) |
1327 | return -ENOMEM; | 1325 | return -ENOMEM; |
1328 | packet->header.length = sizeof(struct ipw_control_packet_body); | 1326 | packet->header.length = sizeof(struct ipw_control_packet_body); |
1329 | packet->body.value = (unsigned char) (state == 0 ? 0 : 1); | 1327 | packet->body.value = (state == 0 ? 0 : 1); |
1330 | send_packet(hw, prio, &packet->header); | 1328 | send_packet(hw, prio, &packet->header); |
1331 | return 0; | 1329 | return 0; |
1332 | } | 1330 | } |
@@ -1504,8 +1502,7 @@ static void handle_setup_get_version_rsp(struct ipw_hardware *hw, | |||
1504 | if (vers_no == TL_SETUP_VERSION) | 1502 | if (vers_no == TL_SETUP_VERSION) |
1505 | __handle_setup_get_version_rsp(hw); | 1503 | __handle_setup_get_version_rsp(hw); |
1506 | else | 1504 | else |
1507 | printk(KERN_ERR | 1505 | printk(KERN_ERR IPWIRELESS_PCCARD_NAME |
1508 | IPWIRELESS_PCCARD_NAME | ||
1509 | ": invalid hardware version no %u\n", | 1506 | ": invalid hardware version no %u\n", |
1510 | (unsigned int) vers_no); | 1507 | (unsigned int) vers_no); |
1511 | } | 1508 | } |
@@ -1528,10 +1525,10 @@ static void ipw_send_setup_packet(struct ipw_hardware *hw) | |||
1528 | 1525 | ||
1529 | static void handle_received_SETUP_packet(struct ipw_hardware *hw, | 1526 | static void handle_received_SETUP_packet(struct ipw_hardware *hw, |
1530 | unsigned int address, | 1527 | unsigned int address, |
1531 | unsigned char *data, int len, | 1528 | const unsigned char *data, int len, |
1532 | int is_last) | 1529 | int is_last) |
1533 | { | 1530 | { |
1534 | union ipw_setup_rx_msg *rx_msg = (union ipw_setup_rx_msg *) data; | 1531 | const union ipw_setup_rx_msg *rx_msg = (const union ipw_setup_rx_msg *) data; |
1535 | 1532 | ||
1536 | if (address != ADDR_SETUP_PROT) { | 1533 | if (address != ADDR_SETUP_PROT) { |
1537 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME | 1534 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME |
@@ -1629,7 +1626,7 @@ struct ipw_hardware *ipwireless_hardware_create(void) | |||
1629 | 1626 | ||
1630 | INIT_LIST_HEAD(&hw->rx_queue); | 1627 | INIT_LIST_HEAD(&hw->rx_queue); |
1631 | INIT_LIST_HEAD(&hw->rx_pool); | 1628 | INIT_LIST_HEAD(&hw->rx_pool); |
1632 | spin_lock_init(&hw->spinlock); | 1629 | spin_lock_init(&hw->lock); |
1633 | tasklet_init(&hw->tasklet, ipwireless_do_tasklet, (unsigned long) hw); | 1630 | tasklet_init(&hw->tasklet, ipwireless_do_tasklet, (unsigned long) hw); |
1634 | INIT_WORK(&hw->work_rx, ipw_receive_data_work); | 1631 | INIT_WORK(&hw->work_rx, ipw_receive_data_work); |
1635 | setup_timer(&hw->setup_timer, ipwireless_setup_timer, | 1632 | setup_timer(&hw->setup_timer, ipwireless_setup_timer, |
@@ -1651,8 +1648,8 @@ void ipwireless_init_hardware_v1(struct ipw_hardware *hw, | |||
1651 | enable_irq(hw->irq); | 1648 | enable_irq(hw->irq); |
1652 | } | 1649 | } |
1653 | hw->base_port = base_port; | 1650 | hw->base_port = base_port; |
1654 | hw->hw_version = is_v2_card ? HW_VERSION_2 : HW_VERSION_1; | 1651 | hw->hw_version = (is_v2_card ? HW_VERSION_2 : HW_VERSION_1); |
1655 | hw->ll_mtu = hw->hw_version == HW_VERSION_1 ? LL_MTU_V1 : LL_MTU_V2; | 1652 | hw->ll_mtu = (hw->hw_version == HW_VERSION_1 ? LL_MTU_V1 : LL_MTU_V2); |
1656 | hw->memregs_CCR = (struct MEMCCR __iomem *) | 1653 | hw->memregs_CCR = (struct MEMCCR __iomem *) |
1657 | ((unsigned short __iomem *) attr_memory + 0x200); | 1654 | ((unsigned short __iomem *) attr_memory + 0x200); |
1658 | hw->memory_info_regs = (struct MEMINFREG __iomem *) common_memory; | 1655 | hw->memory_info_regs = (struct MEMINFREG __iomem *) common_memory; |
@@ -1695,10 +1692,10 @@ static void ipwireless_setup_timer(unsigned long data) | |||
1695 | if (is_card_present(hw)) { | 1692 | if (is_card_present(hw)) { |
1696 | unsigned long flags; | 1693 | unsigned long flags; |
1697 | 1694 | ||
1698 | spin_lock_irqsave(&hw->spinlock, flags); | 1695 | spin_lock_irqsave(&hw->lock, flags); |
1699 | hw->to_setup = 1; | 1696 | hw->to_setup = 1; |
1700 | hw->tx_ready = 1; | 1697 | hw->tx_ready = 1; |
1701 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1698 | spin_unlock_irqrestore(&hw->lock, flags); |
1702 | tasklet_schedule(&hw->tasklet); | 1699 | tasklet_schedule(&hw->tasklet); |
1703 | } | 1700 | } |
1704 | 1701 | ||
diff --git a/drivers/char/pcmcia/ipwireless/hardware.h b/drivers/char/pcmcia/ipwireless/hardware.h index 19ce5eb266b1..90a8590e43b0 100644 --- a/drivers/char/pcmcia/ipwireless/hardware.h +++ b/drivers/char/pcmcia/ipwireless/hardware.h | |||
@@ -34,14 +34,14 @@ struct ipw_network; | |||
34 | 34 | ||
35 | struct ipw_hardware *ipwireless_hardware_create(void); | 35 | struct ipw_hardware *ipwireless_hardware_create(void); |
36 | void ipwireless_hardware_free(struct ipw_hardware *hw); | 36 | void ipwireless_hardware_free(struct ipw_hardware *hw); |
37 | irqreturn_t ipwireless_interrupt(int irq, void *dev_id, struct pt_regs *regs); | 37 | irqreturn_t ipwireless_interrupt(int irq, void *dev_id); |
38 | int ipwireless_set_DTR(struct ipw_hardware *hw, unsigned int channel_idx, | 38 | int ipwireless_set_DTR(struct ipw_hardware *hw, unsigned int channel_idx, |
39 | int state); | 39 | int state); |
40 | int ipwireless_set_RTS(struct ipw_hardware *hw, unsigned int channel_idx, | 40 | int ipwireless_set_RTS(struct ipw_hardware *hw, unsigned int channel_idx, |
41 | int state); | 41 | int state); |
42 | int ipwireless_send_packet(struct ipw_hardware *hw, | 42 | int ipwireless_send_packet(struct ipw_hardware *hw, |
43 | unsigned int channel_idx, | 43 | unsigned int channel_idx, |
44 | unsigned char *data, | 44 | const unsigned char *data, |
45 | unsigned int length, | 45 | unsigned int length, |
46 | void (*packet_sent_callback) (void *cb, | 46 | void (*packet_sent_callback) (void *cb, |
47 | unsigned int length), | 47 | unsigned int length), |
diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index cc7dcea2d283..5eca7a99afe6 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c | |||
@@ -49,7 +49,7 @@ static void ipwireless_detach(struct pcmcia_device *link); | |||
49 | /* Debug mode: more verbose, print sent/recv bytes */ | 49 | /* Debug mode: more verbose, print sent/recv bytes */ |
50 | int ipwireless_debug; | 50 | int ipwireless_debug; |
51 | int ipwireless_loopback; | 51 | int ipwireless_loopback; |
52 | int ipwireless_out_queue = 1; | 52 | int ipwireless_out_queue = 10; |
53 | 53 | ||
54 | module_param_named(debug, ipwireless_debug, int, 0); | 54 | module_param_named(debug, ipwireless_debug, int, 0); |
55 | module_param_named(loopback, ipwireless_loopback, int, 0); | 55 | module_param_named(loopback, ipwireless_loopback, int, 0); |
@@ -57,7 +57,7 @@ module_param_named(out_queue, ipwireless_out_queue, int, 0); | |||
57 | MODULE_PARM_DESC(debug, "switch on debug messages [0]"); | 57 | MODULE_PARM_DESC(debug, "switch on debug messages [0]"); |
58 | MODULE_PARM_DESC(loopback, | 58 | MODULE_PARM_DESC(loopback, |
59 | "debug: enable ras_raw channel [0]"); | 59 | "debug: enable ras_raw channel [0]"); |
60 | MODULE_PARM_DESC(out_queue, "debug: set size of outgoing queue [1]"); | 60 | MODULE_PARM_DESC(out_queue, "debug: set size of outgoing PPP queue [10]"); |
61 | 61 | ||
62 | /* Executes in process context. */ | 62 | /* Executes in process context. */ |
63 | static void signalled_reboot_work(struct work_struct *work_reboot) | 63 | static void signalled_reboot_work(struct work_struct *work_reboot) |
@@ -88,8 +88,6 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
88 | unsigned short buf[64]; | 88 | unsigned short buf[64]; |
89 | cisparse_t parse; | 89 | cisparse_t parse; |
90 | unsigned short cor_value; | 90 | unsigned short cor_value; |
91 | win_req_t request_attr_memory; | ||
92 | win_req_t request_common_memory; | ||
93 | memreq_t memreq_attr_memory; | 91 | memreq_t memreq_attr_memory; |
94 | memreq_t memreq_common_memory; | 92 | memreq_t memreq_common_memory; |
95 | 93 | ||
@@ -188,6 +186,9 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
188 | goto exit0; | 186 | goto exit0; |
189 | } | 187 | } |
190 | 188 | ||
189 | request_region(link->io.BasePort1, link->io.NumPorts1, | ||
190 | IPWIRELESS_PCCARD_NAME); | ||
191 | |||
191 | /* memory settings */ | 192 | /* memory settings */ |
192 | 193 | ||
193 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 194 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
@@ -214,16 +215,16 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
214 | } | 215 | } |
215 | 216 | ||
216 | if (parse.cftable_entry.mem.nwin > 0) { | 217 | if (parse.cftable_entry.mem.nwin > 0) { |
217 | request_common_memory.Attributes = | 218 | ipw->request_common_memory.Attributes = |
218 | WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; | 219 | WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; |
219 | request_common_memory.Base = | 220 | ipw->request_common_memory.Base = |
220 | parse.cftable_entry.mem.win[0].host_addr; | 221 | parse.cftable_entry.mem.win[0].host_addr; |
221 | request_common_memory.Size = parse.cftable_entry.mem.win[0].len; | 222 | ipw->request_common_memory.Size = parse.cftable_entry.mem.win[0].len; |
222 | if (request_common_memory.Size < 0x1000) | 223 | if (ipw->request_common_memory.Size < 0x1000) |
223 | request_common_memory.Size = 0x1000; | 224 | ipw->request_common_memory.Size = 0x1000; |
224 | request_common_memory.AccessSpeed = 0; | 225 | ipw->request_common_memory.AccessSpeed = 0; |
225 | 226 | ||
226 | ret = pcmcia_request_window(&link, &request_common_memory, | 227 | ret = pcmcia_request_window(&link, &ipw->request_common_memory, |
227 | &ipw->handle_common_memory); | 228 | &ipw->handle_common_memory); |
228 | 229 | ||
229 | if (ret != CS_SUCCESS) { | 230 | if (ret != CS_SUCCESS) { |
@@ -246,16 +247,18 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
246 | ipw->is_v2_card = | 247 | ipw->is_v2_card = |
247 | parse.cftable_entry.mem.win[0].len == 0x100; | 248 | parse.cftable_entry.mem.win[0].len == 0x100; |
248 | 249 | ||
249 | ipw->common_memory = ioremap(request_common_memory.Base, | 250 | ipw->common_memory = ioremap(ipw->request_common_memory.Base, |
250 | request_common_memory.Size); | 251 | ipw->request_common_memory.Size); |
252 | request_mem_region(ipw->request_common_memory.Base, | ||
253 | ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME); | ||
251 | 254 | ||
252 | request_attr_memory.Attributes = | 255 | ipw->request_attr_memory.Attributes = |
253 | WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE; | 256 | WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE; |
254 | request_attr_memory.Base = 0; | 257 | ipw->request_attr_memory.Base = 0; |
255 | request_attr_memory.Size = 0; /* this used to be 0x1000 */ | 258 | ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */ |
256 | request_attr_memory.AccessSpeed = 0; | 259 | ipw->request_attr_memory.AccessSpeed = 0; |
257 | 260 | ||
258 | ret = pcmcia_request_window(&link, &request_attr_memory, | 261 | ret = pcmcia_request_window(&link, &ipw->request_attr_memory, |
259 | &ipw->handle_attr_memory); | 262 | &ipw->handle_attr_memory); |
260 | 263 | ||
261 | if (ret != CS_SUCCESS) { | 264 | if (ret != CS_SUCCESS) { |
@@ -274,8 +277,10 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
274 | goto exit2; | 277 | goto exit2; |
275 | } | 278 | } |
276 | 279 | ||
277 | ipw->attr_memory = ioremap(request_attr_memory.Base, | 280 | ipw->attr_memory = ioremap(ipw->request_attr_memory.Base, |
278 | request_attr_memory.Size); | 281 | ipw->request_attr_memory.Size); |
282 | request_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size, | ||
283 | IPWIRELESS_PCCARD_NAME); | ||
279 | } | 284 | } |
280 | 285 | ||
281 | INIT_WORK(&ipw->work_reboot, signalled_reboot_work); | 286 | INIT_WORK(&ipw->work_reboot, signalled_reboot_work); |
@@ -311,14 +316,13 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
311 | (unsigned int) link->irq.AssignedIRQ); | 316 | (unsigned int) link->irq.AssignedIRQ); |
312 | if (ipw->attr_memory && ipw->common_memory) | 317 | if (ipw->attr_memory && ipw->common_memory) |
313 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME | 318 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME |
314 | ": attr memory 0x%08lx-0x%08lx, " | 319 | ": attr memory 0x%08lx-0x%08lx, common memory 0x%08lx-0x%08lx\n", |
315 | "common memory 0x%08lx-0x%08lx\n", | 320 | ipw->request_attr_memory.Base, |
316 | request_attr_memory.Base, | 321 | ipw->request_attr_memory.Base |
317 | request_attr_memory.Base | 322 | + ipw->request_attr_memory.Size - 1, |
318 | + request_attr_memory.Size - 1, | 323 | ipw->request_common_memory.Base, |
319 | request_common_memory.Base, | 324 | ipw->request_common_memory.Base |
320 | request_common_memory.Base | 325 | + ipw->request_common_memory.Size - 1); |
321 | + request_common_memory.Size - 1); | ||
322 | 326 | ||
323 | ipw->network = ipwireless_network_create(ipw->hardware); | 327 | ipw->network = ipwireless_network_create(ipw->hardware); |
324 | if (!ipw->network) | 328 | if (!ipw->network) |
@@ -350,12 +354,16 @@ exit4: | |||
350 | pcmcia_disable_device(link); | 354 | pcmcia_disable_device(link); |
351 | exit3: | 355 | exit3: |
352 | if (ipw->attr_memory) { | 356 | if (ipw->attr_memory) { |
357 | release_mem_region(ipw->request_attr_memory.Base, | ||
358 | ipw->request_attr_memory.Size); | ||
353 | iounmap(ipw->attr_memory); | 359 | iounmap(ipw->attr_memory); |
354 | pcmcia_release_window(ipw->handle_attr_memory); | 360 | pcmcia_release_window(ipw->handle_attr_memory); |
355 | pcmcia_disable_device(link); | 361 | pcmcia_disable_device(link); |
356 | } | 362 | } |
357 | exit2: | 363 | exit2: |
358 | if (ipw->common_memory) { | 364 | if (ipw->common_memory) { |
365 | release_mem_region(ipw->request_common_memory.Base, | ||
366 | ipw->request_common_memory.Size); | ||
359 | iounmap(ipw->common_memory); | 367 | iounmap(ipw->common_memory); |
360 | pcmcia_release_window(ipw->handle_common_memory); | 368 | pcmcia_release_window(ipw->handle_common_memory); |
361 | } | 369 | } |
@@ -367,19 +375,25 @@ exit0: | |||
367 | 375 | ||
368 | static void release_ipwireless(struct ipw_dev *ipw) | 376 | static void release_ipwireless(struct ipw_dev *ipw) |
369 | { | 377 | { |
370 | struct pcmcia_device *link = ipw->link; | 378 | pcmcia_disable_device(ipw->link); |
371 | |||
372 | pcmcia_disable_device(link); | ||
373 | 379 | ||
374 | if (ipw->common_memory) | 380 | if (ipw->common_memory) { |
381 | release_mem_region(ipw->request_common_memory.Base, | ||
382 | ipw->request_common_memory.Size); | ||
375 | iounmap(ipw->common_memory); | 383 | iounmap(ipw->common_memory); |
376 | if (ipw->attr_memory) | 384 | } |
385 | if (ipw->attr_memory) { | ||
386 | release_mem_region(ipw->request_attr_memory.Base, | ||
387 | ipw->request_attr_memory.Size); | ||
377 | iounmap(ipw->attr_memory); | 388 | iounmap(ipw->attr_memory); |
389 | } | ||
378 | if (ipw->common_memory) | 390 | if (ipw->common_memory) |
379 | pcmcia_release_window(ipw->handle_common_memory); | 391 | pcmcia_release_window(ipw->handle_common_memory); |
380 | if (ipw->attr_memory) | 392 | if (ipw->attr_memory) |
381 | pcmcia_release_window(ipw->handle_attr_memory); | 393 | pcmcia_release_window(ipw->handle_attr_memory); |
382 | pcmcia_disable_device(link); | 394 | |
395 | /* Break the link with Card Services */ | ||
396 | pcmcia_disable_device(ipw->link); | ||
383 | } | 397 | } |
384 | 398 | ||
385 | /* | 399 | /* |
@@ -437,10 +451,6 @@ static void ipwireless_detach(struct pcmcia_device *link) | |||
437 | 451 | ||
438 | release_ipwireless(ipw); | 452 | release_ipwireless(ipw); |
439 | 453 | ||
440 | /* Break the link with Card Services */ | ||
441 | if (link) | ||
442 | pcmcia_disable_device(link); | ||
443 | |||
444 | if (ipw->tty != NULL) | 454 | if (ipw->tty != NULL) |
445 | ipwireless_tty_free(ipw->tty); | 455 | ipwireless_tty_free(ipw->tty); |
446 | if (ipw->network != NULL) | 456 | if (ipw->network != NULL) |
diff --git a/drivers/char/pcmcia/ipwireless/main.h b/drivers/char/pcmcia/ipwireless/main.h index 1bfdcc8d47d6..0e0363af9ab2 100644 --- a/drivers/char/pcmcia/ipwireless/main.h +++ b/drivers/char/pcmcia/ipwireless/main.h | |||
@@ -45,10 +45,15 @@ struct ipw_tty; | |||
45 | struct ipw_dev { | 45 | struct ipw_dev { |
46 | struct pcmcia_device *link; | 46 | struct pcmcia_device *link; |
47 | int is_v2_card; | 47 | int is_v2_card; |
48 | |||
48 | window_handle_t handle_attr_memory; | 49 | window_handle_t handle_attr_memory; |
49 | void __iomem *attr_memory; | 50 | void __iomem *attr_memory; |
51 | win_req_t request_attr_memory; | ||
52 | |||
50 | window_handle_t handle_common_memory; | 53 | window_handle_t handle_common_memory; |
51 | void __iomem *common_memory; | 54 | void __iomem *common_memory; |
55 | win_req_t request_common_memory; | ||
56 | |||
52 | dev_node_t nodes[2]; | 57 | dev_node_t nodes[2]; |
53 | /* Reference to attribute memory, containing CIS data */ | 58 | /* Reference to attribute memory, containing CIS data */ |
54 | void *attribute_memory; | 59 | void *attribute_memory; |
diff --git a/drivers/char/pcmcia/ipwireless/network.c b/drivers/char/pcmcia/ipwireless/network.c index fe914d34f7f6..590762a7f217 100644 --- a/drivers/char/pcmcia/ipwireless/network.c +++ b/drivers/char/pcmcia/ipwireless/network.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include "main.h" | 29 | #include "main.h" |
30 | #include "tty.h" | 30 | #include "tty.h" |
31 | 31 | ||
32 | #define MAX_OUTGOING_PACKETS_QUEUED ipwireless_out_queue | ||
33 | #define MAX_ASSOCIATED_TTYS 2 | 32 | #define MAX_ASSOCIATED_TTYS 2 |
34 | 33 | ||
35 | #define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP) | 34 | #define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP) |
@@ -46,7 +45,7 @@ struct ipw_network { | |||
46 | /* Number of packets queued up in hardware module. */ | 45 | /* Number of packets queued up in hardware module. */ |
47 | int outgoing_packets_queued; | 46 | int outgoing_packets_queued; |
48 | /* Spinlock to avoid interrupts during shutdown */ | 47 | /* Spinlock to avoid interrupts during shutdown */ |
49 | spinlock_t spinlock; | 48 | spinlock_t lock; |
50 | struct mutex close_lock; | 49 | struct mutex close_lock; |
51 | 50 | ||
52 | /* PPP ioctl data, not actually used anywere */ | 51 | /* PPP ioctl data, not actually used anywere */ |
@@ -68,20 +67,20 @@ static void notify_packet_sent(void *callback_data, unsigned int packet_length) | |||
68 | struct ipw_network *network = callback_data; | 67 | struct ipw_network *network = callback_data; |
69 | unsigned long flags; | 68 | unsigned long flags; |
70 | 69 | ||
71 | spin_lock_irqsave(&network->spinlock, flags); | 70 | spin_lock_irqsave(&network->lock, flags); |
72 | network->outgoing_packets_queued--; | 71 | network->outgoing_packets_queued--; |
73 | if (network->ppp_channel != NULL) { | 72 | if (network->ppp_channel != NULL) { |
74 | if (network->ppp_blocked) { | 73 | if (network->ppp_blocked) { |
75 | network->ppp_blocked = 0; | 74 | network->ppp_blocked = 0; |
76 | spin_unlock_irqrestore(&network->spinlock, flags); | 75 | spin_unlock_irqrestore(&network->lock, flags); |
77 | ppp_output_wakeup(network->ppp_channel); | 76 | ppp_output_wakeup(network->ppp_channel); |
78 | if (ipwireless_debug) | 77 | if (ipwireless_debug) |
79 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME | 78 | printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME |
80 | ": ppp unblocked\n"); | 79 | ": ppp unblocked\n"); |
81 | } else | 80 | } else |
82 | spin_unlock_irqrestore(&network->spinlock, flags); | 81 | spin_unlock_irqrestore(&network->lock, flags); |
83 | } else | 82 | } else |
84 | spin_unlock_irqrestore(&network->spinlock, flags); | 83 | spin_unlock_irqrestore(&network->lock, flags); |
85 | } | 84 | } |
86 | 85 | ||
87 | /* | 86 | /* |
@@ -93,8 +92,8 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel, | |||
93 | struct ipw_network *network = ppp_channel->private; | 92 | struct ipw_network *network = ppp_channel->private; |
94 | unsigned long flags; | 93 | unsigned long flags; |
95 | 94 | ||
96 | spin_lock_irqsave(&network->spinlock, flags); | 95 | spin_lock_irqsave(&network->lock, flags); |
97 | if (network->outgoing_packets_queued < MAX_OUTGOING_PACKETS_QUEUED) { | 96 | if (network->outgoing_packets_queued < ipwireless_out_queue) { |
98 | unsigned char *buf; | 97 | unsigned char *buf; |
99 | static unsigned char header[] = { | 98 | static unsigned char header[] = { |
100 | PPP_ALLSTATIONS, /* 0xff */ | 99 | PPP_ALLSTATIONS, /* 0xff */ |
@@ -103,7 +102,7 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel, | |||
103 | int ret; | 102 | int ret; |
104 | 103 | ||
105 | network->outgoing_packets_queued++; | 104 | network->outgoing_packets_queued++; |
106 | spin_unlock_irqrestore(&network->spinlock, flags); | 105 | spin_unlock_irqrestore(&network->lock, flags); |
107 | 106 | ||
108 | /* | 107 | /* |
109 | * If we have the requested amount of headroom in the skb we | 108 | * If we have the requested amount of headroom in the skb we |
@@ -144,7 +143,9 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel, | |||
144 | * needs to be unblocked once we are ready to send. | 143 | * needs to be unblocked once we are ready to send. |
145 | */ | 144 | */ |
146 | network->ppp_blocked = 1; | 145 | network->ppp_blocked = 1; |
147 | spin_unlock_irqrestore(&network->spinlock, flags); | 146 | spin_unlock_irqrestore(&network->lock, flags); |
147 | if (ipwireless_debug) | ||
148 | printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": ppp blocked\n"); | ||
148 | return 0; | 149 | return 0; |
149 | } | 150 | } |
150 | } | 151 | } |
@@ -249,11 +250,11 @@ static void do_go_online(struct work_struct *work_go_online) | |||
249 | work_go_online); | 250 | work_go_online); |
250 | unsigned long flags; | 251 | unsigned long flags; |
251 | 252 | ||
252 | spin_lock_irqsave(&network->spinlock, flags); | 253 | spin_lock_irqsave(&network->lock, flags); |
253 | if (!network->ppp_channel) { | 254 | if (!network->ppp_channel) { |
254 | struct ppp_channel *channel; | 255 | struct ppp_channel *channel; |
255 | 256 | ||
256 | spin_unlock_irqrestore(&network->spinlock, flags); | 257 | spin_unlock_irqrestore(&network->lock, flags); |
257 | channel = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL); | 258 | channel = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL); |
258 | if (!channel) { | 259 | if (!channel) { |
259 | printk(KERN_ERR IPWIRELESS_PCCARD_NAME | 260 | printk(KERN_ERR IPWIRELESS_PCCARD_NAME |
@@ -273,10 +274,10 @@ static void do_go_online(struct work_struct *work_go_online) | |||
273 | network->xaccm[3] = 0x60000000U; | 274 | network->xaccm[3] = 0x60000000U; |
274 | network->raccm = ~0U; | 275 | network->raccm = ~0U; |
275 | ppp_register_channel(channel); | 276 | ppp_register_channel(channel); |
276 | spin_lock_irqsave(&network->spinlock, flags); | 277 | spin_lock_irqsave(&network->lock, flags); |
277 | network->ppp_channel = channel; | 278 | network->ppp_channel = channel; |
278 | } | 279 | } |
279 | spin_unlock_irqrestore(&network->spinlock, flags); | 280 | spin_unlock_irqrestore(&network->lock, flags); |
280 | } | 281 | } |
281 | 282 | ||
282 | static void do_go_offline(struct work_struct *work_go_offline) | 283 | static void do_go_offline(struct work_struct *work_go_offline) |
@@ -287,16 +288,16 @@ static void do_go_offline(struct work_struct *work_go_offline) | |||
287 | unsigned long flags; | 288 | unsigned long flags; |
288 | 289 | ||
289 | mutex_lock(&network->close_lock); | 290 | mutex_lock(&network->close_lock); |
290 | spin_lock_irqsave(&network->spinlock, flags); | 291 | spin_lock_irqsave(&network->lock, flags); |
291 | if (network->ppp_channel != NULL) { | 292 | if (network->ppp_channel != NULL) { |
292 | struct ppp_channel *channel = network->ppp_channel; | 293 | struct ppp_channel *channel = network->ppp_channel; |
293 | 294 | ||
294 | network->ppp_channel = NULL; | 295 | network->ppp_channel = NULL; |
295 | spin_unlock_irqrestore(&network->spinlock, flags); | 296 | spin_unlock_irqrestore(&network->lock, flags); |
296 | mutex_unlock(&network->close_lock); | 297 | mutex_unlock(&network->close_lock); |
297 | ppp_unregister_channel(channel); | 298 | ppp_unregister_channel(channel); |
298 | } else { | 299 | } else { |
299 | spin_unlock_irqrestore(&network->spinlock, flags); | 300 | spin_unlock_irqrestore(&network->lock, flags); |
300 | mutex_unlock(&network->close_lock); | 301 | mutex_unlock(&network->close_lock); |
301 | } | 302 | } |
302 | } | 303 | } |
@@ -381,18 +382,18 @@ void ipwireless_network_packet_received(struct ipw_network *network, | |||
381 | * the PPP layer. | 382 | * the PPP layer. |
382 | */ | 383 | */ |
383 | mutex_lock(&network->close_lock); | 384 | mutex_lock(&network->close_lock); |
384 | spin_lock_irqsave(&network->spinlock, flags); | 385 | spin_lock_irqsave(&network->lock, flags); |
385 | if (network->ppp_channel != NULL) { | 386 | if (network->ppp_channel != NULL) { |
386 | struct sk_buff *skb; | 387 | struct sk_buff *skb; |
387 | 388 | ||
388 | spin_unlock_irqrestore(&network->spinlock, | 389 | spin_unlock_irqrestore(&network->lock, |
389 | flags); | 390 | flags); |
390 | 391 | ||
391 | /* Send the data to the ppp_generic module. */ | 392 | /* Send the data to the ppp_generic module. */ |
392 | skb = ipw_packet_received_skb(data, length); | 393 | skb = ipw_packet_received_skb(data, length); |
393 | ppp_input(network->ppp_channel, skb); | 394 | ppp_input(network->ppp_channel, skb); |
394 | } else | 395 | } else |
395 | spin_unlock_irqrestore(&network->spinlock, | 396 | spin_unlock_irqrestore(&network->lock, |
396 | flags); | 397 | flags); |
397 | mutex_unlock(&network->close_lock); | 398 | mutex_unlock(&network->close_lock); |
398 | } | 399 | } |
@@ -410,7 +411,7 @@ struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw) | |||
410 | if (!network) | 411 | if (!network) |
411 | return NULL; | 412 | return NULL; |
412 | 413 | ||
413 | spin_lock_init(&network->spinlock); | 414 | spin_lock_init(&network->lock); |
414 | mutex_init(&network->close_lock); | 415 | mutex_init(&network->close_lock); |
415 | 416 | ||
416 | network->hardware = hw; | 417 | network->hardware = hw; |
@@ -478,10 +479,10 @@ int ipwireless_ppp_channel_index(struct ipw_network *network) | |||
478 | int ret = -1; | 479 | int ret = -1; |
479 | unsigned long flags; | 480 | unsigned long flags; |
480 | 481 | ||
481 | spin_lock_irqsave(&network->spinlock, flags); | 482 | spin_lock_irqsave(&network->lock, flags); |
482 | if (network->ppp_channel != NULL) | 483 | if (network->ppp_channel != NULL) |
483 | ret = ppp_channel_index(network->ppp_channel); | 484 | ret = ppp_channel_index(network->ppp_channel); |
484 | spin_unlock_irqrestore(&network->spinlock, flags); | 485 | spin_unlock_irqrestore(&network->lock, flags); |
485 | 486 | ||
486 | return ret; | 487 | return ret; |
487 | } | 488 | } |
@@ -491,10 +492,15 @@ int ipwireless_ppp_unit_number(struct ipw_network *network) | |||
491 | int ret = -1; | 492 | int ret = -1; |
492 | unsigned long flags; | 493 | unsigned long flags; |
493 | 494 | ||
494 | spin_lock_irqsave(&network->spinlock, flags); | 495 | spin_lock_irqsave(&network->lock, flags); |
495 | if (network->ppp_channel != NULL) | 496 | if (network->ppp_channel != NULL) |
496 | ret = ppp_unit_number(network->ppp_channel); | 497 | ret = ppp_unit_number(network->ppp_channel); |
497 | spin_unlock_irqrestore(&network->spinlock, flags); | 498 | spin_unlock_irqrestore(&network->lock, flags); |
498 | 499 | ||
499 | return ret; | 500 | return ret; |
500 | } | 501 | } |
502 | |||
503 | int ipwireless_ppp_mru(const struct ipw_network *network) | ||
504 | { | ||
505 | return network->mru; | ||
506 | } | ||
diff --git a/drivers/char/pcmcia/ipwireless/network.h b/drivers/char/pcmcia/ipwireless/network.h index ccacd26fc7ef..561f765b3334 100644 --- a/drivers/char/pcmcia/ipwireless/network.h +++ b/drivers/char/pcmcia/ipwireless/network.h | |||
@@ -48,5 +48,6 @@ void ipwireless_ppp_open(struct ipw_network *net); | |||
48 | void ipwireless_ppp_close(struct ipw_network *net); | 48 | void ipwireless_ppp_close(struct ipw_network *net); |
49 | int ipwireless_ppp_channel_index(struct ipw_network *net); | 49 | int ipwireless_ppp_channel_index(struct ipw_network *net); |
50 | int ipwireless_ppp_unit_number(struct ipw_network *net); | 50 | int ipwireless_ppp_unit_number(struct ipw_network *net); |
51 | int ipwireless_ppp_mru(const struct ipw_network *net); | ||
51 | 52 | ||
52 | #endif | 53 | #endif |
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index 42f3815c5ce3..b1414507997c 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c | |||
@@ -259,7 +259,7 @@ static int ipw_write(struct tty_struct *linux_tty, | |||
259 | } | 259 | } |
260 | 260 | ||
261 | ret = ipwireless_send_packet(tty->hardware, IPW_CHANNEL_RAS, | 261 | ret = ipwireless_send_packet(tty->hardware, IPW_CHANNEL_RAS, |
262 | (unsigned char *) buf, count, | 262 | buf, count, |
263 | ipw_write_packet_sent_callback, tty); | 263 | ipw_write_packet_sent_callback, tty); |
264 | if (ret == -1) { | 264 | if (ret == -1) { |
265 | mutex_unlock(&tty->ipw_tty_mutex); | 265 | mutex_unlock(&tty->ipw_tty_mutex); |
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 5405769020a1..5ce07b517c58 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -94,7 +94,7 @@ void cpuidle_install_idle_handler(void) | |||
94 | */ | 94 | */ |
95 | void cpuidle_uninstall_idle_handler(void) | 95 | void cpuidle_uninstall_idle_handler(void) |
96 | { | 96 | { |
97 | if (enabled_devices && (pm_idle != pm_idle_old)) { | 97 | if (enabled_devices && pm_idle_old && (pm_idle != pm_idle_old)) { |
98 | pm_idle = pm_idle_old; | 98 | pm_idle = pm_idle_old; |
99 | cpuidle_kick_cpus(); | 99 | cpuidle_kick_cpus(); |
100 | } | 100 | } |
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index 48d084bdf7c8..3c855ff2992f 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c | |||
@@ -49,6 +49,8 @@ struct bfin_twi_iface { | |||
49 | struct i2c_msg *pmsg; | 49 | struct i2c_msg *pmsg; |
50 | int msg_num; | 50 | int msg_num; |
51 | int cur_msg; | 51 | int cur_msg; |
52 | u16 saved_clkdiv; | ||
53 | u16 saved_control; | ||
52 | void __iomem *regs_base; | 54 | void __iomem *regs_base; |
53 | }; | 55 | }; |
54 | 56 | ||
@@ -565,32 +567,43 @@ static u32 bfin_twi_functionality(struct i2c_adapter *adap) | |||
565 | I2C_FUNC_I2C; | 567 | I2C_FUNC_I2C; |
566 | } | 568 | } |
567 | 569 | ||
568 | |||
569 | static struct i2c_algorithm bfin_twi_algorithm = { | 570 | static struct i2c_algorithm bfin_twi_algorithm = { |
570 | .master_xfer = bfin_twi_master_xfer, | 571 | .master_xfer = bfin_twi_master_xfer, |
571 | .smbus_xfer = bfin_twi_smbus_xfer, | 572 | .smbus_xfer = bfin_twi_smbus_xfer, |
572 | .functionality = bfin_twi_functionality, | 573 | .functionality = bfin_twi_functionality, |
573 | }; | 574 | }; |
574 | 575 | ||
575 | 576 | static int i2c_bfin_twi_suspend(struct platform_device *pdev, pm_message_t state) | |
576 | static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state) | ||
577 | { | 577 | { |
578 | struct bfin_twi_iface *iface = platform_get_drvdata(dev); | 578 | struct bfin_twi_iface *iface = platform_get_drvdata(pdev); |
579 | |||
580 | iface->saved_clkdiv = read_CLKDIV(iface); | ||
581 | iface->saved_control = read_CONTROL(iface); | ||
582 | |||
583 | free_irq(iface->irq, iface); | ||
579 | 584 | ||
580 | /* Disable TWI */ | 585 | /* Disable TWI */ |
581 | write_CONTROL(iface, read_CONTROL(iface) & ~TWI_ENA); | 586 | write_CONTROL(iface, iface->saved_control & ~TWI_ENA); |
582 | SSYNC(); | ||
583 | 587 | ||
584 | return 0; | 588 | return 0; |
585 | } | 589 | } |
586 | 590 | ||
587 | static int i2c_bfin_twi_resume(struct platform_device *dev) | 591 | static int i2c_bfin_twi_resume(struct platform_device *pdev) |
588 | { | 592 | { |
589 | struct bfin_twi_iface *iface = platform_get_drvdata(dev); | 593 | struct bfin_twi_iface *iface = platform_get_drvdata(pdev); |
590 | 594 | ||
591 | /* Enable TWI */ | 595 | int rc = request_irq(iface->irq, bfin_twi_interrupt_entry, |
592 | write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA); | 596 | IRQF_DISABLED, pdev->name, iface); |
593 | SSYNC(); | 597 | if (rc) { |
598 | dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq); | ||
599 | return -ENODEV; | ||
600 | } | ||
601 | |||
602 | /* Resume TWI interface clock as specified */ | ||
603 | write_CLKDIV(iface, iface->saved_clkdiv); | ||
604 | |||
605 | /* Resume TWI */ | ||
606 | write_CONTROL(iface, iface->saved_control); | ||
594 | 607 | ||
595 | return 0; | 608 | return 0; |
596 | } | 609 | } |
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index 79b455a1f090..32104eac8d3d 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c | |||
@@ -77,7 +77,7 @@ static int i2c_gpio_getscl(void *data) | |||
77 | return gpio_get_value(pdata->scl_pin); | 77 | return gpio_get_value(pdata->scl_pin); |
78 | } | 78 | } |
79 | 79 | ||
80 | static int __init i2c_gpio_probe(struct platform_device *pdev) | 80 | static int __devinit i2c_gpio_probe(struct platform_device *pdev) |
81 | { | 81 | { |
82 | struct i2c_gpio_platform_data *pdata; | 82 | struct i2c_gpio_platform_data *pdata; |
83 | struct i2c_algo_bit_data *bit_data; | 83 | struct i2c_algo_bit_data *bit_data; |
@@ -174,7 +174,7 @@ err_alloc_adap: | |||
174 | return ret; | 174 | return ret; |
175 | } | 175 | } |
176 | 176 | ||
177 | static int __exit i2c_gpio_remove(struct platform_device *pdev) | 177 | static int __devexit i2c_gpio_remove(struct platform_device *pdev) |
178 | { | 178 | { |
179 | struct i2c_gpio_platform_data *pdata; | 179 | struct i2c_gpio_platform_data *pdata; |
180 | struct i2c_adapter *adap; | 180 | struct i2c_adapter *adap; |
@@ -196,14 +196,15 @@ static struct platform_driver i2c_gpio_driver = { | |||
196 | .name = "i2c-gpio", | 196 | .name = "i2c-gpio", |
197 | .owner = THIS_MODULE, | 197 | .owner = THIS_MODULE, |
198 | }, | 198 | }, |
199 | .remove = __exit_p(i2c_gpio_remove), | 199 | .probe = i2c_gpio_probe, |
200 | .remove = __devexit_p(i2c_gpio_remove), | ||
200 | }; | 201 | }; |
201 | 202 | ||
202 | static int __init i2c_gpio_init(void) | 203 | static int __init i2c_gpio_init(void) |
203 | { | 204 | { |
204 | int ret; | 205 | int ret; |
205 | 206 | ||
206 | ret = platform_driver_probe(&i2c_gpio_driver, i2c_gpio_probe); | 207 | ret = platform_driver_register(&i2c_gpio_driver); |
207 | if (ret) | 208 | if (ret) |
208 | printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret); | 209 | printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret); |
209 | 210 | ||
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 007390ad9810..4864723c7425 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/err.h> | 33 | #include <linux/err.h> |
34 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
35 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
36 | #include <linux/cpufreq.h> | ||
36 | 37 | ||
37 | #include <asm/hardware.h> | 38 | #include <asm/hardware.h> |
38 | #include <asm/irq.h> | 39 | #include <asm/irq.h> |
@@ -64,6 +65,7 @@ struct s3c24xx_i2c { | |||
64 | unsigned int tx_setup; | 65 | unsigned int tx_setup; |
65 | 66 | ||
66 | enum s3c24xx_i2c_state state; | 67 | enum s3c24xx_i2c_state state; |
68 | unsigned long clkrate; | ||
67 | 69 | ||
68 | void __iomem *regs; | 70 | void __iomem *regs; |
69 | struct clk *clk; | 71 | struct clk *clk; |
@@ -71,6 +73,10 @@ struct s3c24xx_i2c { | |||
71 | struct resource *irq; | 73 | struct resource *irq; |
72 | struct resource *ioarea; | 74 | struct resource *ioarea; |
73 | struct i2c_adapter adap; | 75 | struct i2c_adapter adap; |
76 | |||
77 | #ifdef CONFIG_CPU_FREQ | ||
78 | struct notifier_block freq_transition; | ||
79 | #endif | ||
74 | }; | 80 | }; |
75 | 81 | ||
76 | /* default platform data to use if not supplied in the platform_device | 82 | /* default platform data to use if not supplied in the platform_device |
@@ -501,6 +507,9 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg *msgs, int | |||
501 | unsigned long timeout; | 507 | unsigned long timeout; |
502 | int ret; | 508 | int ret; |
503 | 509 | ||
510 | if (!readl(i2c->regs + S3C2410_IICCON) & S3C2410_IICCON_IRQEN) | ||
511 | return -EIO; | ||
512 | |||
504 | ret = s3c24xx_i2c_set_master(i2c); | 513 | ret = s3c24xx_i2c_set_master(i2c); |
505 | if (ret != 0) { | 514 | if (ret != 0) { |
506 | dev_err(i2c->dev, "cannot get bus (error %d)\n", ret); | 515 | dev_err(i2c->dev, "cannot get bus (error %d)\n", ret); |
@@ -636,27 +645,28 @@ static inline int freq_acceptable(unsigned int freq, unsigned int wanted) | |||
636 | return (diff >= -2 && diff <= 2); | 645 | return (diff >= -2 && diff <= 2); |
637 | } | 646 | } |
638 | 647 | ||
639 | /* s3c24xx_i2c_getdivisor | 648 | /* s3c24xx_i2c_clockrate |
640 | * | 649 | * |
641 | * work out a divisor for the user requested frequency setting, | 650 | * work out a divisor for the user requested frequency setting, |
642 | * either by the requested frequency, or scanning the acceptable | 651 | * either by the requested frequency, or scanning the acceptable |
643 | * range of frequencies until something is found | 652 | * range of frequencies until something is found |
644 | */ | 653 | */ |
645 | 654 | ||
646 | static int s3c24xx_i2c_getdivisor(struct s3c24xx_i2c *i2c, | 655 | static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got) |
647 | struct s3c2410_platform_i2c *pdata, | ||
648 | unsigned long *iicon, | ||
649 | unsigned int *got) | ||
650 | { | 656 | { |
657 | struct s3c2410_platform_i2c *pdata; | ||
651 | unsigned long clkin = clk_get_rate(i2c->clk); | 658 | unsigned long clkin = clk_get_rate(i2c->clk); |
652 | |||
653 | unsigned int divs, div1; | 659 | unsigned int divs, div1; |
660 | u32 iiccon; | ||
654 | int freq; | 661 | int freq; |
655 | int start, end; | 662 | int start, end; |
656 | 663 | ||
664 | i2c->clkrate = clkin; | ||
665 | |||
666 | pdata = s3c24xx_i2c_get_platformdata(i2c->adap.dev.parent); | ||
657 | clkin /= 1000; /* clkin now in KHz */ | 667 | clkin /= 1000; /* clkin now in KHz */ |
658 | 668 | ||
659 | dev_dbg(i2c->dev, "pdata %p, freq %lu %lu..%lu\n", | 669 | dev_dbg(i2c->dev, "pdata %p, freq %lu %lu..%lu\n", |
660 | pdata, pdata->bus_freq, pdata->min_freq, pdata->max_freq); | 670 | pdata, pdata->bus_freq, pdata->min_freq, pdata->max_freq); |
661 | 671 | ||
662 | if (pdata->bus_freq != 0) { | 672 | if (pdata->bus_freq != 0) { |
@@ -688,11 +698,79 @@ static int s3c24xx_i2c_getdivisor(struct s3c24xx_i2c *i2c, | |||
688 | 698 | ||
689 | found: | 699 | found: |
690 | *got = freq; | 700 | *got = freq; |
691 | *iicon |= (divs-1); | 701 | |
692 | *iicon |= (div1 == 512) ? S3C2410_IICCON_TXDIV_512 : 0; | 702 | iiccon = readl(i2c->regs + S3C2410_IICCON); |
703 | iiccon &= ~(S3C2410_IICCON_SCALEMASK | S3C2410_IICCON_TXDIV_512); | ||
704 | iiccon |= (divs-1); | ||
705 | |||
706 | if (div1 == 512) | ||
707 | iiccon |= S3C2410_IICCON_TXDIV_512; | ||
708 | |||
709 | writel(iiccon, i2c->regs + S3C2410_IICCON); | ||
710 | |||
711 | return 0; | ||
712 | } | ||
713 | |||
714 | #ifdef CONFIG_CPU_FREQ | ||
715 | |||
716 | #define freq_to_i2c(_n) container_of(_n, struct s3c24xx_i2c, freq_transition) | ||
717 | |||
718 | static int s3c24xx_i2c_cpufreq_transition(struct notifier_block *nb, | ||
719 | unsigned long val, void *data) | ||
720 | { | ||
721 | struct s3c24xx_i2c *i2c = freq_to_i2c(nb); | ||
722 | unsigned long flags; | ||
723 | unsigned int got; | ||
724 | int delta_f; | ||
725 | int ret; | ||
726 | |||
727 | delta_f = clk_get_rate(i2c->clk) - i2c->clkrate; | ||
728 | |||
729 | /* if we're post-change and the input clock has slowed down | ||
730 | * or at pre-change and the clock is about to speed up, then | ||
731 | * adjust our clock rate. <0 is slow, >0 speedup. | ||
732 | */ | ||
733 | |||
734 | if ((val == CPUFREQ_POSTCHANGE && delta_f < 0) || | ||
735 | (val == CPUFREQ_PRECHANGE && delta_f > 0)) { | ||
736 | spin_lock_irqsave(&i2c->lock, flags); | ||
737 | ret = s3c24xx_i2c_clockrate(i2c, &got); | ||
738 | spin_unlock_irqrestore(&i2c->lock, flags); | ||
739 | |||
740 | if (ret < 0) | ||
741 | dev_err(i2c->dev, "cannot find frequency\n"); | ||
742 | else | ||
743 | dev_info(i2c->dev, "setting freq %d\n", got); | ||
744 | } | ||
745 | |||
746 | return 0; | ||
747 | } | ||
748 | |||
749 | static inline int s3c24xx_i2c_register_cpufreq(struct s3c24xx_i2c *i2c) | ||
750 | { | ||
751 | i2c->freq_transition.notifier_call = s3c24xx_i2c_cpufreq_transition; | ||
752 | |||
753 | return cpufreq_register_notifier(&i2c->freq_transition, | ||
754 | CPUFREQ_TRANSITION_NOTIFIER); | ||
755 | } | ||
756 | |||
757 | static inline void s3c24xx_i2c_deregister_cpufreq(struct s3c24xx_i2c *i2c) | ||
758 | { | ||
759 | cpufreq_unregister_notifier(&i2c->freq_transition, | ||
760 | CPUFREQ_TRANSITION_NOTIFIER); | ||
761 | } | ||
762 | |||
763 | #else | ||
764 | static inline int s3c24xx_i2c_register_cpufreq(struct s3c24xx_i2c *i2c) | ||
765 | { | ||
693 | return 0; | 766 | return 0; |
694 | } | 767 | } |
695 | 768 | ||
769 | static inline void s3c24xx_i2c_deregister_cpufreq(struct s3c24xx_i2c *i2c) | ||
770 | { | ||
771 | } | ||
772 | #endif | ||
773 | |||
696 | /* s3c24xx_i2c_init | 774 | /* s3c24xx_i2c_init |
697 | * | 775 | * |
698 | * initialise the controller, set the IO lines and frequency | 776 | * initialise the controller, set the IO lines and frequency |
@@ -719,9 +797,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c) | |||
719 | 797 | ||
720 | dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr); | 798 | dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr); |
721 | 799 | ||
800 | writel(iicon, i2c->regs + S3C2410_IICCON); | ||
801 | |||
722 | /* we need to work out the divisors for the clock... */ | 802 | /* we need to work out the divisors for the clock... */ |
723 | 803 | ||
724 | if (s3c24xx_i2c_getdivisor(i2c, pdata, &iicon, &freq) != 0) { | 804 | if (s3c24xx_i2c_clockrate(i2c, &freq) != 0) { |
805 | writel(0, i2c->regs + S3C2410_IICCON); | ||
725 | dev_err(i2c->dev, "cannot meet bus frequency required\n"); | 806 | dev_err(i2c->dev, "cannot meet bus frequency required\n"); |
726 | return -EINVAL; | 807 | return -EINVAL; |
727 | } | 808 | } |
@@ -730,8 +811,6 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c) | |||
730 | 811 | ||
731 | dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq); | 812 | dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq); |
732 | dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon); | 813 | dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon); |
733 | |||
734 | writel(iicon, i2c->regs + S3C2410_IICCON); | ||
735 | 814 | ||
736 | /* check for s3c2440 i2c controller */ | 815 | /* check for s3c2440 i2c controller */ |
737 | 816 | ||
@@ -752,9 +831,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c) | |||
752 | static int s3c24xx_i2c_probe(struct platform_device *pdev) | 831 | static int s3c24xx_i2c_probe(struct platform_device *pdev) |
753 | { | 832 | { |
754 | struct s3c24xx_i2c *i2c = &s3c24xx_i2c; | 833 | struct s3c24xx_i2c *i2c = &s3c24xx_i2c; |
834 | struct s3c2410_platform_i2c *pdata; | ||
755 | struct resource *res; | 835 | struct resource *res; |
756 | int ret; | 836 | int ret; |
757 | 837 | ||
838 | pdata = s3c24xx_i2c_get_platformdata(&pdev->dev); | ||
839 | |||
758 | /* find the clock and enable it */ | 840 | /* find the clock and enable it */ |
759 | 841 | ||
760 | i2c->dev = &pdev->dev; | 842 | i2c->dev = &pdev->dev; |
@@ -832,17 +914,34 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) | |||
832 | dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res, | 914 | dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res, |
833 | (unsigned long)res->start); | 915 | (unsigned long)res->start); |
834 | 916 | ||
835 | ret = i2c_add_adapter(&i2c->adap); | 917 | ret = s3c24xx_i2c_register_cpufreq(i2c); |
836 | if (ret < 0) { | 918 | if (ret < 0) { |
837 | dev_err(&pdev->dev, "failed to add bus to i2c core\n"); | 919 | dev_err(&pdev->dev, "failed to register cpufreq notifier\n"); |
838 | goto err_irq; | 920 | goto err_irq; |
839 | } | 921 | } |
840 | 922 | ||
923 | /* Note, previous versions of the driver used i2c_add_adapter() | ||
924 | * to add the bus at any number. We now pass the bus number via | ||
925 | * the platform data, so if unset it will now default to always | ||
926 | * being bus 0. | ||
927 | */ | ||
928 | |||
929 | i2c->adap.nr = pdata->bus_num; | ||
930 | |||
931 | ret = i2c_add_numbered_adapter(&i2c->adap); | ||
932 | if (ret < 0) { | ||
933 | dev_err(&pdev->dev, "failed to add bus to i2c core\n"); | ||
934 | goto err_cpufreq; | ||
935 | } | ||
936 | |||
841 | platform_set_drvdata(pdev, i2c); | 937 | platform_set_drvdata(pdev, i2c); |
842 | 938 | ||
843 | dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id); | 939 | dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id); |
844 | return 0; | 940 | return 0; |
845 | 941 | ||
942 | err_cpufreq: | ||
943 | s3c24xx_i2c_deregister_cpufreq(i2c); | ||
944 | |||
846 | err_irq: | 945 | err_irq: |
847 | free_irq(i2c->irq->start, i2c); | 946 | free_irq(i2c->irq->start, i2c); |
848 | 947 | ||
@@ -870,6 +969,8 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev) | |||
870 | { | 969 | { |
871 | struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); | 970 | struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); |
872 | 971 | ||
972 | s3c24xx_i2c_deregister_cpufreq(i2c); | ||
973 | |||
873 | i2c_del_adapter(&i2c->adap); | 974 | i2c_del_adapter(&i2c->adap); |
874 | free_irq(i2c->irq->start, i2c); | 975 | free_irq(i2c->irq->start, i2c); |
875 | 976 | ||