diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-06 13:49:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-06 13:49:42 -0400 |
commit | 39eda2aba6be642b71f2e0ad623dcb09fd9d79cf (patch) | |
tree | cd0c8f547847641af73e38aab2478f3119dee490 /drivers/tty | |
parent | 2e515bf096c245ba87f20ab4b4ea20f911afaeda (diff) | |
parent | 9f24b0c9ef9b6b1292579c9e2cd7ff07ddc372b7 (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc updates from Ben Herrenschmidt:
"Here's the powerpc batch for this merge window. Some of the
highlights are:
- A bunch of endian fixes ! We don't have full LE support yet in that
release but this contains a lot of fixes all over arch/powerpc to
use the proper accessors, call the firmware with the right endian
mode, etc...
- A few updates to our "powernv" platform (non-virtualized, the one
to run KVM on), among other, support for bridging the P8 LPC bus
for UARTs, support and some EEH fixes.
- Some mpc51xx clock API cleanups in preparation for a clock API
overhaul
- A pile of cleanups of our old math emulation code, including better
support for using it to emulate optional FP instructions on
embedded chips that otherwise have a HW FPU.
- Some infrastructure in selftest, for powerpc now, but could be
generalized, initially used by some tests for our perf instruction
counting code.
- A pile of fixes for hotplug on pseries (that was seriously
bitrotting)
- The usual slew of freescale embedded updates, new boards, 64-bit
hiberation support, e6500 core PMU support, etc..."
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (146 commits)
powerpc: Correct FSCR bit definitions
powerpc/xmon: Fix printing of set of CPUs in xmon
powerpc/pseries: Move lparcfg.c to platforms/pseries
powerpc/powernv: Return secondary CPUs to firmware on kexec
powerpc/btext: Fix CONFIG_PPC_EARLY_DEBUG_BOOTX on ppc32
powerpc: Cleanup handling of the DSCR bit in the FSCR register
powerpc/pseries: Child nodes are not detached by dlpar_detach_node
powerpc/pseries: Add mising of_node_put in delete_dt_node
powerpc/pseries: Make dlpar_configure_connector parent node aware
powerpc/pseries: Do all node initialization in dlpar_parse_cc_node
powerpc/pseries: Fix parsing of initial node path in update_dt_node
powerpc/pseries: Pack update_props_workarea to map correctly to rtas buffer header
powerpc/pseries: Fix over writing of rtas return code in update_dt_node
powerpc/pseries: Fix creation of loop in device node property list
powerpc: Skip emulating & leave interrupts off for kernel program checks
powerpc: Add more exception trampolines for hypervisor exceptions
powerpc: Fix location and rename exception trampolines
powerpc: Add more trap names to xmon
powerpc/pseries: Add a warning in the case of cross-cpu VPA registration
powerpc: Update the 00-Index in Documentation/powerpc
...
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/hvc/hvc_vio.c | 4 | ||||
-rw-r--r-- | drivers/tty/serial/mpc52xx_uart.c | 98 |
2 files changed, 83 insertions, 19 deletions
diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index 0c629807610e..c791b18cdd08 100644 --- a/drivers/tty/hvc/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c | |||
@@ -404,7 +404,7 @@ module_exit(hvc_vio_exit); | |||
404 | void __init hvc_vio_init_early(void) | 404 | void __init hvc_vio_init_early(void) |
405 | { | 405 | { |
406 | struct device_node *stdout_node; | 406 | struct device_node *stdout_node; |
407 | const u32 *termno; | 407 | const __be32 *termno; |
408 | const char *name; | 408 | const char *name; |
409 | const struct hv_ops *ops; | 409 | const struct hv_ops *ops; |
410 | 410 | ||
@@ -429,7 +429,7 @@ void __init hvc_vio_init_early(void) | |||
429 | termno = of_get_property(stdout_node, "reg", NULL); | 429 | termno = of_get_property(stdout_node, "reg", NULL); |
430 | if (termno == NULL) | 430 | if (termno == NULL) |
431 | goto out; | 431 | goto out; |
432 | hvterm_priv0.termno = *termno; | 432 | hvterm_priv0.termno = of_read_number(termno, 1); |
433 | spin_lock_init(&hvterm_priv0.buf_lock); | 433 | spin_lock_init(&hvterm_priv0.buf_lock); |
434 | hvterm_privs[0] = &hvterm_priv0; | 434 | hvterm_privs[0] = &hvterm_priv0; |
435 | 435 | ||
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index e1280a20b7a2..5be1df39f9f5 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c | |||
@@ -107,6 +107,8 @@ struct psc_ops { | |||
107 | unsigned int (*set_baudrate)(struct uart_port *port, | 107 | unsigned int (*set_baudrate)(struct uart_port *port, |
108 | struct ktermios *new, | 108 | struct ktermios *new, |
109 | struct ktermios *old); | 109 | struct ktermios *old); |
110 | int (*clock_alloc)(struct uart_port *port); | ||
111 | void (*clock_relse)(struct uart_port *port); | ||
110 | int (*clock)(struct uart_port *port, int enable); | 112 | int (*clock)(struct uart_port *port, int enable); |
111 | int (*fifoc_init)(void); | 113 | int (*fifoc_init)(void); |
112 | void (*fifoc_uninit)(void); | 114 | void (*fifoc_uninit)(void); |
@@ -616,31 +618,73 @@ static irqreturn_t mpc512x_psc_handle_irq(struct uart_port *port) | |||
616 | return IRQ_NONE; | 618 | return IRQ_NONE; |
617 | } | 619 | } |
618 | 620 | ||
619 | static int mpc512x_psc_clock(struct uart_port *port, int enable) | 621 | static struct clk *psc_mclk_clk[MPC52xx_PSC_MAXNUM]; |
622 | |||
623 | /* called from within the .request_port() callback (allocation) */ | ||
624 | static int mpc512x_psc_alloc_clock(struct uart_port *port) | ||
620 | { | 625 | { |
621 | struct clk *psc_clk; | ||
622 | int psc_num; | 626 | int psc_num; |
623 | char clk_name[10]; | 627 | char clk_name[16]; |
628 | struct clk *clk; | ||
629 | int err; | ||
630 | |||
631 | psc_num = (port->mapbase & 0xf00) >> 8; | ||
632 | snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); | ||
633 | clk = devm_clk_get(port->dev, clk_name); | ||
634 | if (IS_ERR(clk)) { | ||
635 | dev_err(port->dev, "Failed to get MCLK!\n"); | ||
636 | return PTR_ERR(clk); | ||
637 | } | ||
638 | err = clk_prepare_enable(clk); | ||
639 | if (err) { | ||
640 | dev_err(port->dev, "Failed to enable MCLK!\n"); | ||
641 | return err; | ||
642 | } | ||
643 | psc_mclk_clk[psc_num] = clk; | ||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | /* called from within the .release_port() callback (release) */ | ||
648 | static void mpc512x_psc_relse_clock(struct uart_port *port) | ||
649 | { | ||
650 | int psc_num; | ||
651 | struct clk *clk; | ||
652 | |||
653 | psc_num = (port->mapbase & 0xf00) >> 8; | ||
654 | clk = psc_mclk_clk[psc_num]; | ||
655 | if (clk) { | ||
656 | clk_disable_unprepare(clk); | ||
657 | psc_mclk_clk[psc_num] = NULL; | ||
658 | } | ||
659 | } | ||
660 | |||
661 | /* implementation of the .clock() callback (enable/disable) */ | ||
662 | static int mpc512x_psc_endis_clock(struct uart_port *port, int enable) | ||
663 | { | ||
664 | int psc_num; | ||
665 | struct clk *psc_clk; | ||
666 | int ret; | ||
624 | 667 | ||
625 | if (uart_console(port)) | 668 | if (uart_console(port)) |
626 | return 0; | 669 | return 0; |
627 | 670 | ||
628 | psc_num = (port->mapbase & 0xf00) >> 8; | 671 | psc_num = (port->mapbase & 0xf00) >> 8; |
629 | snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); | 672 | psc_clk = psc_mclk_clk[psc_num]; |
630 | psc_clk = clk_get(port->dev, clk_name); | 673 | if (!psc_clk) { |
631 | if (IS_ERR(psc_clk)) { | ||
632 | dev_err(port->dev, "Failed to get PSC clock entry!\n"); | 674 | dev_err(port->dev, "Failed to get PSC clock entry!\n"); |
633 | return -ENODEV; | 675 | return -ENODEV; |
634 | } | 676 | } |
635 | 677 | ||
636 | dev_dbg(port->dev, "%s %sable\n", clk_name, enable ? "en" : "dis"); | 678 | dev_dbg(port->dev, "mclk %sable\n", enable ? "en" : "dis"); |
637 | 679 | if (enable) { | |
638 | if (enable) | 680 | ret = clk_enable(psc_clk); |
639 | clk_enable(psc_clk); | 681 | if (ret) |
640 | else | 682 | dev_err(port->dev, "Failed to enable MCLK!\n"); |
683 | return ret; | ||
684 | } else { | ||
641 | clk_disable(psc_clk); | 685 | clk_disable(psc_clk); |
642 | 686 | return 0; | |
643 | return 0; | 687 | } |
644 | } | 688 | } |
645 | 689 | ||
646 | static void mpc512x_psc_get_irq(struct uart_port *port, struct device_node *np) | 690 | static void mpc512x_psc_get_irq(struct uart_port *port, struct device_node *np) |
@@ -873,7 +917,9 @@ static struct psc_ops mpc5125_psc_ops = { | |||
873 | .cw_disable_ints = mpc5125_psc_cw_disable_ints, | 917 | .cw_disable_ints = mpc5125_psc_cw_disable_ints, |
874 | .cw_restore_ints = mpc5125_psc_cw_restore_ints, | 918 | .cw_restore_ints = mpc5125_psc_cw_restore_ints, |
875 | .set_baudrate = mpc5125_psc_set_baudrate, | 919 | .set_baudrate = mpc5125_psc_set_baudrate, |
876 | .clock = mpc512x_psc_clock, | 920 | .clock_alloc = mpc512x_psc_alloc_clock, |
921 | .clock_relse = mpc512x_psc_relse_clock, | ||
922 | .clock = mpc512x_psc_endis_clock, | ||
877 | .fifoc_init = mpc512x_psc_fifoc_init, | 923 | .fifoc_init = mpc512x_psc_fifoc_init, |
878 | .fifoc_uninit = mpc512x_psc_fifoc_uninit, | 924 | .fifoc_uninit = mpc512x_psc_fifoc_uninit, |
879 | .get_irq = mpc512x_psc_get_irq, | 925 | .get_irq = mpc512x_psc_get_irq, |
@@ -906,7 +952,9 @@ static struct psc_ops mpc512x_psc_ops = { | |||
906 | .cw_disable_ints = mpc512x_psc_cw_disable_ints, | 952 | .cw_disable_ints = mpc512x_psc_cw_disable_ints, |
907 | .cw_restore_ints = mpc512x_psc_cw_restore_ints, | 953 | .cw_restore_ints = mpc512x_psc_cw_restore_ints, |
908 | .set_baudrate = mpc512x_psc_set_baudrate, | 954 | .set_baudrate = mpc512x_psc_set_baudrate, |
909 | .clock = mpc512x_psc_clock, | 955 | .clock_alloc = mpc512x_psc_alloc_clock, |
956 | .clock_relse = mpc512x_psc_relse_clock, | ||
957 | .clock = mpc512x_psc_endis_clock, | ||
910 | .fifoc_init = mpc512x_psc_fifoc_init, | 958 | .fifoc_init = mpc512x_psc_fifoc_init, |
911 | .fifoc_uninit = mpc512x_psc_fifoc_uninit, | 959 | .fifoc_uninit = mpc512x_psc_fifoc_uninit, |
912 | .get_irq = mpc512x_psc_get_irq, | 960 | .get_irq = mpc512x_psc_get_irq, |
@@ -1166,6 +1214,9 @@ mpc52xx_uart_type(struct uart_port *port) | |||
1166 | static void | 1214 | static void |
1167 | mpc52xx_uart_release_port(struct uart_port *port) | 1215 | mpc52xx_uart_release_port(struct uart_port *port) |
1168 | { | 1216 | { |
1217 | if (psc_ops->clock_relse) | ||
1218 | psc_ops->clock_relse(port); | ||
1219 | |||
1169 | /* remapped by us ? */ | 1220 | /* remapped by us ? */ |
1170 | if (port->flags & UPF_IOREMAP) { | 1221 | if (port->flags & UPF_IOREMAP) { |
1171 | iounmap(port->membase); | 1222 | iounmap(port->membase); |
@@ -1190,11 +1241,24 @@ mpc52xx_uart_request_port(struct uart_port *port) | |||
1190 | err = request_mem_region(port->mapbase, sizeof(struct mpc52xx_psc), | 1241 | err = request_mem_region(port->mapbase, sizeof(struct mpc52xx_psc), |
1191 | "mpc52xx_psc_uart") != NULL ? 0 : -EBUSY; | 1242 | "mpc52xx_psc_uart") != NULL ? 0 : -EBUSY; |
1192 | 1243 | ||
1193 | if (err && (port->flags & UPF_IOREMAP)) { | 1244 | if (err) |
1245 | goto out_membase; | ||
1246 | |||
1247 | if (psc_ops->clock_alloc) { | ||
1248 | err = psc_ops->clock_alloc(port); | ||
1249 | if (err) | ||
1250 | goto out_mapregion; | ||
1251 | } | ||
1252 | |||
1253 | return 0; | ||
1254 | |||
1255 | out_mapregion: | ||
1256 | release_mem_region(port->mapbase, sizeof(struct mpc52xx_psc)); | ||
1257 | out_membase: | ||
1258 | if (port->flags & UPF_IOREMAP) { | ||
1194 | iounmap(port->membase); | 1259 | iounmap(port->membase); |
1195 | port->membase = NULL; | 1260 | port->membase = NULL; |
1196 | } | 1261 | } |
1197 | |||
1198 | return err; | 1262 | return err; |
1199 | } | 1263 | } |
1200 | 1264 | ||