aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-23 11:28:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-23 11:28:25 -0400
commit9bf9b2f3ad6362cdc9ef79291d440a92960b8f51 (patch)
treec50a317a619096a6ec84c243fafef50388004df6 /drivers
parent9779a8325a9bbf4ccd3853e0e4064984cf9da9c9 (diff)
parent54622f10a6aabb8bb2bdacf3dd070046f03dc246 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (53 commits) powerpc: Support for relocatable kdump kernel powerpc: Don't use a 16G page if beyond mem= limits powerpc: Add del_node() for early boot code to prune inapplicable devices. powerpc: Further compile fixup for STRICT_MM_TYPECHECKS powerpc: Remove empty #else from signal_64.c powerpc: Move memory size print into common show_cpuinfo for 32-bit hvc_console: Remove __devexit annotation of hvc_remove() hvc_console: Add support for tty window resizing hvc_console: Fix loop if put_char() returns 0 hvc_console: Add tty driver flag TTY_DRIVER_RESET_TERMIOS hvc_console: Add a hangup notifier for backends powerpc/83xx: Add DS1339 RTC support for MPC8349E-mITX boards .dts powerpc/83xx: Add support for MCU microcontroller in .dts files powerpc/85xx: Move mpc8572ds.dts to address-cells/size-cells = <2> of/spi: Support specifying chip select as active high via device tree powerpc: Remove device_type = "board_control" properties in .dts files i2c-cpm: Suppress autoprobing for devices powerpc/85xx: Fix mpc8536ds dma interrupt numbers powerpc/85xx: Enable enhanced functions for 8536 TSEC powerpc: Delete unused prom_strtoul and prom_memparse ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/hvc_console.c86
-rw-r--r--drivers/char/hvc_console.h12
-rw-r--r--drivers/char/hvc_irq.c5
-rw-r--r--drivers/char/hvc_iseries.c1
-rw-r--r--drivers/char/hvc_vio.c1
-rw-r--r--drivers/char/hvc_xen.c1
-rw-r--r--drivers/char/virtio_console.c1
-rw-r--r--drivers/i2c/busses/i2c-cpm.c1
-rw-r--r--drivers/net/fec_mpc52xx_phy.c55
-rw-r--r--drivers/net/ibm_newemac/core.c10
-rw-r--r--drivers/net/ibm_newemac/mal.c15
-rw-r--r--drivers/of/of_i2c.c2
-rw-r--r--drivers/of/of_spi.c2
-rw-r--r--drivers/oprofile/buffer_sync.c24
-rw-r--r--drivers/oprofile/cpu_buffer.c15
-rw-r--r--drivers/oprofile/event_buffer.h7
16 files changed, 185 insertions, 53 deletions
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index bf70450a49cc..5b819b12675a 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -161,7 +161,7 @@ static void hvc_console_print(struct console *co, const char *b,
161 } 161 }
162 } else { 162 } else {
163 r = cons_ops[index]->put_chars(vtermnos[index], c, i); 163 r = cons_ops[index]->put_chars(vtermnos[index], c, i);
164 if (r < 0) { 164 if (r <= 0) {
165 /* throw away chars on error */ 165 /* throw away chars on error */
166 i = 0; 166 i = 0;
167 } else if (r > 0) { 167 } else if (r > 0) {
@@ -374,6 +374,9 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
374 if (hp->ops->notifier_del) 374 if (hp->ops->notifier_del)
375 hp->ops->notifier_del(hp, hp->data); 375 hp->ops->notifier_del(hp, hp->data);
376 376
377 /* cancel pending tty resize work */
378 cancel_work_sync(&hp->tty_resize);
379
377 /* 380 /*
378 * Chain calls chars_in_buffer() and returns immediately if 381 * Chain calls chars_in_buffer() and returns immediately if
379 * there is no buffered data otherwise sleeps on a wait queue 382 * there is no buffered data otherwise sleeps on a wait queue
@@ -399,6 +402,9 @@ static void hvc_hangup(struct tty_struct *tty)
399 if (!hp) 402 if (!hp)
400 return; 403 return;
401 404
405 /* cancel pending tty resize work */
406 cancel_work_sync(&hp->tty_resize);
407
402 spin_lock_irqsave(&hp->lock, flags); 408 spin_lock_irqsave(&hp->lock, flags);
403 409
404 /* 410 /*
@@ -418,8 +424,8 @@ static void hvc_hangup(struct tty_struct *tty)
418 424
419 spin_unlock_irqrestore(&hp->lock, flags); 425 spin_unlock_irqrestore(&hp->lock, flags);
420 426
421 if (hp->ops->notifier_del) 427 if (hp->ops->notifier_hangup)
422 hp->ops->notifier_del(hp, hp->data); 428 hp->ops->notifier_hangup(hp, hp->data);
423 429
424 while(temp_open_count) { 430 while(temp_open_count) {
425 --temp_open_count; 431 --temp_open_count;
@@ -431,7 +437,7 @@ static void hvc_hangup(struct tty_struct *tty)
431 * Push buffered characters whether they were just recently buffered or waiting 437 * Push buffered characters whether they were just recently buffered or waiting
432 * on a blocked hypervisor. Call this function with hp->lock held. 438 * on a blocked hypervisor. Call this function with hp->lock held.
433 */ 439 */
434static void hvc_push(struct hvc_struct *hp) 440static int hvc_push(struct hvc_struct *hp)
435{ 441{
436 int n; 442 int n;
437 443
@@ -439,7 +445,7 @@ static void hvc_push(struct hvc_struct *hp)
439 if (n <= 0) { 445 if (n <= 0) {
440 if (n == 0) { 446 if (n == 0) {
441 hp->do_wakeup = 1; 447 hp->do_wakeup = 1;
442 return; 448 return 0;
443 } 449 }
444 /* throw away output on error; this happens when 450 /* throw away output on error; this happens when
445 there is no session connected to the vterm. */ 451 there is no session connected to the vterm. */
@@ -450,6 +456,8 @@ static void hvc_push(struct hvc_struct *hp)
450 memmove(hp->outbuf, hp->outbuf + n, hp->n_outbuf); 456 memmove(hp->outbuf, hp->outbuf + n, hp->n_outbuf);
451 else 457 else
452 hp->do_wakeup = 1; 458 hp->do_wakeup = 1;
459
460 return n;
453} 461}
454 462
455static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count) 463static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count)
@@ -492,6 +500,39 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count
492 return written; 500 return written;
493} 501}
494 502
503/**
504 * hvc_set_winsz() - Resize the hvc tty terminal window.
505 * @work: work structure.
506 *
507 * The routine shall not be called within an atomic context because it
508 * might sleep.
509 *
510 * Locking: hp->lock
511 */
512static void hvc_set_winsz(struct work_struct *work)
513{
514 struct hvc_struct *hp;
515 unsigned long hvc_flags;
516 struct tty_struct *tty;
517 struct winsize ws;
518
519 hp = container_of(work, struct hvc_struct, tty_resize);
520 if (!hp)
521 return;
522
523 spin_lock_irqsave(&hp->lock, hvc_flags);
524 if (!hp->tty) {
525 spin_unlock_irqrestore(&hp->lock, hvc_flags);
526 return;
527 }
528 ws = hp->ws;
529 tty = tty_kref_get(hp->tty);
530 spin_unlock_irqrestore(&hp->lock, hvc_flags);
531
532 tty_do_resize(tty, tty, &ws);
533 tty_kref_put(tty);
534}
535
495/* 536/*
496 * This is actually a contract between the driver and the tty layer outlining 537 * This is actually a contract between the driver and the tty layer outlining
497 * how much write room the driver can guarantee will be sent OR BUFFERED. This 538 * how much write room the driver can guarantee will be sent OR BUFFERED. This
@@ -538,16 +579,20 @@ int hvc_poll(struct hvc_struct *hp)
538 char buf[N_INBUF] __ALIGNED__; 579 char buf[N_INBUF] __ALIGNED__;
539 unsigned long flags; 580 unsigned long flags;
540 int read_total = 0; 581 int read_total = 0;
582 int written_total = 0;
541 583
542 spin_lock_irqsave(&hp->lock, flags); 584 spin_lock_irqsave(&hp->lock, flags);
543 585
544 /* Push pending writes */ 586 /* Push pending writes */
545 if (hp->n_outbuf > 0) 587 if (hp->n_outbuf > 0)
546 hvc_push(hp); 588 written_total = hvc_push(hp);
547 589
548 /* Reschedule us if still some write pending */ 590 /* Reschedule us if still some write pending */
549 if (hp->n_outbuf > 0) 591 if (hp->n_outbuf > 0) {
550 poll_mask |= HVC_POLL_WRITE; 592 poll_mask |= HVC_POLL_WRITE;
593 /* If hvc_push() was not able to write, sleep a few msecs */
594 timeout = (written_total) ? 0 : MIN_TIMEOUT;
595 }
551 596
552 /* No tty attached, just skip */ 597 /* No tty attached, just skip */
553 tty = hp->tty; 598 tty = hp->tty;
@@ -632,6 +677,24 @@ int hvc_poll(struct hvc_struct *hp)
632} 677}
633EXPORT_SYMBOL_GPL(hvc_poll); 678EXPORT_SYMBOL_GPL(hvc_poll);
634 679
680/**
681 * hvc_resize() - Update terminal window size information.
682 * @hp: HVC console pointer
683 * @ws: Terminal window size structure
684 *
685 * Stores the specified window size information in the hvc structure of @hp.
686 * The function schedule the tty resize update.
687 *
688 * Locking: Locking free; the function MUST be called holding hp->lock
689 */
690void hvc_resize(struct hvc_struct *hp, struct winsize ws)
691{
692 if ((hp->ws.ws_row != ws.ws_row) || (hp->ws.ws_col != ws.ws_col)) {
693 hp->ws = ws;
694 schedule_work(&hp->tty_resize);
695 }
696}
697
635/* 698/*
636 * This kthread is either polling or interrupt driven. This is determined by 699 * This kthread is either polling or interrupt driven. This is determined by
637 * calling hvc_poll() who determines whether a console adapter support 700 * calling hvc_poll() who determines whether a console adapter support
@@ -659,10 +722,6 @@ static int khvcd(void *unused)
659 poll_mask |= HVC_POLL_READ; 722 poll_mask |= HVC_POLL_READ;
660 if (hvc_kicked) 723 if (hvc_kicked)
661 continue; 724 continue;
662 if (poll_mask & HVC_POLL_WRITE) {
663 yield();
664 continue;
665 }
666 set_current_state(TASK_INTERRUPTIBLE); 725 set_current_state(TASK_INTERRUPTIBLE);
667 if (!hvc_kicked) { 726 if (!hvc_kicked) {
668 if (poll_mask == 0) 727 if (poll_mask == 0)
@@ -718,6 +777,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
718 777
719 kref_init(&hp->kref); 778 kref_init(&hp->kref);
720 779
780 INIT_WORK(&hp->tty_resize, hvc_set_winsz);
721 spin_lock_init(&hp->lock); 781 spin_lock_init(&hp->lock);
722 spin_lock(&hvc_structs_lock); 782 spin_lock(&hvc_structs_lock);
723 783
@@ -743,7 +803,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
743} 803}
744EXPORT_SYMBOL_GPL(hvc_alloc); 804EXPORT_SYMBOL_GPL(hvc_alloc);
745 805
746int __devexit hvc_remove(struct hvc_struct *hp) 806int hvc_remove(struct hvc_struct *hp)
747{ 807{
748 unsigned long flags; 808 unsigned long flags;
749 struct tty_struct *tty; 809 struct tty_struct *tty;
@@ -796,7 +856,7 @@ static int hvc_init(void)
796 drv->minor_start = HVC_MINOR; 856 drv->minor_start = HVC_MINOR;
797 drv->type = TTY_DRIVER_TYPE_SYSTEM; 857 drv->type = TTY_DRIVER_TYPE_SYSTEM;
798 drv->init_termios = tty_std_termios; 858 drv->init_termios = tty_std_termios;
799 drv->flags = TTY_DRIVER_REAL_RAW; 859 drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
800 tty_set_operations(drv, &hvc_ops); 860 tty_set_operations(drv, &hvc_ops);
801 861
802 /* Always start the kthread because there can be hotplug vty adapters 862 /* Always start the kthread because there can be hotplug vty adapters
diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h
index 9790201718ae..8297dbc2e6ec 100644
--- a/drivers/char/hvc_console.h
+++ b/drivers/char/hvc_console.h
@@ -27,6 +27,7 @@
27#ifndef HVC_CONSOLE_H 27#ifndef HVC_CONSOLE_H
28#define HVC_CONSOLE_H 28#define HVC_CONSOLE_H
29#include <linux/kref.h> 29#include <linux/kref.h>
30#include <linux/tty.h>
30 31
31/* 32/*
32 * This is the max number of console adapters that can/will be found as 33 * This is the max number of console adapters that can/will be found as
@@ -56,6 +57,8 @@ struct hvc_struct {
56 struct hv_ops *ops; 57 struct hv_ops *ops;
57 int irq_requested; 58 int irq_requested;
58 int data; 59 int data;
60 struct winsize ws;
61 struct work_struct tty_resize;
59 struct list_head next; 62 struct list_head next;
60 struct kref kref; /* ref count & hvc_struct lifetime */ 63 struct kref kref; /* ref count & hvc_struct lifetime */
61}; 64};
@@ -65,9 +68,10 @@ struct hv_ops {
65 int (*get_chars)(uint32_t vtermno, char *buf, int count); 68 int (*get_chars)(uint32_t vtermno, char *buf, int count);
66 int (*put_chars)(uint32_t vtermno, const char *buf, int count); 69 int (*put_chars)(uint32_t vtermno, const char *buf, int count);
67 70
68 /* Callbacks for notification. Called in open and close */ 71 /* Callbacks for notification. Called in open, close and hangup */
69 int (*notifier_add)(struct hvc_struct *hp, int irq); 72 int (*notifier_add)(struct hvc_struct *hp, int irq);
70 void (*notifier_del)(struct hvc_struct *hp, int irq); 73 void (*notifier_del)(struct hvc_struct *hp, int irq);
74 void (*notifier_hangup)(struct hvc_struct *hp, int irq);
71}; 75};
72 76
73/* Register a vterm and a slot index for use as a console (console_init) */ 77/* Register a vterm and a slot index for use as a console (console_init) */
@@ -77,15 +81,19 @@ extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
77extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int data, 81extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int data,
78 struct hv_ops *ops, int outbuf_size); 82 struct hv_ops *ops, int outbuf_size);
79/* remove a vterm from hvc tty operation (module_exit or hotplug remove) */ 83/* remove a vterm from hvc tty operation (module_exit or hotplug remove) */
80extern int __devexit hvc_remove(struct hvc_struct *hp); 84extern int hvc_remove(struct hvc_struct *hp);
81 85
82/* data available */ 86/* data available */
83int hvc_poll(struct hvc_struct *hp); 87int hvc_poll(struct hvc_struct *hp);
84void hvc_kick(void); 88void hvc_kick(void);
85 89
90/* Resize hvc tty terminal window */
91extern void hvc_resize(struct hvc_struct *hp, struct winsize ws);
92
86/* default notifier for irq based notification */ 93/* default notifier for irq based notification */
87extern int notifier_add_irq(struct hvc_struct *hp, int data); 94extern int notifier_add_irq(struct hvc_struct *hp, int data);
88extern void notifier_del_irq(struct hvc_struct *hp, int data); 95extern void notifier_del_irq(struct hvc_struct *hp, int data);
96extern void notifier_hangup_irq(struct hvc_struct *hp, int data);
89 97
90 98
91#if defined(CONFIG_XMON) && defined(CONFIG_SMP) 99#if defined(CONFIG_XMON) && defined(CONFIG_SMP)
diff --git a/drivers/char/hvc_irq.c b/drivers/char/hvc_irq.c
index 73a59cdb8947..d09e5688d449 100644
--- a/drivers/char/hvc_irq.c
+++ b/drivers/char/hvc_irq.c
@@ -42,3 +42,8 @@ void notifier_del_irq(struct hvc_struct *hp, int irq)
42 free_irq(irq, hp); 42 free_irq(irq, hp);
43 hp->irq_requested = 0; 43 hp->irq_requested = 0;
44} 44}
45
46void notifier_hangup_irq(struct hvc_struct *hp, int irq)
47{
48 notifier_del_irq(hp, irq);
49}
diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c
index b71c610fe5ae..b74a2f8ab908 100644
--- a/drivers/char/hvc_iseries.c
+++ b/drivers/char/hvc_iseries.c
@@ -202,6 +202,7 @@ static struct hv_ops hvc_get_put_ops = {
202 .put_chars = put_chars, 202 .put_chars = put_chars,
203 .notifier_add = notifier_add_irq, 203 .notifier_add = notifier_add_irq,
204 .notifier_del = notifier_del_irq, 204 .notifier_del = notifier_del_irq,
205 .notifier_hangup = notifier_hangup_irq,
205}; 206};
206 207
207static int __devinit hvc_vio_probe(struct vio_dev *vdev, 208static int __devinit hvc_vio_probe(struct vio_dev *vdev,
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index 93f3840c1682..019e0b58593d 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -82,6 +82,7 @@ static struct hv_ops hvc_get_put_ops = {
82 .put_chars = hvc_put_chars, 82 .put_chars = hvc_put_chars,
83 .notifier_add = notifier_add_irq, 83 .notifier_add = notifier_add_irq,
84 .notifier_del = notifier_del_irq, 84 .notifier_del = notifier_del_irq,
85 .notifier_hangup = notifier_hangup_irq,
85}; 86};
86 87
87static int __devinit hvc_vio_probe(struct vio_dev *vdev, 88static int __devinit hvc_vio_probe(struct vio_dev *vdev,
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c
index 538ceea5e7df..eba999f8598d 100644
--- a/drivers/char/hvc_xen.c
+++ b/drivers/char/hvc_xen.c
@@ -102,6 +102,7 @@ static struct hv_ops hvc_ops = {
102 .put_chars = write_console, 102 .put_chars = write_console,
103 .notifier_add = notifier_add_irq, 103 .notifier_add = notifier_add_irq,
104 .notifier_del = notifier_del_irq, 104 .notifier_del = notifier_del_irq,
105 .notifier_hangup = notifier_hangup_irq,
105}; 106};
106 107
107static int __init xen_init(void) 108static int __init xen_init(void)
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index d0f4eb6fdb7f..3fb0d2c88ba5 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -198,6 +198,7 @@ static int __devinit virtcons_probe(struct virtio_device *dev)
198 virtio_cons.put_chars = put_chars; 198 virtio_cons.put_chars = put_chars;
199 virtio_cons.notifier_add = notifier_add_vio; 199 virtio_cons.notifier_add = notifier_add_vio;
200 virtio_cons.notifier_del = notifier_del_vio; 200 virtio_cons.notifier_del = notifier_del_vio;
201 virtio_cons.notifier_hangup = notifier_del_vio;
201 202
202 /* The first argument of hvc_alloc() is the virtual console number, so 203 /* The first argument of hvc_alloc() is the virtual console number, so
203 * we use zero. The second argument is the parameter for the 204 * we use zero. The second argument is the parameter for the
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
index 8164de1f4d72..228f75723063 100644
--- a/drivers/i2c/busses/i2c-cpm.c
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -423,7 +423,6 @@ static const struct i2c_adapter cpm_ops = {
423 .owner = THIS_MODULE, 423 .owner = THIS_MODULE,
424 .name = "i2c-cpm", 424 .name = "i2c-cpm",
425 .algo = &cpm_i2c_algo, 425 .algo = &cpm_i2c_algo,
426 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
427}; 426};
428 427
429static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) 428static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm)
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c
index 08e18bcb970f..45dd9bdc5d62 100644
--- a/drivers/net/fec_mpc52xx_phy.c
+++ b/drivers/net/fec_mpc52xx_phy.c
@@ -2,6 +2,7 @@
2 * Driver for the MPC5200 Fast Ethernet Controller - MDIO bus driver 2 * Driver for the MPC5200 Fast Ethernet Controller - MDIO bus driver
3 * 3 *
4 * Copyright (C) 2007 Domen Puncer, Telargo, Inc. 4 * Copyright (C) 2007 Domen Puncer, Telargo, Inc.
5 * Copyright (C) 2008 Wolfram Sang, Pengutronix
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
@@ -21,58 +22,45 @@ struct mpc52xx_fec_mdio_priv {
21 struct mpc52xx_fec __iomem *regs; 22 struct mpc52xx_fec __iomem *regs;
22}; 23};
23 24
24static int mpc52xx_fec_mdio_read(struct mii_bus *bus, int phy_id, int reg) 25static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
26 int reg, u32 value)
25{ 27{
26 struct mpc52xx_fec_mdio_priv *priv = bus->priv; 28 struct mpc52xx_fec_mdio_priv *priv = bus->priv;
27 struct mpc52xx_fec __iomem *fec; 29 struct mpc52xx_fec __iomem *fec;
28 int tries = 100; 30 int tries = 100;
29 u32 request = FEC_MII_READ_FRAME; 31
32 value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
33 value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
30 34
31 fec = priv->regs; 35 fec = priv->regs;
32 out_be32(&fec->ievent, FEC_IEVENT_MII); 36 out_be32(&fec->ievent, FEC_IEVENT_MII);
33 37 out_be32(&priv->regs->mii_data, value);
34 request |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
35 request |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
36
37 out_be32(&priv->regs->mii_data, request);
38 38
39 /* wait for it to finish, this takes about 23 us on lite5200b */ 39 /* wait for it to finish, this takes about 23 us on lite5200b */
40 while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries) 40 while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
41 udelay(5); 41 udelay(5);
42 42
43 if (tries == 0) 43 if (!tries)
44 return -ETIMEDOUT; 44 return -ETIMEDOUT;
45 45
46 return in_be32(&priv->regs->mii_data) & FEC_MII_DATA_DATAMSK; 46 return value & FEC_MII_DATA_OP_RD ?
47 in_be32(&priv->regs->mii_data) & FEC_MII_DATA_DATAMSK : 0;
47} 48}
48 49
49static int mpc52xx_fec_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 data) 50static int mpc52xx_fec_mdio_read(struct mii_bus *bus, int phy_id, int reg)
50{ 51{
51 struct mpc52xx_fec_mdio_priv *priv = bus->priv; 52 return mpc52xx_fec_mdio_transfer(bus, phy_id, reg, FEC_MII_READ_FRAME);
52 struct mpc52xx_fec __iomem *fec; 53}
53 u32 value = data;
54 int tries = 100;
55
56 fec = priv->regs;
57 out_be32(&fec->ievent, FEC_IEVENT_MII);
58
59 value |= FEC_MII_WRITE_FRAME;
60 value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
61 value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
62
63 out_be32(&priv->regs->mii_data, value);
64
65 /* wait for request to finish */
66 while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
67 udelay(5);
68
69 if (tries == 0)
70 return -ETIMEDOUT;
71 54
72 return 0; 55static int mpc52xx_fec_mdio_write(struct mii_bus *bus, int phy_id, int reg,
56 u16 data)
57{
58 return mpc52xx_fec_mdio_transfer(bus, phy_id, reg,
59 data | FEC_MII_WRITE_FRAME);
73} 60}
74 61
75static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_id *match) 62static int mpc52xx_fec_mdio_probe(struct of_device *of,
63 const struct of_device_id *match)
76{ 64{
77 struct device *dev = &of->dev; 65 struct device *dev = &of->dev;
78 struct device_node *np = of->node; 66 struct device_node *np = of->node;
@@ -131,7 +119,8 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_i
131 dev_set_drvdata(dev, bus); 119 dev_set_drvdata(dev, bus);
132 120
133 /* set MII speed */ 121 /* set MII speed */
134 out_be32(&priv->regs->mii_speed, ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1); 122 out_be32(&priv->regs->mii_speed,
123 ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1);
135 124
136 /* enable MII interrupt */ 125 /* enable MII interrupt */
137 out_be32(&priv->regs->imask, in_be32(&priv->regs->imask) | FEC_IMASK_MII); 126 out_be32(&priv->regs->imask, in_be32(&priv->regs->imask) | FEC_IMASK_MII);
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index efcf21c9f5c7..2ee2622258f5 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -2604,8 +2604,16 @@ static int __devinit emac_init_config(struct emac_instance *dev)
2604 if (of_device_is_compatible(np, "ibm,emac-440ep") || 2604 if (of_device_is_compatible(np, "ibm,emac-440ep") ||
2605 of_device_is_compatible(np, "ibm,emac-440gr")) 2605 of_device_is_compatible(np, "ibm,emac-440gr"))
2606 dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX; 2606 dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX;
2607 if (of_device_is_compatible(np, "ibm,emac-405ez")) 2607 if (of_device_is_compatible(np, "ibm,emac-405ez")) {
2608#ifdef CONFIG_IBM_NEW_EMAC_NO_FLOW_CONTROL
2608 dev->features |= EMAC_FTR_NO_FLOW_CONTROL_40x; 2609 dev->features |= EMAC_FTR_NO_FLOW_CONTROL_40x;
2610#else
2611 printk(KERN_ERR "%s: Flow control not disabled!\n",
2612 np->full_name);
2613 return -ENXIO;
2614#endif
2615 }
2616
2609 } 2617 }
2610 2618
2611 /* Fixup some feature bits based on the device tree */ 2619 /* Fixup some feature bits based on the device tree */
diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c
index 1839d3f154a3..ecf9798987fa 100644
--- a/drivers/net/ibm_newemac/mal.c
+++ b/drivers/net/ibm_newemac/mal.c
@@ -280,9 +280,11 @@ static irqreturn_t mal_txeob(int irq, void *dev_instance)
280 mal_schedule_poll(mal); 280 mal_schedule_poll(mal);
281 set_mal_dcrn(mal, MAL_TXEOBISR, r); 281 set_mal_dcrn(mal, MAL_TXEOBISR, r);
282 282
283#ifdef CONFIG_PPC_DCR_NATIVE
283 if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT)) 284 if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT))
284 mtdcri(SDR0, DCRN_SDR_ICINTSTAT, 285 mtdcri(SDR0, DCRN_SDR_ICINTSTAT,
285 (mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICTX)); 286 (mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICTX));
287#endif
286 288
287 return IRQ_HANDLED; 289 return IRQ_HANDLED;
288} 290}
@@ -298,9 +300,11 @@ static irqreturn_t mal_rxeob(int irq, void *dev_instance)
298 mal_schedule_poll(mal); 300 mal_schedule_poll(mal);
299 set_mal_dcrn(mal, MAL_RXEOBISR, r); 301 set_mal_dcrn(mal, MAL_RXEOBISR, r);
300 302
303#ifdef CONFIG_PPC_DCR_NATIVE
301 if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT)) 304 if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT))
302 mtdcri(SDR0, DCRN_SDR_ICINTSTAT, 305 mtdcri(SDR0, DCRN_SDR_ICINTSTAT,
303 (mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICRX)); 306 (mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICRX));
307#endif
304 308
305 return IRQ_HANDLED; 309 return IRQ_HANDLED;
306} 310}
@@ -572,9 +576,18 @@ static int __devinit mal_probe(struct of_device *ofdev,
572 goto fail; 576 goto fail;
573 } 577 }
574 578
575 if (of_device_is_compatible(ofdev->node, "ibm,mcmal-405ez")) 579 if (of_device_is_compatible(ofdev->node, "ibm,mcmal-405ez")) {
580#if defined(CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT) && \
581 defined(CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR)
576 mal->features |= (MAL_FTR_CLEAR_ICINTSTAT | 582 mal->features |= (MAL_FTR_CLEAR_ICINTSTAT |
577 MAL_FTR_COMMON_ERR_INT); 583 MAL_FTR_COMMON_ERR_INT);
584#else
585 printk(KERN_ERR "%s: Support for 405EZ not enabled!\n",
586 ofdev->node->full_name);
587 err = -ENODEV;
588 goto fail;
589#endif
590 }
578 591
579 mal->txeob_irq = irq_of_parse_and_map(ofdev->node, 0); 592 mal->txeob_irq = irq_of_parse_and_map(ofdev->node, 0);
580 mal->rxeob_irq = irq_of_parse_and_map(ofdev->node, 1); 593 mal->rxeob_irq = irq_of_parse_and_map(ofdev->node, 1);
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
index 6a98dc8aa30b..24bbef777c19 100644
--- a/drivers/of/of_i2c.c
+++ b/drivers/of/of_i2c.c
@@ -41,7 +41,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
41 41
42 info.addr = *addr; 42 info.addr = *addr;
43 43
44 request_module(info.type); 44 request_module("%s", info.type);
45 45
46 result = i2c_new_device(adap, &info); 46 result = i2c_new_device(adap, &info);
47 if (result == NULL) { 47 if (result == NULL) {
diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c
index b01eec026f68..bed0ed6dcdc1 100644
--- a/drivers/of/of_spi.c
+++ b/drivers/of/of_spi.c
@@ -61,6 +61,8 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np)
61 spi->mode |= SPI_CPHA; 61 spi->mode |= SPI_CPHA;
62 if (of_find_property(nc, "spi-cpol", NULL)) 62 if (of_find_property(nc, "spi-cpol", NULL))
63 spi->mode |= SPI_CPOL; 63 spi->mode |= SPI_CPOL;
64 if (of_find_property(nc, "spi-cs-high", NULL))
65 spi->mode |= SPI_CS_HIGH;
64 66
65 /* Device speed */ 67 /* Device speed */
66 prop = of_get_property(nc, "spi-max-frequency", &len); 68 prop = of_get_property(nc, "spi-max-frequency", &len);
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index ed982273fb8b..37681700b61a 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -628,3 +628,27 @@ void sync_buffer(int cpu)
628 628
629 mutex_unlock(&buffer_mutex); 629 mutex_unlock(&buffer_mutex);
630} 630}
631
632/* The function can be used to add a buffer worth of data directly to
633 * the kernel buffer. The buffer is assumed to be a circular buffer.
634 * Take the entries from index start and end at index end, wrapping
635 * at max_entries.
636 */
637void oprofile_put_buff(unsigned long *buf, unsigned int start,
638 unsigned int stop, unsigned int max)
639{
640 int i;
641
642 i = start;
643
644 mutex_lock(&buffer_mutex);
645 while (i != stop) {
646 add_event_entry(buf[i++]);
647
648 if (i >= max)
649 i = 0;
650 }
651
652 mutex_unlock(&buffer_mutex);
653}
654
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index e1bd5a937f6c..7ba39fe20a8a 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -38,13 +38,26 @@ static int work_enabled;
38void free_cpu_buffers(void) 38void free_cpu_buffers(void)
39{ 39{
40 int i; 40 int i;
41 41
42 for_each_online_cpu(i) { 42 for_each_online_cpu(i) {
43 vfree(per_cpu(cpu_buffer, i).buffer); 43 vfree(per_cpu(cpu_buffer, i).buffer);
44 per_cpu(cpu_buffer, i).buffer = NULL; 44 per_cpu(cpu_buffer, i).buffer = NULL;
45 } 45 }
46} 46}
47 47
48unsigned long oprofile_get_cpu_buffer_size(void)
49{
50 return fs_cpu_buffer_size;
51}
52
53void oprofile_cpu_buffer_inc_smpl_lost(void)
54{
55 struct oprofile_cpu_buffer *cpu_buf
56 = &__get_cpu_var(cpu_buffer);
57
58 cpu_buf->sample_lost_overflow++;
59}
60
48int alloc_cpu_buffers(void) 61int alloc_cpu_buffers(void)
49{ 62{
50 int i; 63 int i;
diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h
index 5076ed1ebd8f..84bf324c5771 100644
--- a/drivers/oprofile/event_buffer.h
+++ b/drivers/oprofile/event_buffer.h
@@ -17,6 +17,13 @@ int alloc_event_buffer(void);
17 17
18void free_event_buffer(void); 18void free_event_buffer(void);
19 19
20/**
21 * Add data to the event buffer.
22 * The data passed is free-form, but typically consists of
23 * file offsets, dcookies, context information, and ESCAPE codes.
24 */
25void add_event_entry(unsigned long data);
26
20/* wake up the process sleeping on the event file */ 27/* wake up the process sleeping on the event file */
21void wake_up_buffer_waiter(void); 28void wake_up_buffer_waiter(void);
22 29